Go to the documentation of this file.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 #include <avr/io.h>
00043 #include <avr/interrupt.h>
00044 #include "usiTwiSlave.h"
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054 #if defined( __AVR_ATtiny2313__ )
00055 # define DDR_USI DDRB
00056 # define PORT_USI PORTB
00057 # define PIN_USI PINB
00058 # define PORT_USI_SDA PB5
00059 # define PORT_USI_SCL PB7
00060 # define PIN_USI_SDA PINB5
00061 # define PIN_USI_SCL PINB7
00062 # define USI_START_COND_INT USISIF
00063 # define USI_START_VECTOR USI_START_vect
00064 # define USI_OVERFLOW_VECTOR USI_OVERFLOW_vect
00065 #endif
00066
00067 #if defined( __AVR_ATtiny25__ ) | \
00068 defined( __AVR_ATtiny45__ ) | \
00069 defined( __AVR_ATtiny85__ )
00070 # define DDR_USI DDRB
00071 # define PORT_USI PORTB
00072 # define PIN_USI PINB
00073 # define PORT_USI_SDA PB0
00074 # define PORT_USI_SCL PB2
00075 # define PIN_USI_SDA PINB0
00076 # define PIN_USI_SCL PINB2
00077 # define USI_START_COND_INT USICIF
00078 # define USI_START_VECTOR USI_START_vect
00079 # define USI_OVERFLOW_VECTOR USI_OVF_vect
00080 #endif
00081
00082 #if defined( __AVR_ATtiny26__ )
00083 # define DDR_USI DDRB
00084 # define PORT_USI PORTB
00085 # define PIN_USI PINB
00086 # define PORT_USI_SDA PB0
00087 # define PORT_USI_SCL PB2
00088 # define PIN_USI_SDA PINB0
00089 # define PIN_USI_SCL PINB2
00090 # define USI_START_COND_INT USISIF
00091 # define USI_START_VECTOR USI_STRT_vect
00092 # define USI_OVERFLOW_VECTOR USI_OVF_vect
00093 #endif
00094
00095 #if defined( __AVR_ATtiny261__ ) | \
00096 defined( __AVR_ATtiny461__ ) | \
00097 defined( __AVR_ATtiny861__ )
00098 # define DDR_USI DDRB
00099 # define PORT_USI PORTB
00100 # define PIN_USI PINB
00101 # define PORT_USI_SDA PB0
00102 # define PORT_USI_SCL PB2
00103 # define PIN_USI_SDA PINB0
00104 # define PIN_USI_SCL PINB2
00105 # define USI_START_COND_INT USISIF
00106 # define USI_START_VECTOR USI_START_vect
00107 # define USI_OVERFLOW_VECTOR USI_OVF_vect
00108 #endif
00109
00110 #if defined( __AVR_ATmega165__ ) | \
00111 defined( __AVR_ATmega325__ ) | \
00112 defined( __AVR_ATmega3250__ ) | \
00113 defined( __AVR_ATmega645__ ) | \
00114 defined( __AVR_ATmega6450__ ) | \
00115 defined( __AVR_ATmega329__ ) | \
00116 defined( __AVR_ATmega3290__ )
00117 # define DDR_USI DDRE
00118 # define PORT_USI PORTE
00119 # define PIN_USI PINE
00120 # define PORT_USI_SDA PE5
00121 # define PORT_USI_SCL PE4
00122 # define PIN_USI_SDA PINE5
00123 # define PIN_USI_SCL PINE4
00124 # define USI_START_COND_INT USISIF
00125 # define USI_START_VECTOR USI_START_vect
00126 # define USI_OVERFLOW_VECTOR USI_OVERFLOW_vect
00127 #endif
00128
00129 #if defined( __AVR_ATmega169__ )
00130 # define DDR_USI DDRE
00131 # define PORT_USI PORTE
00132 # define PIN_USI PINE
00133 # define PORT_USI_SDA PE5
00134 # define PORT_USI_SCL PE4
00135 # define PIN_USI_SDA PINE5
00136 # define PIN_USI_SCL PINE4
00137 # define USI_START_COND_INT USISIF
00138 # define USI_START_VECTOR USI_START_vect
00139 # define USI_OVERFLOW_VECTOR USI_OVERFLOW_vect
00140 #endif
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150 #define SET_USI_TO_SEND_ACK( ) \
00151 { \
00152 \
00153 USIDR = 0; \
00154 \
00155 DDR_USI |= ( 1 << PORT_USI_SDA ); \
00156 \
00157 USISR = \
00158 ( 0 << USI_START_COND_INT ) | \
00159 ( 1 << USIOIF ) | ( 1 << USIPF ) | \
00160 ( 1 << USIDC )| \
00161 \
00162 ( 0x0E << USICNT0 ); \
00163 }
00164
00165 #define SET_USI_TO_READ_ACK( ) \
00166 { \
00167 \
00168 DDR_USI &= ~( 1 << PORT_USI_SDA ); \
00169 \
00170 USIDR = 0; \
00171 \
00172 USISR = \
00173 ( 0 << USI_START_COND_INT ) | \
00174 ( 1 << USIOIF ) | \
00175 ( 1 << USIPF ) | \
00176 ( 1 << USIDC ) | \
00177 \
00178 ( 0x0E << USICNT0 ); \
00179 }
00180
00181 #define SET_USI_TO_TWI_START_CONDITION_MODE( ) \
00182 { \
00183 USICR = \
00184 \
00185 ( 1 << USISIE ) | ( 0 << USIOIE ) | \
00186 \
00187 ( 1 << USIWM1 ) | ( 0 << USIWM0 ) | \
00188 \
00189 \
00190 ( 1 << USICS1 ) | ( 0 << USICS0 ) | ( 0 << USICLK ) | \
00191 \
00192 ( 0 << USITC ); \
00193 USISR = \
00194 \
00195 ( 0 << USI_START_COND_INT ) | ( 1 << USIOIF ) | ( 1 << USIPF ) | \
00196 ( 1 << USIDC ) | ( 0x0 << USICNT0 ); \
00197 }
00198
00199 #define SET_USI_TO_SEND_DATA( ) \
00200 { \
00201 \
00202 DDR_USI |= ( 1 << PORT_USI_SDA ); \
00203 \
00204 USISR = \
00205 ( 0 << USI_START_COND_INT ) | ( 1 << USIOIF ) | ( 1 << USIPF ) | \
00206 ( 1 << USIDC) | \
00207 \
00208 ( 0x0 << USICNT0 ); \
00209 }
00210
00211 #define SET_USI_TO_READ_DATA( ) \
00212 { \
00213 \
00214 DDR_USI &= ~( 1 << PORT_USI_SDA ); \
00215 \
00216 USISR = \
00217 ( 0 << USI_START_COND_INT ) | ( 1 << USIOIF ) | \
00218 ( 1 << USIPF ) | ( 1 << USIDC ) | \
00219 \
00220 ( 0x0 << USICNT0 ); \
00221 }
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231 typedef enum
00232 {
00233 USI_SLAVE_CHECK_ADDRESS = 0x00,
00234 USI_SLAVE_SEND_DATA = 0x01,
00235 USI_SLAVE_REQUEST_REPLY_FROM_SEND_DATA = 0x02,
00236 USI_SLAVE_CHECK_REPLY_FROM_SEND_DATA = 0x03,
00237 USI_SLAVE_REQUEST_DATA = 0x04,
00238 USI_SLAVE_GET_DATA_AND_SEND_ACK = 0x05
00239 } overflowState_t;
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249 static uint8_t slaveAddress;
00250 static volatile overflowState_t overflowState;
00251
00252
00253 static uint8_t rxBuf[ TWI_RX_BUFFER_SIZE ];
00254 static volatile uint8_t rxHead;
00255 static volatile uint8_t rxTail;
00256
00257 static uint8_t txBuf[ TWI_TX_BUFFER_SIZE ];
00258 static volatile uint8_t txHead;
00259 static volatile uint8_t txTail;
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273 static
00274 void
00275 flushTwiBuffers(
00276 void
00277 )
00278 {
00279 rxTail = 0;
00280 rxHead = 0;
00281 txTail = 0;
00282 txHead = 0;
00283 }
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297 void
00298 usiTwiSlaveInit(
00299 uint8_t ownAddress
00300 )
00301 {
00302
00303 flushTwiBuffers( );
00304
00305 slaveAddress = ownAddress;
00306
00307
00308
00309
00310
00311
00312
00313 DDR_USI |= ( 1 << PORT_USI_SCL ) | ( 1 << PORT_USI_SDA );
00314
00315
00316 PORT_USI |= ( 1 << PORT_USI_SCL );
00317
00318
00319 PORT_USI |= ( 1 << PORT_USI_SDA );
00320
00321
00322 DDR_USI &= ~( 1 << PORT_USI_SDA );
00323
00324 USICR =
00325
00326 ( 1 << USISIE ) |
00327
00328 ( 0 << USIOIE ) |
00329
00330 ( 1 << USIWM1 ) | ( 0 << USIWM0 ) |
00331
00332
00333 ( 1 << USICS1 ) | ( 0 << USICS0 ) | ( 0 << USICLK ) |
00334
00335 ( 0 << USITC );
00336
00337
00338
00339 USISR = ( 1 << USI_START_COND_INT ) | ( 1 << USIOIF ) | ( 1 << USIPF ) | ( 1 << USIDC );
00340
00341 }
00342
00343
00344
00345
00346
00347 void
00348 usiTwiTransmitByte(
00349 uint8_t data
00350 )
00351 {
00352
00353 uint8_t tmphead;
00354
00355
00356 tmphead = ( txHead + 1 ) & TWI_TX_BUFFER_MASK;
00357
00358
00359 while ( tmphead == txTail );
00360
00361
00362 txBuf[ tmphead ] = data;
00363
00364
00365 txHead = tmphead;
00366
00367 }
00368
00369
00370
00371
00372
00373 uint8_t
00374 usiTwiReceiveByte(
00375 void
00376 )
00377 {
00378
00379
00380 while ( rxHead == rxTail );
00381
00382
00383 rxTail = ( rxTail + 1 ) & TWI_RX_BUFFER_MASK;
00384
00385
00386 return rxBuf[ rxTail ];
00387
00388 }
00389
00390
00391
00392
00393
00394 bool
00395 usiTwiDataInReceiveBuffer(
00396 void
00397 )
00398 {
00399
00400
00401 return rxHead != rxTail;
00402
00403 }
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413 ISR( USI_START_VECTOR )
00414 {
00415
00416
00417 overflowState = USI_SLAVE_CHECK_ADDRESS;
00418
00419
00420 DDR_USI &= ~( 1 << PORT_USI_SDA );
00421
00422
00423
00424
00425
00426
00427 while (
00428
00429 ( PIN_USI & ( 1 << PIN_USI_SCL ) ) &&
00430
00431 !( ( PIN_USI & ( 1 << PIN_USI_SDA ) ) )
00432 );
00433
00434
00435 if ( !( PIN_USI & ( 1 << PIN_USI_SDA ) ) )
00436 {
00437
00438
00439
00440 USICR =
00441
00442 ( 1 << USISIE ) |
00443
00444 ( 1 << USIOIE ) |
00445
00446 ( 1 << USIWM1 ) | ( 1 << USIWM0 ) |
00447
00448
00449 ( 1 << USICS1 ) | ( 0 << USICS0 ) | ( 0 << USICLK ) |
00450
00451 ( 0 << USITC );
00452
00453 }
00454 else
00455 {
00456
00457
00458 USICR =
00459
00460 ( 1 << USISIE ) |
00461
00462 ( 0 << USIOIE ) |
00463
00464 ( 1 << USIWM1 ) | ( 0 << USIWM0 ) |
00465
00466
00467 ( 1 << USICS1 ) | ( 0 << USICS0 ) | ( 0 << USICLK ) |
00468
00469 ( 0 << USITC );
00470
00471 }
00472
00473 USISR =
00474
00475
00476 ( 1 << USI_START_COND_INT ) | ( 1 << USIOIF ) |
00477 ( 1 << USIPF ) |( 1 << USIDC ) |
00478
00479 ( 0x0 << USICNT0);
00480
00481 }
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495 ISR( USI_OVERFLOW_VECTOR )
00496 {
00497
00498 switch ( overflowState )
00499 {
00500
00501
00502
00503 case USI_SLAVE_CHECK_ADDRESS:
00504 if ( ( USIDR == 0 ) || ( ( USIDR >> 1 ) == slaveAddress) )
00505 {
00506 if ( USIDR & 0x01 )
00507 {
00508 overflowState = USI_SLAVE_SEND_DATA;
00509 }
00510 else
00511 {
00512 overflowState = USI_SLAVE_REQUEST_DATA;
00513 }
00514 SET_USI_TO_SEND_ACK( );
00515 }
00516 else
00517 {
00518 SET_USI_TO_TWI_START_CONDITION_MODE( );
00519 }
00520 break;
00521
00522
00523
00524 case USI_SLAVE_CHECK_REPLY_FROM_SEND_DATA:
00525 if ( USIDR )
00526 {
00527
00528 SET_USI_TO_TWI_START_CONDITION_MODE( );
00529 return;
00530 }
00531
00532
00533
00534
00535
00536 case USI_SLAVE_SEND_DATA:
00537
00538 if ( txHead != txTail )
00539 {
00540 txTail = ( txTail + 1 ) & TWI_TX_BUFFER_MASK;
00541 USIDR = txBuf[ txTail ];
00542 }
00543 else
00544 {
00545
00546 SET_USI_TO_TWI_START_CONDITION_MODE( );
00547 return;
00548 }
00549 overflowState = USI_SLAVE_REQUEST_REPLY_FROM_SEND_DATA;
00550 SET_USI_TO_SEND_DATA( );
00551 break;
00552
00553
00554
00555 case USI_SLAVE_REQUEST_REPLY_FROM_SEND_DATA:
00556 overflowState = USI_SLAVE_CHECK_REPLY_FROM_SEND_DATA;
00557 SET_USI_TO_READ_ACK( );
00558 break;
00559
00560
00561
00562 case USI_SLAVE_REQUEST_DATA:
00563 overflowState = USI_SLAVE_GET_DATA_AND_SEND_ACK;
00564 SET_USI_TO_READ_DATA( );
00565 break;
00566
00567
00568
00569 case USI_SLAVE_GET_DATA_AND_SEND_ACK:
00570
00571
00572 rxHead = ( rxHead + 1 ) & TWI_RX_BUFFER_MASK;
00573 rxBuf[ rxHead ] = USIDR;
00574
00575 overflowState = USI_SLAVE_REQUEST_DATA;
00576 SET_USI_TO_SEND_ACK( );
00577 break;
00578
00579 }
00580
00581 }