i2c_xmega.c
Go to the documentation of this file.
00001
00040 #include "cfg/cfg_i2c.h"
00041
00042
00043 #define LOG_LEVEL  I2C_LOG_LEVEL
00044 #define LOG_FORMAT I2C_LOG_FORMAT
00045 #include <cfg/log.h>
00046
00047 #include <cfg/debug.h>
00048 #include <cfg/macros.h> // BV()
00049 #include <cfg/module.h>
00050
00051 #include <cpu/detect.h>
00052 #include <cpu/irq.h>
00053 #include <cpu/types.h>
00054
00055 #include <drv/timer.h>
00056 #include <drv/i2c.h>
00057
00058 #include <cpu/power.h>
00059
00060 #include <avr/io.h>
00061 #include <util/twi.h> //AVRLIBC TWI bit mask definitions
00062 #include <stdbool.h>
00063
00064 #if !CONFIG_I2C_DISABLE_OLD_API
00065     #error I2C_OLD_API is not implemented
00066 #endif
00067 
00068 /*
00069  * New Api
00070  */
00071 struct I2cHardware
00072 {
00073     volatile TWI_t *twi;
00074 };
00075
00076 /* Baud register setting calculation. Formula described in datasheet. */
00077 #define TWI_BAUD(F_SYS, F_TWI) (DIV_ROUND(F_SYS, (2 * F_TWI)) - 5)
00078 
00079 // Wait until write interrupt is set
00080 #define WAIT_UNTIL_WRITE_INTERRUPT_SET(TWI) \
00081         do { \
00082             while (((TWI)->MASTER.STATUS & TWI_MASTER_WIF_bm) == 0) \
00083                 cpu_relax(); \
00084         } while (0)
00085 
00086 #define WAIT_UNTIL_READ_OR_WRITE_INTERRUPT_SET(TWI) \
00087         do { \
00088             while (((TWI)->MASTER.STATUS & (TWI_MASTER_WIF_bm | TWI_MASTER_RIF_bm)) == 0) \
00089                 cpu_relax(); \
00090         } while (0)
00091 
00092 #define MASTER_STATE_IS_IDLE(TWI)   (((TWI)->MASTER.STATUS & TWI_MASTER_BUSSTATE_gm) == TWI_MASTER_BUSSTATE_IDLE_gc)
00093 #define MASTER_STATE_IS_OWNER(TWI)  (((TWI)->MASTER.STATUS & TWI_MASTER_BUSSTATE_gm) == TWI_MASTER_BUSSTATE_OWNER_gc)
00094 #define MASTER_STATE_IS_BUSY(TWI)   (((TWI)->MASTER.STATUS & TWI_MASTER_BUSSTATE_gm) == TWI_MASTER_BUSSTATE_BUSY_gc)
00095 #define MASTER_STATE_IS_UNKOWN(TWI) (((TWI)->MASTER.STATUS & TWI_MASTER_BUSSTATE_gm) == TWI_MASTER_BUSSTATE_UNKNOWN_gc)
00096 
00097 // Wait until ready for the next transaction
00098 #define WAIT_UNTIL_READY_FOR_TRANSACTION(TWI) \
00099         do { \
00100                while (MASTER_STATE_IS_BUSY(TWI))\
00101                 cpu_relax(); \
00102         } while (0)
00103 
00104
00105 #define READ_INTERRUPT_FLAG_IS_SET(TWI) (((TWI)->MASTER.STATUS & TWI_MASTER_RIF_bm) != 0)
00106 #define ARBLOST_OR_BUSERR_OCCURED(TWI) (((TWI)->MASTER.STATUS & (TWI_MASTER_BUSERR_bm | TWI_MASTER_ARBLOST_bm)) != 0)
00107 #define ARBLOST_OCCURED(TWI) (((TWI)->MASTER.STATUS & TWI_MASTER_ARBLOST_bm) != 0)
00108 #define BUSERR_OCCURED(TWI) (((TWI)->MASTER.STATUS & TWI_MASTER_BUSERR_bm) != 0)
00109 #define ACK_RECEIVED(TWI) (((TWI)->MASTER.STATUS & TWI_MASTER_RXACK_bm) == 0)
00110 #define NACK_RECEIVED(TWI) (((TWI)->MASTER.STATUS & TWI_MASTER_RXACK_bm) != 0)
00111 #define CLEAR_BUSERROR(TWI) ((TWI)->MASTER.STATUS |= TWI_MASTER_BUSERR_bm)
00112 #define SET_IDLESTATE(TWI)  ((TWI)->MASTER.STATUS = ((TWI)->MASTER.STATUS & (~TWI_MASTER_BUSSTATE_gm)) | TWI_MASTER_BUSSTATE_IDLE_gc)
00113 
00117 INLINE void i2c_hw_stop(volatile TWI_t *twi)
00118 {
00119     twi->MASTER.CTRLC |= TWI_MASTER_CMD_STOP_gc;
00120 }
00121
00122 static void i2c_xmega_start(I2c *i2c, uint16_t slave_addr)
00123 {
00124     /*
00125      * Loop on the select write sequence: when the eeprom is busy
00126      * writing previously sent data it will reply to the SLA_W
00127      * control byte with a NACK.  In this case, we must
00128      * keep trying until the slave responds with an ACK.
00129      */
00130     ticks_t start = timer_clock();
00131     volatile TWI_t *twi = i2c->hw->twi;
00132     bool stop_loop = false;
00133
00134     //check if there is a buserror
00135     //if so, try to clear it!
00136     if (BUSERR_OCCURED(twi))
00137     {
00138         LOG_WARN("Clearing BusError from TWI device\r\n");
00139         CLEAR_BUSERROR(twi);
00140         LOG_WARN("Forcing TWI Device to IDLE state\r\n");
00141         SET_IDLESTATE(twi);
00142         LOG_WARN("Current status is: %d\r\n", twi->MASTER.STATUS);
00143     }
00144
00145     while (!stop_loop)
00146     {
00147         //Wait until we are in IDLE state.
00148         //Due to a set timeout, we will always retun to IDLE state
00149         //in due time.
00150         WAIT_UNTIL_READY_FOR_TRANSACTION(twi);
00151
00152         //Write the address
00153         //This will first generate the start condition
00154         if (I2C_TEST_START(i2c->flags) == I2C_START_W)
00155         {
00156             //start a write action
00157             uint8_t write_address = ((uint8_t)slave_addr << 1) & ~0x01;
00158             twi->MASTER.ADDR = write_address;
00159
00160             //Wait until the write interrupt flag is set.
00161             //this will also be set when an error occurs.
00162             WAIT_UNTIL_WRITE_INTERRUPT_SET(twi);
00163         }
00164         else
00165         {
00166             uint8_t read_address = ((uint8_t)slave_addr << 1) | 0x01;
00167             twi->MASTER.ADDR = read_address;
00168
00169             //Wait until the read or write interrupt flag is set.
00170             //In this case, a write interrupt flag is set on an error
00171             //a read interrupt on an ack
00172             WAIT_UNTIL_READ_OR_WRITE_INTERRUPT_SET(twi);
00173         }
00174
00175
00176         //check if Arbitration Lost of Buserror has occured
00177         if (ARBLOST_OR_BUSERR_OCCURED(twi))
00178         {
00179             if (ARBLOST_OCCURED(twi))
00180             {
00181                 i2c->errors |= I2C_ARB_LOST;
00182             }
00183
00184             if (BUSERR_OCCURED(twi))
00185             {
00186                 i2c->errors |= I2C_ERR;
00187             }
00188             LOG_ERR("Start error [%x]\n", twi->MASTER.STATUS);
00189
00190             // reset i2c
00191             i2c->xfer_size = 0;
00192             // try to send a stop signal
00193             i2c_hw_stop(twi);
00194             stop_loop = true;
00195         }
00196         else if (ACK_RECEIVED(twi))
00197         {
00198             //ack received
00199             stop_loop = true;
00200         }
00201         else
00202         {
00203             //nack received
00204             //ignore if writing, the slave device might just be busy
00205             //with a precious command.
00206             if (I2C_TEST_START(i2c->flags) == I2C_START_W)
00207             {
00208                 //Just check if the start timeout has occured
00209                 if (timer_clock() - start > ms_to_ticks(CONFIG_I2C_START_TIMEOUT))
00210                 {
00211                     LOG_ERR("Start timeout\n");
00212                     i2c->errors |= I2C_START_TIMEOUT;
00213                     i2c_hw_stop(twi);
00214                     stop_loop = true;
00215                 }
00216             }
00217             else
00218             {
00219                 //while reading.... stop
00220                 LOG_ERR("Start addr NACK[%x]\n", twi->MASTER.STATUS);
00221                 i2c->errors |= I2C_NO_ACK;
00222                 i2c_hw_stop(twi);
00223                 stop_loop = true;
00224             }
00225         }
00226     }
00227 }
00228
00229 static void i2c_xmega_putc(I2c *i2c, const uint8_t data)
00230 {
00231     volatile TWI_t *twi = i2c->hw->twi;
00232
00233     twi->MASTER.DATA = data;
00234
00235     WAIT_UNTIL_WRITE_INTERRUPT_SET(twi);
00236
00237     if (ARBLOST_OR_BUSERR_OCCURED(twi))
00238     {
00239         if (ARBLOST_OCCURED(twi))
00240         {
00241             i2c->errors |= I2C_ARB_LOST;
00242         }
00243
00244         if (BUSERR_OCCURED(twi))
00245         {
00246             i2c->errors |= I2C_ERR;
00247         }
00248
00249         LOG_ERR("Data write error [%x]\n", twi->MASTER.STATUS);
00250         i2c_hw_stop(twi);
00251     }
00252     else if (NACK_RECEIVED(twi))
00253     {
00254         LOG_ERR("Data nack[%x]\n", twi->MASTER.STATUS);
00255         i2c->errors |= I2C_DATA_NACK;
00256         i2c_hw_stop(twi);
00257     }
00258
00259     if ((i2c->xfer_size == 1) && (I2C_TEST_STOP(i2c->flags) == I2C_STOP))
00260     {
00261         i2c_hw_stop(twi);
00262     }
00263 }
00264
00265 static uint8_t i2c_xmega_getc(I2c *i2c)
00266 {
00267     volatile TWI_t *twi = i2c->hw->twi;
00268
00269     //check if the RIF flag is set
00270     if (READ_INTERRUPT_FLAG_IS_SET(twi))
00271     {
00272         //read the available data
00273         uint8_t data = twi->MASTER.DATA;
00274         //if this is the last byte to receive, send nack otherwise ack.
00275         if (i2c->xfer_size == 1)
00276         {
00277             //nack needs to be send
00278             //check if a stop needs to be generated afther the ack, of a repeat start.
00279             if (I2C_TEST_STOP(i2c->flags) == I2C_STOP)
00280             {
00281                 //send nack and stop
00282                 twi->MASTER.CTRLC = TWI_MASTER_ACKACT_bm | TWI_MASTER_CMD_STOP_gc;
00283             }
00284             else
00285             {
00286                 //only set the nack. The repeated start will be send on the next
00287                 //call to i2c_xmega_start
00288                 twi->MASTER.CTRLC = TWI_MASTER_ACKACT_bm;
00289             }
00290         }
00291         else
00292         {
00293             //send ack and request next byte
00294             twi->MASTER.CTRLC = TWI_MASTER_CMD_RECVTRANS_gc;
00295             //Wait until the read or write interrupt flag is set.
00296             //In this case, a write interrupt flag is set on an error
00297             //a read interrupt on an ack
00298             WAIT_UNTIL_READ_OR_WRITE_INTERRUPT_SET(twi);
00299             //check if Arbitration Lost of Buserror has occured
00300             if ( ARBLOST_OR_BUSERR_OCCURED(twi))
00301             {
00302                 if (ARBLOST_OCCURED(twi))
00303                 {
00304                     i2c->errors |= I2C_ARB_LOST;
00305                 }
00306
00307                 if (BUSERR_OCCURED(twi))
00308                 {
00309                     i2c->errors |= I2C_ERR;
00310                 }
00311
00312                 LOG_ERR("Data error [%x]\n", twi->MASTER.STATUS);
00313                 i2c_hw_stop(twi);
00314                 return 0xFF;
00315             }
00316         }
00317         return data;
00318     }
00319     else
00320     {
00321         LOG_ERR("Data RIF not set[%x]\n", twi->MASTER.STATUS);
00322         i2c->errors |= I2C_ERR;
00323         i2c_hw_stop(twi);
00324         return 0xFF;
00325     }
00326 }
00327
00328
00329 static const I2cVT i2c_xmega_vt =
00330 {
00331     .start = i2c_xmega_start,
00332     .getc = i2c_xmega_getc,
00333     .putc = i2c_xmega_putc,
00334     .write = i2c_genericWrite,
00335     .read = i2c_genericRead,
00336 };
00337
00338 struct I2cHardware i2c_xmega_hw[] =
00339 {
00340     { /* I2C0 */
00341         .twi = &TWIC,
00342     },
00343     { /* ICC1 */
00344         .twi = &TWIE,
00345     },
00346     #if CPU_AVR_XMEGA_A1
00347     { /* I2C2 */
00348         .twi = &TWID,
00349     },
00350     { /* ICC3 */
00351         .twi = &TWIF,
00352     },
00353     #endif
00354 };
00355
00359 void i2c_hw_init(I2c *i2c, int dev, uint32_t clock)
00360 {
00361     i2c->hw = &i2c_xmega_hw[dev];
00362     i2c->vt = &i2c_xmega_vt;
00363
00364     volatile TWI_t *twi = i2c->hw->twi;
00365
00366     //enable TWI Master Mode
00367     twi->MASTER.CTRLA = TWI_MASTER_ENABLE_bm;
00368     //set an Interactive Bus Timeout
00369     twi->MASTER.CTRLB = TWI_MASTER_TIMEOUT_50US_gc;
00370     //set baud rate
00371     ASSERT(clock);
00372     twi->MASTER.BAUD = TWI_BAUD(CPU_FREQ, clock);
00373     //set status to idle
00374     twi->MASTER.STATUS = TWI_MASTER_BUSSTATE_IDLE_gc;
00375 }