twi_lib.c

Go to the documentation of this file.
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 }

Generated on Mon Dec 1 11:12:21 2008 for AVR498 : Atmel BLDC control on ATAVRMC301 with ATtiny861 by  doxygen 1.5.4