Mbed for ESIMEos / Mbed 2 deprecated FRDM-KL46Z_LCD_I2C_demo

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers twi.c Source File

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__