| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561 | /*  twi.c - TWI/I2C library for Wiring & Arduino  Copyright (c) 2006 Nicholas Zambetti.  All right reserved.  This library is free software; you can redistribute it and/or  modify it under the terms of the GNU Lesser General Public  License as published by the Free Software Foundation; either  version 2.1 of the License, or (at your option) any later version.  This library is distributed in the hope that it will be useful,  but WITHOUT ANY WARRANTY; without even the implied warranty of  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU  Lesser General Public License for more details.  You should have received a copy of the GNU Lesser General Public  License along with this library; if not, write to the Free Software  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA  Modified 2012 by Todd Krein (todd@krein.org) to implement repeated starts*/#include <math.h>#include <stdlib.h>#include <inttypes.h>#include <avr/io.h>#include <avr/interrupt.h>#include <compat/twi.h>#include "Arduino.h" // for digitalWrite#ifndef cbi#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))#endif#ifndef sbi#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))#endif#include "pins_arduino.h"#include "twi.h"static volatile uint8_t twi_state;static volatile uint8_t twi_slarw;static volatile uint8_t twi_sendStop;			// should the transaction end with a stopstatic volatile uint8_t twi_inRepStart;			// in the middle of a repeated startstatic void (*twi_onSlaveTransmit)(void);static void (*twi_onSlaveReceive)(uint8_t*, int);static uint8_t twi_masterBuffer[TWI_BUFFER_LENGTH];static volatile uint8_t twi_masterBufferIndex;static volatile uint8_t twi_masterBufferLength;static uint8_t twi_txBuffer[TWI_BUFFER_LENGTH];static volatile uint8_t twi_txBufferIndex;static volatile uint8_t twi_txBufferLength;static uint8_t twi_rxBuffer[TWI_BUFFER_LENGTH];static volatile uint8_t twi_rxBufferIndex;static volatile uint8_t twi_error;/*  * Function twi_init * Desc     readys twi pins and sets twi bitrate * Input    none * Output   none */void twi_init(void){  // initialize state  twi_state = TWI_READY;  twi_sendStop = true;		// default value  twi_inRepStart = false;    // activate internal pullups for twi.  digitalWrite(SDA, 1);  digitalWrite(SCL, 1);  // initialize twi prescaler and bit rate  cbi(TWSR, TWPS0);  cbi(TWSR, TWPS1);  TWBR = ((F_CPU / TWI_FREQ) - 16) / 2;  /* twi bit rate formula from atmega128 manual pg 204  SCL Frequency = CPU Clock Frequency / (16 + (2 * TWBR))  note: TWBR should be 10 or higher for master mode  It is 72 for a 16mhz Wiring board with 100kHz TWI */  // enable twi module, acks, and twi interrupt  TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA);}/*  * Function twi_disable * Desc     disables twi pins * Input    none * Output   none */void twi_disable(void){  // disable twi module, acks, and twi interrupt  TWCR &= ~(_BV(TWEN) | _BV(TWIE) | _BV(TWEA));  // deactivate internal pullups for twi.  digitalWrite(SDA, 0);  digitalWrite(SCL, 0);}/*  * Function twi_slaveInit * Desc     sets slave address and enables interrupt * Input    none * Output   none */void twi_setAddress(uint8_t address){  // set twi slave address (skip over TWGCE bit)  TWAR = address << 1;}/*  * Function twi_setClock * Desc     sets twi bit rate * Input    Clock Frequency * Output   none */void twi_setFrequency(uint32_t frequency){  TWBR = ((F_CPU / frequency) - 16) / 2;    /* twi bit rate formula from atmega128 manual pg 204  SCL Frequency = CPU Clock Frequency / (16 + (2 * TWBR))  note: TWBR should be 10 or higher for master mode  It is 72 for a 16mhz Wiring board with 100kHz TWI */}/*  * Function twi_readFrom * Desc     attempts to become twi bus master and read a *          series of bytes from a device on the bus * Input    address: 7bit i2c device address *          data: pointer to byte array *          length: number of bytes to read into array *          sendStop: Boolean indicating whether to send a stop at the end * Output   number of bytes read */uint8_t twi_readFrom(uint8_t address, uint8_t* data, uint8_t length, uint8_t sendStop){  uint8_t i;  // ensure data will fit into buffer  if(TWI_BUFFER_LENGTH < length){    return 0;  }  // wait until twi is ready, become master receiver  while(TWI_READY != twi_state){    continue;  }  twi_state = TWI_MRX;  twi_sendStop = sendStop;  // reset error state (0xFF.. no error occured)  twi_error = 0xFF;  // initialize buffer iteration vars  twi_masterBufferIndex = 0;  twi_masterBufferLength = length-1;  // This is not intuitive, read on...  // On receive, the previously configured ACK/NACK setting is transmitted in  // response to the received byte before the interrupt is signalled.   // Therefor we must actually set NACK when the _next_ to last byte is  // received, causing that NACK to be sent in response to receiving the last  // expected byte of data.  // build sla+w, slave device address + w bit  twi_slarw = TW_READ;  twi_slarw |= address << 1;  if (true == twi_inRepStart) {    // if we're in the repeated start state, then we've already sent the start,    // (@@@ we hope), and the TWI statemachine is just waiting for the address byte.    // We need to remove ourselves from the repeated start state before we enable interrupts,    // since the ISR is ASYNC, and we could get confused if we hit the ISR before cleaning    // up. Also, don't enable the START interrupt. There may be one pending from the     // repeated start that we sent ourselves, and that would really confuse things.    twi_inRepStart = false;			// remember, we're dealing with an ASYNC ISR    do {      TWDR = twi_slarw;    } while(TWCR & _BV(TWWC));    TWCR = _BV(TWINT) | _BV(TWEA) | _BV(TWEN) | _BV(TWIE);	// enable INTs, but not START  }  else    // send start condition    TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT) | _BV(TWSTA);  // wait for read operation to complete  while(TWI_MRX == twi_state){    continue;  }  if (twi_masterBufferIndex < length)    length = twi_masterBufferIndex;  // copy twi buffer to data  for(i = 0; i < length; ++i){    data[i] = twi_masterBuffer[i];  }	  return length;}/*  * Function twi_writeTo * Desc     attempts to become twi bus master and write a *          series of bytes to a device on the bus * Input    address: 7bit i2c device address *          data: pointer to byte array *          length: number of bytes in array *          wait: boolean indicating to wait for write or not *          sendStop: boolean indicating whether or not to send a stop at the end * Output   0 .. success *          1 .. length to long for buffer *          2 .. address send, NACK received *          3 .. data send, NACK received *          4 .. other twi error (lost bus arbitration, bus error, ..) */uint8_t twi_writeTo(uint8_t address, uint8_t* data, uint8_t length, uint8_t wait, uint8_t sendStop){  uint8_t i;  // ensure data will fit into buffer  if(TWI_BUFFER_LENGTH < length){    return 1;  }  // wait until twi is ready, become master transmitter  while(TWI_READY != twi_state){    continue;  }  twi_state = TWI_MTX;  twi_sendStop = sendStop;  // reset error state (0xFF.. no error occured)  twi_error = 0xFF;  // initialize buffer iteration vars  twi_masterBufferIndex = 0;  twi_masterBufferLength = length;    // copy data to twi buffer  for(i = 0; i < length; ++i){    twi_masterBuffer[i] = data[i];  }    // build sla+w, slave device address + w bit  twi_slarw = TW_WRITE;  twi_slarw |= address << 1;    // if we're in a repeated start, then we've already sent the START  // in the ISR. Don't do it again.  //  if (true == twi_inRepStart) {    // if we're in the repeated start state, then we've already sent the start,    // (@@@ we hope), and the TWI statemachine is just waiting for the address byte.    // We need to remove ourselves from the repeated start state before we enable interrupts,    // since the ISR is ASYNC, and we could get confused if we hit the ISR before cleaning    // up. Also, don't enable the START interrupt. There may be one pending from the     // repeated start that we sent outselves, and that would really confuse things.    twi_inRepStart = false;			// remember, we're dealing with an ASYNC ISR    do {      TWDR = twi_slarw;				    } while(TWCR & _BV(TWWC));    TWCR = _BV(TWINT) | _BV(TWEA) | _BV(TWEN) | _BV(TWIE);	// enable INTs, but not START  }  else    // send start condition    TWCR = _BV(TWINT) | _BV(TWEA) | _BV(TWEN) | _BV(TWIE) | _BV(TWSTA);	// enable INTs  // wait for write operation to complete  while(wait && (TWI_MTX == twi_state)){    continue;  }    if (twi_error == 0xFF)    return 0;	// success  else if (twi_error == TW_MT_SLA_NACK)    return 2;	// error: address send, nack received  else if (twi_error == TW_MT_DATA_NACK)    return 3;	// error: data send, nack received  else    return 4;	// other twi error}/*  * Function twi_transmit * Desc     fills slave tx buffer with data *          must be called in slave tx event callback * Input    data: pointer to byte array *          length: number of bytes in array * Output   1 length too long for buffer *          2 not slave transmitter *          0 ok */uint8_t twi_transmit(const uint8_t* data, uint8_t length){  uint8_t i;  // ensure data will fit into buffer  if(TWI_BUFFER_LENGTH < (twi_txBufferLength+length)){    return 1;  }    // ensure we are currently a slave transmitter  if(TWI_STX != twi_state){    return 2;  }    // set length and copy data into tx buffer  for(i = 0; i < length; ++i){    twi_txBuffer[twi_txBufferLength+i] = data[i];  }  twi_txBufferLength += length;    return 0;}/*  * Function twi_attachSlaveRxEvent * Desc     sets function called before a slave read operation * Input    function: callback function to use * Output   none */void twi_attachSlaveRxEvent( void (*function)(uint8_t*, int) ){  twi_onSlaveReceive = function;}/*  * Function twi_attachSlaveTxEvent * Desc     sets function called before a slave write operation * Input    function: callback function to use * Output   none */void twi_attachSlaveTxEvent( void (*function)(void) ){  twi_onSlaveTransmit = function;}/*  * Function twi_reply * Desc     sends byte or readys receive line * Input    ack: byte indicating to ack or to nack * Output   none */void twi_reply(uint8_t ack){  // transmit master read ready signal, with or without ack  if(ack){    TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWINT) | _BV(TWEA);  }else{	  TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWINT);  }}/*  * Function twi_stop * Desc     relinquishes bus master status * Input    none * Output   none */void twi_stop(void){  // send stop condition  TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT) | _BV(TWSTO);  // wait for stop condition to be exectued on bus  // TWINT is not set after a stop condition!  while(TWCR & _BV(TWSTO)){    continue;  }  // update twi state  twi_state = TWI_READY;}/*  * Function twi_releaseBus * Desc     releases bus control * Input    none * Output   none */void twi_releaseBus(void){  // release bus  TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT);  // update twi state  twi_state = TWI_READY;}ISR(TWI_vect){  switch(TW_STATUS){    // All Master    case TW_START:     // sent start condition    case TW_REP_START: // sent repeated start condition      // copy device address and r/w bit to output register and ack      TWDR = twi_slarw;      twi_reply(1);      break;    // Master Transmitter    case TW_MT_SLA_ACK:  // slave receiver acked address    case TW_MT_DATA_ACK: // slave receiver acked data      // if there is data to send, send it, otherwise stop       if(twi_masterBufferIndex < twi_masterBufferLength){        // copy data to output register and ack        TWDR = twi_masterBuffer[twi_masterBufferIndex++];        twi_reply(1);      }else{	if (twi_sendStop)          twi_stop();	else {	  twi_inRepStart = true;	// we're gonna send the START	  // don't enable the interrupt. We'll generate the start, but we 	  // avoid handling the interrupt until we're in the next transaction,	  // at the point where we would normally issue the start.	  TWCR = _BV(TWINT) | _BV(TWSTA)| _BV(TWEN) ;	  twi_state = TWI_READY;	}      }      break;    case TW_MT_SLA_NACK:  // address sent, nack received      twi_error = TW_MT_SLA_NACK;      twi_stop();      break;    case TW_MT_DATA_NACK: // data sent, nack received      twi_error = TW_MT_DATA_NACK;      twi_stop();      break;    case TW_MT_ARB_LOST: // lost bus arbitration      twi_error = TW_MT_ARB_LOST;      twi_releaseBus();      break;    // Master Receiver    case TW_MR_DATA_ACK: // data received, ack sent      // put byte into buffer      twi_masterBuffer[twi_masterBufferIndex++] = TWDR;    case TW_MR_SLA_ACK:  // address sent, ack received      // ack if more bytes are expected, otherwise nack      if(twi_masterBufferIndex < twi_masterBufferLength){        twi_reply(1);      }else{        twi_reply(0);      }      break;    case TW_MR_DATA_NACK: // data received, nack sent      // put final byte into buffer      twi_masterBuffer[twi_masterBufferIndex++] = TWDR;	if (twi_sendStop)          twi_stop();	else {	  twi_inRepStart = true;	// we're gonna send the START	  // don't enable the interrupt. We'll generate the start, but we 	  // avoid handling the interrupt until we're in the next transaction,	  // at the point where we would normally issue the start.	  TWCR = _BV(TWINT) | _BV(TWSTA)| _BV(TWEN) ;	  twi_state = TWI_READY;	}    	break;    case TW_MR_SLA_NACK: // address sent, nack received      twi_stop();      break;    // TW_MR_ARB_LOST handled by TW_MT_ARB_LOST case    // Slave Receiver    case TW_SR_SLA_ACK:   // addressed, returned ack    case TW_SR_GCALL_ACK: // addressed generally, returned ack    case TW_SR_ARB_LOST_SLA_ACK:   // lost arbitration, returned ack    case TW_SR_ARB_LOST_GCALL_ACK: // lost arbitration, returned ack      // enter slave receiver mode      twi_state = TWI_SRX;      // indicate that rx buffer can be overwritten and ack      twi_rxBufferIndex = 0;      twi_reply(1);      break;    case TW_SR_DATA_ACK:       // data received, returned ack    case TW_SR_GCALL_DATA_ACK: // data received generally, returned ack      // if there is still room in the rx buffer      if(twi_rxBufferIndex < TWI_BUFFER_LENGTH){        // put byte in buffer and ack        twi_rxBuffer[twi_rxBufferIndex++] = TWDR;        twi_reply(1);      }else{        // otherwise nack        twi_reply(0);      }      break;    case TW_SR_STOP: // stop or repeated start condition received      // ack future responses and leave slave receiver state      twi_releaseBus();      // put a null char after data if there's room      if(twi_rxBufferIndex < TWI_BUFFER_LENGTH){        twi_rxBuffer[twi_rxBufferIndex] = '\0';      }      // callback to user defined callback      twi_onSlaveReceive(twi_rxBuffer, twi_rxBufferIndex);      // since we submit rx buffer to "wire" library, we can reset it      twi_rxBufferIndex = 0;      break;    case TW_SR_DATA_NACK:       // data received, returned nack    case TW_SR_GCALL_DATA_NACK: // data received generally, returned nack      // nack back at master      twi_reply(0);      break;        // Slave Transmitter    case TW_ST_SLA_ACK:          // addressed, returned ack    case TW_ST_ARB_LOST_SLA_ACK: // arbitration lost, returned ack      // enter slave transmitter mode      twi_state = TWI_STX;      // ready the tx buffer index for iteration      twi_txBufferIndex = 0;      // set tx buffer length to be zero, to verify if user changes it      twi_txBufferLength = 0;      // request for txBuffer to be filled and length to be set      // note: user must call twi_transmit(bytes, length) to do this      twi_onSlaveTransmit();      // if they didn't change buffer & length, initialize it      if(0 == twi_txBufferLength){        twi_txBufferLength = 1;        twi_txBuffer[0] = 0x00;      }      // transmit first byte from buffer, fall    case TW_ST_DATA_ACK: // byte sent, ack returned      // copy data to output register      TWDR = twi_txBuffer[twi_txBufferIndex++];      // if there is more to send, ack, otherwise nack      if(twi_txBufferIndex < twi_txBufferLength){        twi_reply(1);      }else{        twi_reply(0);      }      break;    case TW_ST_DATA_NACK: // received nack, we are done     case TW_ST_LAST_DATA: // received ack, but we are done already!      // ack future responses      twi_reply(1);      // leave slave receiver state      twi_state = TWI_READY;      break;    // All    case TW_NO_INFO:   // no state information      break;    case TW_BUS_ERROR: // bus error, illegal stop/start      twi_error = TW_BUS_ERROR;      twi_stop();      break;  }}
 |