C51 COMPILER V7.09   IIC                                                                   06/22/2006 17:37:20 PAGE 1   


C51 COMPILER V7.09, COMPILATION OF MODULE IIC
OBJECT MODULE PLACED IN iic.OBJ
COMPILER INVOKED BY: C:\Keil\C51\BIN\C51.EXE iic.c OPTIMIZE(SIZE) BROWSE DEBUG OBJECTEXTEND

line level    source

   1          /*
   2          **********************************************************************************************************
             -***********
   3          *                                                                                               I2C BUS LOW LEVEL FUNCTIONS
   4          *
   5          * Description:  Low level IIC functions
   6          * File:                 iic.c
   7          * Software:             Keil C (C51) compiler, eval version 7.09 under uVision2 IDE v2.40
   8          * Programmer:   John Leung, TechToys Co. (www.TechToys.com.hk)
   9          * Hardware:             gLCD-STK1
  10          * Date:                 14th May 2006
  11          * Version:              1.0
  12          *
  13          **********************************************************************************************************
             -***********
  14          */
  15          #include <REGX52.h>
  16          #include <intrins.h>
  17          #include "iic.h"
  18          
  19          /*
  20          **********************************************************************************************************
             -***********
  21          *                                                                                                       LOCAL DEFINITIONS
  22          **********************************************************************************************************
             -***********
  23          */
  24          #define HIGH                            1
  25          #define LOW                                     0
  26          #define Delay5Us        {_nop_();_nop_();_nop_();_nop_();_nop_();}      //for 12MHz xtal, generic 8051
  27          
  28          /*
  29          **********************************************************************************************************
             -***********
  30          *                                                                                       IIC START CONDITION GENERATION
  31          * Function:     Generate an I2C bus start condition
  32          * Argument:     none
  33          * Return:       none
  34          * Note:         Hardware-dependent for direct I/O operation on SDA and SCL required.
  35          *                       Delay5Us is a macro assuming the system clock (xtal) is 12MHz or less for 12-clock 8051
  36          **********************************************************************************************************
             -***********
  37          */
  38          void i2c_Start(void)
  39          {
  40   1              SDA = HIGH;
  41   1              SCL = HIGH;
  42   1              Delay5Us;
  43   1              SDA = LOW;              
  44   1              Delay5Us;
  45   1              SCL = LOW;
  46   1      }
  47          
  48          /*
  49          **********************************************************************************************************
C51 COMPILER V7.09   IIC                                                                   06/22/2006 17:37:20 PAGE 2   

             -***********
  50          *                                                                                       IIC STOP CONDITION GENERATION
  51          * Function:     Generate an I2C stop condition
  52          * Argument:     none
  53          * Return:       none
  54          * Note:         Hardware-dependent for direct I/O operation on SDA and SCL required.
  55          *                       Delay5Us is a macro assuming the system clock (xtal) is 12MHz or less for 12-clock 8051
  56          **********************************************************************************************************
             -***********
  57          */
  58          void i2c_Stop(void)
  59          {
  60   1              SDA = LOW;
  61   1              SCL = HIGH;
  62   1              Delay5Us;
  63   1              SDA = HIGH;
  64   1              Delay5Us;
  65   1      }
  66          
  67          /*
  68          **********************************************************************************************************
             -***********
  69          *                                                                                       IIC ACK CONDITION GENERATION
  70          * Function:     This function is called to generate an ACK or noACK.
  71          * Argument:     'reply'         ACK if an acknowledge is required, i.e. SDA pulled low
  72          *                                               noACK if an acknowledge not required, i.e. SDA pulled high
  73          * Return:       none
  74          * Warning:      The argument reply of type 'bit', which is KEIL C specific
  75          * Note:         ACK and noACK constants defined under iic.h, public constants
  76          *                       Hardware-dependent for direct I/O operation on SDA and SCL required.            
  77          *                       Delay5Us is a macro assuming the system clock (xtal) is 12MHz or less for 12-clock 8051
  78          **********************************************************************************************************
             -***********
  79          */
  80          void i2c_Ack(bit reply)
  81          {
  82   1              (reply==ACK)?(SDA=LOW):(SDA=HIGH);
  83   1              _nop_();_nop_();_nop_();
  84   1              SCL = HIGH;
  85   1              Delay5Us;
  86   1              SCL=LOW;
  87   1              _nop_();_nop_();
  88   1      }
  89          
  90          /*
  91          **********************************************************************************************************
             -***********
  92          *                                                                               IIC LOW LEVEL SEND BYTE FUNCTION
  93          * Function:     This function is called to write a byte to the i2c bus in MBS first.
  94          *                       The function caller(master) sends a byte, and in the 9th bit, waits for an ACK or noACK
  95          *                       from the slave. The slave may reply either ACK or noACK.
  96          *                       Waiting for ACK signal is NOT infinite to avoid program hang-up.
  97          *                       Statement 'while((SDA==HIGH)&&(i++<0x80))' employed for ACK waiting with timeout
  98          * Argument:     'c'             the byte to send
  99          * Return:       ACK     if the slave does acknowledge
 100          *                       noACK   if the slave didn't acknowledge
 101          *                       ACK and noACK defined under iic.h, public constants
 102          * WARNING : the type 'bit' is KEIL C specific
 103          * Note:         Hardware-dependent for direct I/O operation on SDA and SCL required.
 104          *                       Delay5Us is a macro assuming the system clock (xtal) is 12MHz or less for 12-clock 8051
 105          **********************************************************************************************************
             -***********
C51 COMPILER V7.09   IIC                                                                   06/22/2006 17:37:20 PAGE 3   

 106          */
 107          bit i2c_SendByte(unsigned char c)
 108          {
 109   1              unsigned char i;
 110   1      
 111   1              for(i=0;i<8;i++)
 112   1              {
 113   2                      ((c<<i)&0x80)? (SDA = HIGH):(SDA = LOW);
 114   2                      _nop_();
 115   2                      SCL = HIGH;
 116   2                      Delay5Us;       //for data on SDA to be valid for at least 4.7usec
 117   2                      SCL = LOW;
 118   2              }
 119   1              i=0;
 120   1              SDA = HIGH;             //release data line to read ACK/noACK signal from slave
 121   1              SCL = HIGH;             //take clock line high for a stable data line read
 122   1              while((SDA==HIGH)&&(i++<0x80));
 123   1              (SDA==LOW)? (i = ACK):(i = noACK);
 124   1              SCL = LOW;
 125   1              _nop_();_nop_();
 126   1              return (i);
 127   1      }
 128          
 129          /*
 130          **********************************************************************************************************
             -***********
 131          *                                                                                       IIC LOW LEVEL READ BYTE FUNCTION
 132          * Function:     This function is called to read a byte from the i2c bus.
 133          * Argument:     none
 134          * Return:       The byte read from the IIC bus
 135          * Note:         Hardware-dependent for direct I/O operation on SDA and SCL required.
 136          *                       Delay5Us is a macro assuming the system clock (xtal) is 12MHz or less for 12-clock 8051
 137          **********************************************************************************************************
             -***********
 138          */
 139          unsigned char i2c_RcvByte(void)
 140          {
 141   1              unsigned char val=0;
 142   1              unsigned char i;
 143   1              
 144   1              SDA = HIGH;                             //release data line for input
 145   1      
 146   1              for(i=0; i<8; i++)              //bit counter from 0 to 7 (inclusive)
 147   1              {
 148   2                      SCL = LOW;
 149   2                      Delay5Us;
 150   2                      SCL = HIGH;
 151   2                      _nop_();_nop_();
 152   2                      val = val<<1;
 153   2                      if (SDA==HIGH) val = val|1;
 154   2              }
 155   1      
 156   1              SCL = LOW;
 157   1              _nop_();_nop_();
 158   1              return (val);
 159   1      }
 160          
 161          /*
 162          **********************************************************************************************************
             -***********
 163          *                                                                                               SEQUENTIAL WRITE BYTES
 164          * Function:     This function is called to sequentially write an array/string of a certain length
C51 COMPILER V7.09   IIC                                                                   06/22/2006 17:37:20 PAGE 4   

 165          *                       to an iic slave. STOP bit is not generated at the end of every byte written except
 166          *                       the last byte.
 167          * Argument:     'device'        iic device address, e.g. 0xA0 for 24LC02 EEPROM, 0xA2 for PCF8563 RTC etc
 168          *                       'addrh'         internal address's high byte, if any. If address is 8-bit, 
 169          *                                               this should be passed a NONE defined under iic.h
 170          *                       'addrl'         internal address's low address byte.
 171          *                       '*s'            pointer to the array/string to write
 172          *                       'length'        length of the array or string to write
 173          * Return:       'noACK' if any of the iic write action passes a bus collision error
 174          *                       'ACK'   if all of the iic write action successful
 175          * WARNING : the type 'bit' is KEIL C specific
 176          * Note:         Example:
 177          *                       s[0] = 0x00; s[1] = 0x12;
 178          *                       i2c_SeqWr(0xA2, NONE, 0x00, &s[0], 2);  //This is to initialize PCF8563 rtc
 179          **********************************************************************************************************
             -***********
 180          */
 181          bit i2c_SeqWr(unsigned char device, unsigned char addrh, unsigned char addrl, unsigned char *s, unsigned c
             -har length)
 182          {
 183   1              unsigned char i;
 184   1      
 185   1              i2c_Start();
 186   1              if(i2c_SendByte(device)==noACK) return (noACK);
 187   1              if(addrh!=NONE) 
 188   1              {
 189   2                      if(i2c_SendByte(addrh)==noACK) return (noACK);
 190   2              }
 191   1              if(i2c_SendByte(addrl)==noACK) return (noACK);
 192   1              for (i=0;i<length;i++)
 193   1              {
 194   2                      if(i2c_SendByte(*s)==noACK) return (noACK);
 195   2                      s++;
 196   2              }
 197   1              i2c_Stop();
 198   1              return (ACK);
 199   1      }
 200          
 201          /*
 202          **********************************************************************************************************
             -***********
 203          *                                                                                               SEQUENTIAL READ BYTES
 204          * Function:     This function is called to sequentially read an array/string of a certain length
 205          *                       from an iic slave.
 206          * Argument:     'device'        iic device address, e.g. 0xA0 for 24LC02 EEPROM, 0xA2 for PCF8563 RTC etc
 207          *                       'addrh'         internal address's high byte, if any. If address is 8-bit, 
 208          *                                               this should be passed a NONE defined under iic.h
 209          *                       'addrl'         intermal address's low address byte.
 210          *                       '*s'            pointer to the array/string to read
 211          *                       'length'        length of the array or string to write
 212          * Return:       'noACK' if any of the iic write action passes a bus collision error
 213          *                       'ACK'   if all of the iic write action successful
 214          * WARNING : the type 'bit' is KEIL C specific. Array/string passed to *s should be large enough to hold th
             -e 
 215          *                       total data length.
 216          * Note:         
 217          **********************************************************************************************************
             -***********
 218          */
 219          bit i2c_SeqRd(unsigned char device, unsigned char addrh, unsigned char addrl, unsigned char *s, unsigned c
             -har length)
 220          {
C51 COMPILER V7.09   IIC                                                                   06/22/2006 17:37:20 PAGE 5   

 221   1              unsigned char i;
 222   1      
 223   1              i2c_Start();
 224   1              if(i2c_SendByte(device)==noACK) return (noACK);
 225   1              if(addrh!=NONE) 
 226   1              {
 227   2                      if(i2c_SendByte(addrh)==noACK) return (noACK);
 228   2              }
 229   1              if(i2c_SendByte(addrl)==noACK) return (noACK);
 230   1              i2c_Start();
 231   1              //RTC_ADDR+1 = 1010 001R/W, R/W = 1 for READ, R/W = 0 for WRITE
 232   1              if(i2c_SendByte(device+1)==noACK) return (noACK);
 233   1              
 234   1              for(i=0; i<length-1; i++)
 235   1              {
 236   2                      *s = i2c_RcvByte();
 237   2                      i2c_Ack(ACK);
 238   2                      s++;
 239   2              }
 240   1      
 241   1              *s = i2c_RcvByte();
 242   1              i2c_Ack(noACK);
 243   1              i2c_Stop();
 244   1      
 245   1              return (ACK);
 246   1      }


MODULE INFORMATION:   STATIC OVERLAYABLE
   CODE SIZE        =    348    ----
   CONSTANT SIZE    =   ----    ----
   XDATA SIZE       =   ----    ----
   PDATA SIZE       =   ----    ----
   DATA SIZE        =   ----      14
   IDATA SIZE       =   ----    ----
   BIT SIZE         =   ----       1
END OF MODULE INFORMATION.


C51 COMPILATION COMPLETE.  0 WARNING(S),  0 ERROR(S)
