00001 /*C************************************************************************** 00002 * $RCSfile: twi_lib.c,v $ 00003 *---------------------------------------------------------------------------- 00004 * Copyright (c) 2002 Atmel. 00005 *---------------------------------------------------------------------------- 00006 * RELEASE: $Name: avr-can11-lib-mcu-0_0_3 $ 00007 * REVISION: $Revision: 1.22.2.3 $ 00008 * FILE_CVSID: $Id: twi_lib.c,v 1.22.2.3 2004/04/01 10:40:15 jberthy Exp $ 00009 *---------------------------------------------------------------------------- 00010 * PURPOSE: 00011 * This file provides all minimal functionnal access to the TWI interface 00012 * for T89C51Ix2 products. 00013 *****************************************************************************/ 00014 00015 00016 /*_____ I N C L U D E S ____________________________________________________*/ 00017 #include "config.h" 00018 #include "twi_lib.h" 00019 #include "twi_drv.h" 00020 00021 /*_____ G L O B A L D E F I N I T I O N _________________________________*/ 00022 volatile bit twi_busy; 00023 volatile unsigned char twi_err; 00024 volatile Length_TWI_frame twi_nb_transmited; 00025 volatile unsigned char twi_recptr; 00026 00027 /*V************************************************************************** 00028 * NAME: twi_slave_data[TWI_NB_SLAVE_DATA] 00029 *---------------------------------------------------------------------------- 00030 * PURPOSE: 00031 * Global public Variable for TWI message in slave mode 00032 *****************************************************************************/ 00033 volatile unsigned char xdata twi_slave_data[TWI_NB_SLAVE_DATA]; 00034 00035 /*V************************************************************************** 00036 * NAME: twi_message 00037 *---------------------------------------------------------------------------- 00038 * PURPOSE: 00039 * Global public Variable for TWI message in master mode 00040 *****************************************************************************/ 00041 volatile TWI_message xdata twi_message; 00042 00043 /*_____ D E F I N I T I O N ________________________________________________*/ 00044 #define MAX_READ_BUFFER 50 00045 00046 // write (without stop) + read 00047 extern volatile U8 flag_repeated_start; 00048 00049 // receive buffer is ready 00050 extern volatile U8 flag_receive_buffer; 00051 00052 // transmit buffer is ready 00053 extern volatile U8 flag_transmit_buffer; 00054 00055 extern U8 read_data_buffer[MAX_READ_BUFFER]; //data 00056 00057 extern U8 data_length; 00058 00059 /*_____ M A C R O S ________________________________________________________*/ 00060 00061 00062 /*F************************************************************************** 00063 * NAME: twi_lib_init 00064 *---------------------------------------------------------------------------- 00065 * PARAMS: 00066 * return: none 00067 *---------------------------------------------------------------------------- 00068 * PURPOSE: 00069 *---------------------------------------------------------------------------- 00070 * EXAMPLE: 00071 *---------------------------------------------------------------------------- 00072 * NOTE: 00073 *---------------------------------------------------------------------------- 00074 * REQUIREMENTS: 00075 *****************************************************************************/ 00076 void twi_lib_init(void) 00077 { 00078 Twi_set_baudrate(FOSC/TWI_BAUDRATE); 00079 Twi_init_hw(TWI_CONFIG); 00080 } 00081 00082 00083 /*F************************************************************************** 00084 * NAME: twi_decode_status 00085 *---------------------------------------------------------------------------- 00086 * PARAMS: 00087 * return: none 00088 *---------------------------------------------------------------------------- 00089 * PURPOSE: 00090 * main processing state machine for TWI message reception transmission 00091 * in slave or master mode. 00092 * This function is called when an event occured on the TWI interface. 00093 * Can be used both in polling or interrupt mode. 00094 *---------------------------------------------------------------------------- 00095 * EXAMPLE: 00096 *---------------------------------------------------------------------------- 00097 * NOTE: 00098 *---------------------------------------------------------------------------- 00099 * REQUIREMENTS: 00100 *****************************************************************************/ 00101 void twi_decode_status() 00102 { 00103 switch ( Twi_get_status() ) // switch (SSTA) 00104 { 00105 // STATE 00h: Bus Error has occurred 00106 // ACTION: Enter not addressed SLV mode and release bus 00107 case 0x00 : 00108 twi_busy = FALSE; 00109 twi_err = TWI_BUS_ERROR; 00110 break; 00111 00112 #ifdef TWI_MASTER 00113 //STATE 08h: A start condition has been sent 00114 //ACTION: SLR+R/W are transmitted, ACK bit received 00115 case 0x08 : 00116 Twi_clear_start(); //Pas besoin fait en hard ??? 00117 Twi_set_data(twi_message.address<<1); 00118 if ( twi_message.rw == TWI_READ ) 00119 { 00120 Twi_set_data(++Twi_get_data()); // Add 1 for Read bit in AdrWord 00121 } 00122 Twi_set_aa(); //from here to 0x18 transmit or 0x40 receive 00123 break; 00124 00125 //STATE 10h: A repeated start condition has been sent 00126 //ACTION: SLR+R/W are transmitted, ACK bit received 00127 case 0x10 : 00128 Twi_clear_start(); // Reset STA bit in SSCON 00129 Twi_set_data(twi_message.address<<1); 00130 if ( twi_message.rw == TWI_READ ) 00131 { 00132 Twi_set_data(++Twi_get_data()); // Add 1 for Read bit in AdrWord 00133 } 00134 Twi_set_aa(); // wait on ACK bit 00135 break; 00136 00137 //STATE 18h: SLR+W was transmitted, ACK bit received 00138 //ACTION: Transmit data byte, ACK bit received 00139 //PREVIOUS STATE: 0x08 or 0x10 00140 case 0x18 : // master transmit, after sending 00141 twi_nb_transmited=0; // slave address, now load data 00142 Twi_set_data(*(twi_message.buf)); // byte and send it 00143 00144 if (twi_message.nbbytes==0) // no datas to transmit 00145 { 00146 Twi_set_stop(); 00147 twi_err = TWI_OK; 00148 twi_busy = FALSE; // transfer complete, clear twi_busy 00149 } 00150 Twi_clear_si(); 00151 break; 00152 00153 //STATE 20h: SLR+W was transmitted, NOT ACK bit received 00154 //ACTION: Transmit STOP 00155 case 0x20 : 00156 Twi_set_stop(); // Twi_set_stop will also clear twiint flag 00157 twi_busy = FALSE; 00158 twi_err = TWI_HOST_ADR_NACK; 00159 break; 00160 00161 //STATE 28h: DATA was transmitted, ACK bit received 00162 //ACTION: If last byte, send STOP, else send more data bytes 00163 case 0x28: // master transmit, after sending ; data byte, ACK received 00164 twi_nb_transmited++; // inc nb data transmit on message 00165 twi_message.buf++; // inc pointer ti data to be transmited 00166 if ( twi_nb_transmited < twi_message.nbbytes ) // if there are still bytes to send 00167 { 00168 Twi_set_data(*(twi_message.buf)); 00169 Twi_set_aa(); // wait on ACK bit 00170 } 00171 else 00172 { 00173 if(flag_repeated_start == 1) 00174 { 00175 //repeated start 00176 Twi_repeated_start(); 00177 00178 //init next transmission 00179 twi_nb_transmited = 0; 00180 twi_message.rw = TWI_READ; 00181 twi_message.nbbytes = data_length; 00182 twi_message.buf = read_data_buffer; 00183 00184 flag_repeated_start = 0; 00185 } 00186 else if(flag_repeated_start == 0) 00187 { 00188 //run out of data, send stop, 00189 Twi_set_stop(); // Twi_set_stop will also clear twiint flag 00190 00191 //end of write command 00192 flag_transmit_buffer = 0; 00193 } 00194 00195 twi_err = TWI_OK; 00196 twi_busy = FALSE; //transfer complete, clear twi_busy 00197 } 00198 break; 00199 00200 //STATE 30h: DATA was transmitted, NOT ACK bit received 00201 //ACTION: Transmit STOP 00202 case 0x30 : 00203 Twi_set_stop(); // Twi_set_stop will also clear twiint flag 00204 twi_busy = FALSE; 00205 twi_err = TWI_HOST_ADR_NACK; 00206 break; 00207 00208 //STATE 38h: Arbitration lost in SLA+W or DATA. 00209 //ACTION: Release bus, enter not addressed SLV mode 00210 // Wait for bus lines to be free 00211 case 0x38 : 00212 twi_busy = FALSE; 00213 twi_err = TWI_ARBITRATION_LOST; 00214 Twi_clear_si(); 00215 // #ifdef USER_TWI_FCT_ARBITRATION_LOST_IN_SLA+W_OR_DATA 00216 // TWI_fct_arb_lostinSLAorDATA(); 00217 // #endif 00218 break; 00219 00220 //MASTER RECEIVER MODE FOLLOWS 00221 //STATE 40h: SLA+R transmitted, ACK received 00222 //ACTION: Receive DATA, ACK to be returned 00223 //PREVIOS STATE: 0x08 or 0x10 00224 case 0x40 : //master receive, after sending 00225 if ( twi_message.nbbytes == 1 ) 00226 { 00227 Twi_clear_aa(); // only one data to receive, noACK to be send after the fisrt incoming data 00228 Twi_clear_si(); 00229 } 00230 else if (!twi_message.nbbytes ) Twi_set_stop(); // special case: no data to read ! clear also twint 00231 else 00232 { 00233 Twi_set_aa(); //wait on ACK bit 00234 twi_nb_transmited=0; //data byte to be received, NOT ACK bit to follow --> 0x58 00235 } 00236 break; 00237 00238 //STATE 48h: SLA+R transmitted, NOT ACK received 00239 //ACTION: Transmit STOP 00240 case 0x48 : 00241 Twi_set_stop(); //clear also twint 00242 twi_busy = FALSE; 00243 twi_err = TWI_HOST_ADR_NACK; 00244 break; 00245 00246 //STATE 50h: Data has been received, ACK returned 00247 //ACTION: Read DATA. If expecting more continue else STOP 00248 case 0x50 : //master receive, received data 00249 //byte and ACK, copy it into 00250 *(twi_message.buf+twi_nb_transmited) = Twi_get_data(); //buffer 00251 twi_nb_transmited++; 00252 if ( twi_nb_transmited < (twi_message.nbbytes-1) ) Twi_set_aa(); // get more bytes 00253 else 00254 { 00255 Twi_clear_aa(); //only one more byte to come 00256 Twi_clear_si(); 00257 } 00258 break; 00259 00260 //STATE 58h: Data has been received, NOT ACK returned 00261 //ACTION: Read DATA. Generate STOP 00262 case 0x58 : 00263 *(twi_message.buf+twi_nb_transmited) = Twi_get_data(); 00264 Twi_set_stop(); 00265 00266 //the receive buffer is ready 00267 flag_receive_buffer = 0; 00268 00269 twi_busy = FALSE; 00270 twi_err = TWI_OK; 00271 break; 00272 #endif 00273 00274 00275 #ifdef TWI_SLAVE 00276 //STATE 60h: Own SLA+W has been received,ACK returned 00277 //ACTION: Read DATA. return ACK 00278 case 0x60 : 00279 Twi_set_aa(); 00280 twi_busy = TRUE; 00281 twi_recptr=0; 00282 break; 00283 00284 //STATE 68h: Arbitration lost in SLA and R/W as MASTER. Own SLA + W has been received. ACK returned 00285 //ACTION: Read DATA. return ACK ;re-start MASTER, 00286 case 0x68 : 00287 Twi_set_start(); 00288 break; 00289 00290 //STATE 70h: General call received, ACK returned 00291 //ACTION: Receive DATA. return ACK 00292 case 0x70 : 00293 Twi_set_aa(); 00294 twi_busy = TRUE; 00295 break; 00296 00297 //STATE 78h: Arbitration lost in SLA+R/W as MASTER. General call has arrived ack returned 00298 //ACTION: Receive DATA. return ACK. Restart master 00299 case 0x78 : 00300 Twi_set_start(); 00301 twi_busy = TRUE; 00302 break; 00303 00304 //STATE 80h: Previously addressed with own SLA. Data received and ACK returned 00305 //ACTION: Read DATA. 00306 case 0x80 : 00307 twi_slave_data[twi_recptr] = Twi_get_data(); 00308 twi_recptr ++; 00309 if ( twi_recptr < TWI_NB_SLAVE_DATA ) Twi_set_aa(); // ACK will be returned 00310 else 00311 { 00312 Twi_clear_aa(); // it was last data not ACK will be returned ( buffer full ) 00313 Twi_clear_si(); 00314 } 00315 break; 00316 00317 //STATE 88h: Previously addressed with own SLA. Data received and NOT ACK returned 00318 //ACTION: Dont' Read DATA. Enter NOT addressed SLV mode 00319 case 0x88 : 00320 //STATE 98h: Previously addressed with general call. Data arrved and NOT ACK returned 00321 //ACTION: Dont Read DATA. Enter NOT addressed SLV mode 00322 case 0x98 : 00323 Twi_set_aa(); // ready to send another ACK if addresed as slave 00324 break; 00325 00326 //STATE 90h: Previously addressed with general call. Data received and ACK returned 00327 //ACTION: Read DATA. 00328 case 0x90 : 00329 twi_slave_data[twi_recptr] = Twi_get_data(); 00330 twi_recptr = twi_recptr + 1; 00331 Twi_clear_si(); 00332 break; 00333 00334 //STATE A0h: A stop or repeated start has arrived, whilst still addressed as SLV/REC or SLV/TRX 00335 //ACTION: Dont Read DATA. Enter NOT addressed SLV mode 00336 case 0xA0 : 00337 Twi_set_aa(); 00338 twi_busy = FALSE; 00339 twi_err = TWI_OK; 00340 break; 00341 00342 //STATE A8h: addressed with own SLA+R 00343 //ACTION: Prepare first data to be transmited 00344 case 0xA8 : 00345 00346 twi_busy = TRUE; 00347 twi_recptr=0; 00348 Twi_set_data(twi_slave_data[0]); // Prepare next data 00349 Twi_set_aa(); 00350 break; 00351 00352 00353 //STATE B8h: Previously addressed with own SLA. Data sent 00354 // and ACK returned 00355 //ACTION: Write DATA. 00356 case 0xB8 : 00357 twi_recptr++; 00358 if ( twi_recptr < TWI_NB_SLAVE_DATA ) Twi_set_data(twi_slave_data[twi_recptr]); 00359 else 00360 Twi_clear_aa(); // it was last data not ACK will be returned ( buffer full ) 00361 Twi_clear_si(); 00362 break; 00363 00364 00365 //STATE C0h: Previously addressed with own SLA. Data sent and NACK returned 00366 //ACTION: It was last data to be sent 00367 case 0xC0 : 00368 twi_busy=FALSE; 00369 twi_err = TWI_OK; 00370 Twi_clear_si(); 00371 break; 00372 #endif 00373 00374 //if we arrived here, unknown state has occurred..... 00375 default : 00376 Twi_set_stop(); 00377 twi_busy = FALSE; 00378 twi_err = TWI_UNKNOWN; 00379 break; 00380 } 00381 } 00382 00383 00384 #ifdef TWI_MASTER 00385 unsigned char twi_send_message_polling( unsigned char slave_addr,bit rw, Length_TWI_frame nbbytes, unsigned char *info ) 00386 { 00387 twi_message.address = slave_addr; 00388 twi_message.rw = rw; 00389 twi_message.nbbytes = nbbytes; 00390 twi_message.buf = info; 00391 Twi_wait_hw_stop(); 00392 Disable_twi_interrupt(); //FIXME 00393 twi_nb_transmited=0; 00394 if (!twi_busy) 00395 { 00396 twi_busy =1; 00397 twi_err = TWI_OK; 00398 Twi_set_start(); 00399 while (twi_busy) 00400 { 00401 Twi_wait_event(); 00402 twi_decode_status(); 00403 // Twi_clear_si(); //REMOVE FROM MAIN LOOP, ADDED IN ALL NECESARY CASE (See JSB /RLE) 00404 } 00405 // Twi_set_stop(); RLE 00406 return twi_err; 00407 } 00408 Twi_set_stop(); 00409 return TWI_NOT_FREE; 00410 } 00411 #endif 00412 00413 00414 00415 #ifdef TWI_MASTER 00416 #ifndef DO_NOT_USE_TWI_INTERRUPT 00417 /*F************************************************************************** 00418 * NAME: twi_send_message_interrupt 00419 *---------------------------------------------------------------------------- 00420 * PARAMS: 00421 * *slave_addr: The slave component address 00422 * rw: Read or write operation flag ( read = 1 ) 00423 * nbbytes: number of bytes to be read or write 00424 * *info: pointer to the data to be processed 00425 * return: TWI error code state 00426 *---------------------------------------------------------------------------- 00427 * PURPOSE: 00428 * This function can be used to send an TWI message to a slave 00429 * in interrupt mode. 00430 *---------------------------------------------------------------------------- 00431 * EXAMPLE: 00432 *---------------------------------------------------------------------------- 00433 * NOTE: 00434 *---------------------------------------------------------------------------- 00435 * REQUIREMENTS: 00436 *****************************************************************************/ 00437 unsigned char twi_send_message_interrupt( unsigned char slave_addr,bit rw, Length_TWI_frame nbytes, unsigned char *info) 00438 { 00439 twi_message.address = slave_addr; 00440 twi_message.rw = rw; 00441 twi_message.nbbytes = nbytes; 00442 twi_message.buf = info; 00443 Twi_wait_hw_stop(); 00444 twi_nb_transmited=0; 00445 if (!twi_busy) 00446 { 00447 twi_err = TWI_OK; 00448 twi_busy =1; 00449 Enable_twi_interrupt(); 00450 Twi_set_start(); 00451 return twi_err; 00452 } 00453 Twi_set_stop(); 00454 return TWI_NOT_FREE; 00455 } 00456 #endif 00457 #endif 00458 00459 00460 #ifdef TWI_SLAVE 00461 /*F************************************************************************** 00462 * NAME: twi_slave_polling 00463 *---------------------------------------------------------------------------- 00464 * PARAMS: 00465 * return: TWI error code state 00466 *---------------------------------------------------------------------------- 00467 * PURPOSE: 00468 * This function can be called to be able to answer another master request 00469 * in polling mode. 00470 *---------------------------------------------------------------------------- 00471 * EXAMPLE: 00472 *---------------------------------------------------------------------------- 00473 * NOTE: 00474 *---------------------------------------------------------------------------- 00475 * REQUIREMENTS: 00476 *****************************************************************************/ 00477 unsigned char twi_slave_polling(void) 00478 { 00479 Twi_wait_event(); 00480 twi_decode_status(); 00481 Twi_clear_si(); 00482 while (twi_busy) 00483 { 00484 Twi_wait_event(); 00485 twi_decode_status(); 00486 // Twi_clear_si();//REMOVE FROM MAIN LOOP, ADDED IN ALL NECESARY CASE (See JSB /RLE) 00487 } 00488 return twi_err; 00489 } 00490 00491 /*F************************************************************************** 00492 * NAME: twi_slave_interrupt 00493 *---------------------------------------------------------------------------- 00494 * PARAMS: 00495 * return: none 00496 *---------------------------------------------------------------------------- 00497 * PURPOSE: 00498 * This function can be called to be able to answer another master request 00499 * in interrupt mode (stand alone mode). 00500 *---------------------------------------------------------------------------- 00501 * EXAMPLE: 00502 *---------------------------------------------------------------------------- 00503 * NOTE: 00504 *---------------------------------------------------------------------------- 00505 * REQUIREMENTS: 00506 *****************************************************************************/ 00507 void twi_slave_interrupt(void) 00508 { 00509 Enable_interrupt(); 00510 Enable_twi_interrupt(); 00511 } 00512 #endif 00513 00514 /*F************************************************************************** 00515 * NAME: twi_putchar 00516 *---------------------------------------------------------------------------- 00517 * PARAMS: 00518 * return: 00519 *---------------------------------------------------------------------------- 00520 * PURPOSE: 00521 * *---------------------------------------------------------------------------- 00522 * EXAMPLE: 00523 *---------------------------------------------------------------------------- 00524 * NOTE: 00525 *---------------------------------------------------------------------------- 00526 * REQUIREMENTS: 00527 *****************************************************************************/ 00528 Byte twi_putchar(Byte addr, Byte b) 00529 { 00530 Twi_wait_hw_stop(); 00531 Twi_set_start(); 00532 Twi_wait_event(); 00533 if (Twi_get_status() == 0x08) //start sent 00534 { 00535 Twi_clear_start(); 00536 Twi_set_data(addr<<1); 00537 Twi_set_aa(); //Also clear TWINT 00538 Twi_wait_event(); 00539 if (Twi_get_status() == 0x18) //ADR+W sent 00540 { 00541 Twi_set_data(b); 00542 Twi_clear_si(); 00543 Twi_wait_event(); 00544 if (Twi_get_status() == 0x28) //data sent 00545 { 00546 Twi_set_stop(); 00547 Twi_clear_si(); 00548 return TWI_OK; 00549 } 00550 } 00551 else 00552 { 00553 Twi_clear_start(); 00554 Twi_set_stop(); //Also clear TWINT 00555 } 00556 } 00557 Twi_clear_start(); 00558 Twi_clear_si(); 00559 return TWI_UNKNOWN; 00560 } 00561 00562 /*F************************************************************************** 00563 * NAME: twi_getchar 00564 *---------------------------------------------------------------------------- 00565 * PARAMS: 00566 * return: 00567 *---------------------------------------------------------------------------- 00568 * PURPOSE: 00569 * *--------------------------------------------------------------------------- 00570 * EXAMPLE: 00571 *---------------------------------------------------------------------------- 00572 * NOTE: 00573 *---------------------------------------------------------------------------- 00574 * REQUIREMENTS: 00575 *****************************************************************************/ 00576 Uint16 twi_getchar(Byte addr) 00577 { 00578 Union16 data ret; 00579 00580 ret.b[0] = TWI_UNKNOWN; 00581 ret.b[1] = 0; 00582 Twi_wait_hw_stop(); 00583 Twi_set_start(); 00584 Twi_wait_event(); 00585 if (Twi_get_status() == 0x08) //start sent 00586 { 00587 Twi_clear_start(); 00588 Twi_set_data((addr<<1)+1); //ADR+R 00589 Twi_set_aa(); //Also clear TWINT 00590 Twi_wait_event(); 00591 if (Twi_get_status() == 0x40) //ADR+R sent 00592 { 00593 Twi_clear_aa(); //only one byte t receive: NACK after 00594 Twi_clear_si(); 00595 Twi_wait_event(); 00596 if (Twi_get_status() == 0x58) //data received 00597 { 00598 ret.b[1] = Twi_get_data(); 00599 Twi_set_stop(); //Also clear TWINT 00600 ret.b[0] = TWI_OK; 00601 } 00602 } 00603 else 00604 { 00605 Twi_clear_start(); 00606 Twi_set_stop(); //Also clear TWINT 00607 } 00608 } 00609 return ret.w; 00610 } 00611 00612 00613 00614 /*F************************************************************************** 00615 * NAME: twi_interrupt 00616 *---------------------------------------------------------------------------- 00617 * PARAMS: 00618 * return: none 00619 *---------------------------------------------------------------------------- 00620 * PURPOSE: 00621 * TWI interrupt routine service 00622 *---------------------------------------------------------------------------- 00623 * EXAMPLE: 00624 *---------------------------------------------------------------------------- 00625 * NOTE: 00626 *---------------------------------------------------------------------------- 00627 * REQUIREMENTS: 00628 *****************************************************************************/ 00629 #ifdef AVRGCC 00630 ISR(TWI_vect) 00631 #else 00632 #pragma vector = TWI_vect 00633 __interrupt void twi_interrupt() 00634 #endif 00635 { 00636 twi_decode_status(); 00637 // Twi_clear_si(); //REMOVE FROM MAIN LOOP, ADDED IN ALL NECESARY CASE (See JSB /RLE) 00638 }