00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052 #include <avr/io.h>
00053 #include <avr/signal.h>
00054 #include <avr/interrupt.h>
00055 #include <avr/twi.h>
00056
00057 #include "i2c.h"
00058
00059
00060
00061
00062
00063 #define I2C_IDLE 0
00064 #define I2C_BUSY 1
00065 #define I2C_SENT_START 2
00066 #define I2C_SENT_DEVICEADDR 3
00067 #define I2C_SENT_REGADDR 4
00068 #define I2C_SENT_DATA 5
00069
00070 static volatile u08 I2cState;
00071 static u08 I2cDeviceAddrRW;
00072 static u08 I2cData[0x10];
00073 static u08 I2cDataIndex;
00074 static u08 I2cDataLength;
00075
00076
00077 static void (*i2cSlaveReceive)(u08 data);
00078
00079
00080 void i2cInit(void)
00081 {
00082
00083 sbi(PORTC, 0);
00084 sbi(PORTC, 1);
00085 sbi(PORTD, 0);
00086 sbi(PORTD, 1);
00087
00088
00089 i2cSlaveReceive = 0;
00090
00091 i2cSetBitrate(100);
00092
00093 sbi(TWCR, TWEN);
00094
00095 I2cState = I2C_IDLE;
00096
00097 sbi(TWCR, TWIE);
00098 sbi(TWCR, TWEA);
00099
00100 sei();
00101 }
00102
00103 void i2cSetBitrate(u16 bitrateKHz)
00104 {
00105 u08 bitrate_div;
00106
00107
00108 #ifdef TWPS0
00109
00110
00111
00112 cbi(TWSR, TWPS0);
00113 cbi(TWSR, TWPS1);
00114 #endif
00115
00116 bitrate_div = (((F_CPU/1000l)/bitrateKHz)-16)/2;
00117
00118 outb(TWBR, 0xFF);
00119 }
00120
00121 void i2cSetLocalDeviceAddr(u08 deviceAddr, u08 genCallEn)
00122 {
00123
00124 outb(TWAR, ((deviceAddr&0xFE) | (genCallEn?1:0)) );
00125 }
00126
00127 void i2cSetReceiveHandler(void (*i2cRx_func)(u08 data))
00128 {
00129 i2cSlaveReceive = i2cRx_func;
00130 }
00131
00132 void i2cSend(u08 deviceAddr, u08 length, u08* data)
00133 {
00134 u08 i;
00135
00136 while(I2cState);
00137
00138 I2cDeviceAddrRW = (deviceAddr&0xFE);
00139 for(i=0; i<length; i++)
00140 I2cData[i] = *data++;
00141 I2cDataIndex = 0;
00142 I2cDataLength = length;
00143
00144 I2cState = I2C_BUSY;
00145
00146 outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT)|BV(TWSTA));
00147 }
00148
00149 void i2cReceive(u08 deviceAddr, u08 length, u08* data)
00150 {
00151 u08 i;
00152
00153 while(I2cState);
00154
00155 I2cDeviceAddrRW = (deviceAddr&0xFE);
00156 I2cDataIndex = 0;
00157 I2cDataLength = length;
00158
00159 I2cState = I2C_BUSY;
00160
00161 outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT)|BV(TWSTA));
00162
00163 while(I2cState);
00164
00165 for(i=0; i<length; i++)
00166 *data++ = I2cData[i];
00167 }
00168
00169
00170 SIGNAL(SIG_2WIRE_SERIAL)
00171 {
00172 u08 data=0;
00173
00174 u08 status = inb(TWSR) & TWSR_STATUS_MASK;
00175
00176 switch(status)
00177 {
00178
00179
00180 case TW_START:
00181
00182 outb(TWDR, I2cDeviceAddrRW);
00183 outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT));
00184 break;
00185 case TW_REP_START:
00186 break;
00187
00188
00189 case TW_MT_SLA_ACK:
00190 case TW_MT_DATA_ACK:
00191 if(I2cDataIndex < I2cDataLength)
00192 {
00193
00194 outb(TWDR, I2cData[I2cDataIndex++]);
00195 outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT));
00196 }
00197 else
00198 {
00199
00200 outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT)|BV(TWSTO)|BV(TWEA));
00201
00202 I2cState = I2C_IDLE;
00203 }
00204 break;
00205 case TW_MR_DATA_NACK:
00206
00207 I2cData[I2cDataIndex++] = inb(TWDR);
00208
00209 case TW_MR_SLA_NACK:
00210 case TW_MT_SLA_NACK:
00211 case TW_MT_DATA_NACK:
00212
00213 outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT)|BV(TWSTO)|BV(TWEA));
00214
00215 I2cState = I2C_IDLE;
00216 break;
00217 case TW_MT_ARB_LOST:
00218
00219
00220 outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT));
00221
00222 I2cState = I2C_IDLE;
00223
00224
00225 break;
00226 case TW_MR_DATA_ACK:
00227
00228 I2cData[I2cDataIndex++] = inb(TWDR);
00229
00230 case TW_MR_SLA_ACK:
00231 if(I2cDataIndex < (I2cDataLength-1))
00232
00233 outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT)|BV(TWEA));
00234 else
00235
00236 outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT));
00237 break;
00238
00239
00240 case TW_SR_SLA_ACK:
00241 case TW_SR_ARB_LOST_SLA_ACK:
00242 case TW_SR_GCALL_ACK:
00243 case TW_SR_ARB_LOST_GCALL_ACK:
00244
00245 outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT)|BV(TWEA));
00246 break;
00247 case TW_SR_DATA_ACK:
00248 case TW_SR_GCALL_DATA_ACK:
00249
00250 data = inb(TWDR);
00251 if(i2cSlaveReceive) i2cSlaveReceive(data);
00252
00253 outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT)|BV(TWEA));
00254 break;
00255 case TW_SR_DATA_NACK:
00256 case TW_SR_GCALL_DATA_NACK:
00257 break;
00258 case TW_SR_STOP:
00259
00260 outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT)|BV(TWEA));
00261
00262 I2cState = I2C_IDLE;
00263 break;
00264
00265
00266 case TW_ST_SLA_ACK:
00267 case TW_ST_ARB_LOST_SLA_ACK:
00268 case TW_ST_DATA_ACK:
00269 case TW_ST_DATA_NACK:
00270 case TW_ST_LAST_DATA:
00271
00272 case TW_NO_INFO:
00273 case TW_BUS_ERROR:
00274 break;
00275 }
00276 }
00277
00278 void i2cSendNI(u08 deviceAddr, u08 length, u08* data)
00279 {
00280
00281 cbi(TWCR, TWIE);
00282
00283
00284 outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT)|BV(TWSTA));
00285 while( !(inb(TWCR) & BV(TWINT)) );
00286
00287
00288 outb(TWDR, (deviceAddr&0xFE) );
00289 outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT));
00290 while( !(inb(TWCR) & BV(TWINT)) );
00291
00292
00293 while(length)
00294 {
00295 outb(TWDR, *data++);
00296 outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT));
00297 while( !(inb(TWCR) & BV(TWINT)) );
00298 length--;
00299 }
00300
00301
00302
00303 outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT)|BV(TWEA)|BV(TWSTO));
00304
00305 sbi(TWCR, TWIE);
00306 }
00307
00308 void i2cReceiveNI(u08 deviceAddr, u08 length, u08 *data)
00309 {
00310
00311 cbi(TWCR, TWIE);
00312
00313
00314 outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT)|BV(TWSTA));
00315 while( !(inb(TWCR) & BV(TWINT)) );
00316
00317
00318 outb(TWDR, (deviceAddr&0xFE) | 0x01);
00319 outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT));
00320 while( !(inb(TWCR) & BV(TWINT)) );
00321
00322
00323 while(length > 1)
00324 {
00325 outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT)|BV(TWEA));
00326 while( !(inb(TWCR) & BV(TWINT)) );
00327 *data++ = inb(TWDR);
00328 length--;
00329 }
00330
00331
00332 outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT));
00333 while( !(inb(TWCR) & BV(TWINT)) );
00334 *data++ = inb(TWDR);
00335
00336
00337
00338 outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT)|BV(TWEA)|BV(TWSTO));
00339
00340 sbi(TWCR, TWIE);
00341 }