ixp425I2c.c
上传用户:luoyougen
上传日期:2008-05-12
资源大小:23136k
文件大小:9k
源码类别:

VxWorks

开发平台:

C/C++

  1. /* ixp425I2c.c - Intel IXP425 I2C source file */
  2. /* Copyright 2002 Wind River Systems, Inc. */
  3. /*
  4. modification history
  5. --------------------
  6. 01a,05jun02,jb  initial version...
  7. */
  8. /*
  9. DESCRIPTION
  10. This is the driver for the Intel IXP425 I2C bus protocol. This is a software
  11. only implementation which uses two pins on the IXP425 GPIO Controller.
  12. Note the IXP425 only supports one master device i.e. the GPIO controller
  13. itself.
  14. USAGE
  15. An example read from an I2C device using the individual protocol functions
  16. is shown below:
  17. {
  18. :
  19.     if (ixp425I2CStart() == OK)
  20.         {
  21.         ixp425I2CByteTransmit((devAddr & IXP425_I2C_WRITE_MSK));
  22.         ixp425I2CAckReceive();
  23. ixp425I2CByteTransmit(offset);
  24. ixp425I2CAckReceive();
  25.         -- Switch to read mode --
  26. IXP425_I2C_SCL_SET_HIGH;
  27.         IXP425_I2C_SDA_SET_HIGH;
  28.         if(ixp425I2CStart() != OK)
  29.     {
  30.     ixp425I2CStop();
  31.     return(ERROR);
  32.     }
  33.         ixp425I2CByteTransmit((devAddr | IXP425_I2C_READ_FLAG));
  34. ixp425I2CAckReceive();
  35. for(byteCnt=0; byteCnt<num; byteCnt++)
  36.     {
  37.             ixp425I2CByteReceive(Buf);
  38.             Buf++;
  39.     -- Prevent giving an ACK on the last byte --
  40.             if (byteCnt < (num - 1))
  41.                 ixp425I2CAckSend();
  42.     }
  43. ixp425I2CStop();
  44. :
  45. }
  46. }
  47. INCLUDE FILES: ixp425I2c.h
  48. SEE ALSO:
  49. .I "Ixp425 Data Sheet,"
  50. */
  51. /* includes */
  52. #include "vxWorks.h"
  53. #include "ixp425.h"
  54. #include "ixdp425.h"
  55. #include "ixp425Gpio.h"
  56. #include "ixp425I2c.h"
  57. #include "intLib.h"
  58. /* defines */
  59. /* Microsecond delay for SCL setup and hold times */
  60. #define IXP425_I2C_SCLDELAY sysMicroDelay(10)
  61. /* Data setup time */
  62. #define IXP425_I2C_SDADELAY sysMicroDelay(1)
  63. #define IXP425_I2C_SDA_GET(val) (ixp425GPIOLineGet(IXP425_I2C_SDA, val))
  64. #define IXP425_I2C_SCL_GET(val) (ixp425GPIOLineGet(IXP425_I2C_SCL, val)) 
  65. #define IXP425_I2C_SDA_SET_HIGH {
  66.         ixp425GPIOLineSet(IXP425_I2C_SDA, IXP425_GPIO_HIGH); 
  67. IXP425_I2C_SDADELAY;}
  68. #define IXP425_I2C_SDA_SET_LOW {
  69. ixp425GPIOLineSet(IXP425_I2C_SDA, IXP425_GPIO_LOW); 
  70. IXP425_I2C_SDADELAY;}
  71. #define IXP425_I2C_SCL_SET_HIGH {
  72. ixp425GPIOLineSet(IXP425_I2C_SCL, IXP425_GPIO_HIGH); 
  73. IXP425_I2C_SCLDELAY;}
  74. #define IXP425_I2C_SCL_SET_LOW {
  75. ixp425GPIOLineSet(IXP425_I2C_SCL, IXP425_GPIO_LOW); 
  76. IXP425_I2C_SCLDELAY;}
  77. extern void sysMicroDelay();
  78. /* forward declarations */
  79. LOCAL STATUS ixp425I2CBusFree (void);
  80. /******************************************************************************
  81. *
  82. * ixp425I2CStart (Control signal) - Initiate a transfer on the I2C bus. This 
  83. *  should only be called from a master device (i.e. GPIO controller
  84. *  on IXP425)
  85. *
  86. * RETURNS: OK when the bus is free. ERROR if the bus is already in use by another
  87. *    task.
  88. */
  89. STATUS ixp425I2CStart ()
  90.     {
  91.     int key;
  92.     key =  intLock();
  93.     if (ixp425I2CBusFree() == OK)
  94.         {
  95.         ixp425GPIOLineConfig(IXP425_I2C_SDA, IXP425_GPIO_OUT);
  96.         ixp425GPIOLineConfig(IXP425_I2C_SCL, IXP425_GPIO_OUT);
  97. IXP425_I2C_SCL_SET_HIGH;
  98.         IXP425_I2C_SDA_SET_HIGH;
  99.         IXP425_I2C_SDA_SET_LOW;
  100. intUnlock(key);
  101. return (OK);
  102.         }
  103.     
  104.     intUnlock(key);
  105.     return (ERROR);
  106.     }
  107. /******************************************************************************
  108. *
  109. * ixp425I2CStop (Control signal) - End a transfer session. The I2C bus will be
  110. * left in a free state; i.e. SCL HIGH and SDA HIGH. This should
  111. * only be called from a master device (i.e. GPIO controller on 
  112. * IXP425)
  113. *
  114. * RETURNS: N/A
  115. */
  116. void ixp425I2CStop ()
  117.     {
  118.     ixp425GPIOLineConfig(IXP425_I2C_SDA, IXP425_GPIO_OUT);
  119.     ixp425GPIOLineConfig(IXP425_I2C_SCL, IXP425_GPIO_OUT);
  120.     IXP425_I2C_SDA_SET_LOW;
  121.     IXP425_I2C_SCL_SET_HIGH;
  122.     IXP425_I2C_SDA_SET_HIGH;
  123.     }
  124. /******************************************************************************
  125. * ixp425I2CAckSend (Control signal) - Send an acknowledgement
  126. *
  127. * This function sends an acknowledgement on the I2C bus.
  128. * RETURNS: N/A
  129. */
  130. void ixp425I2CAckSend ()
  131.     {
  132.     ixp425GPIOLineConfig(IXP425_I2C_SDA, IXP425_GPIO_OUT);
  133.     ixp425GPIOLineConfig(IXP425_I2C_SCL, IXP425_GPIO_OUT);
  134.     IXP425_I2C_SDA_SET_LOW;
  135.     IXP425_I2C_SCL_SET_HIGH;
  136.     IXP425_I2C_SCL_SET_LOW;
  137.     IXP425_I2C_SDA_SET_HIGH;
  138.     }
  139. /******************************************************************************
  140. * ixp425I2CAckReceive (Control Signal) - Get an acknowledgement from the I2C bus.
  141. * RETURNS: OK if acknowledge received by slave; ERROR otherwise.
  142. */
  143. STATUS ixp425I2CAckReceive ()
  144.     {
  145.     int retryCnt = 0;
  146.     IXP425_GPIO_SIG sda;
  147.     ixp425GPIOLineConfig(IXP425_I2C_SDA, IXP425_GPIO_OUT);
  148.     ixp425GPIOLineConfig(IXP425_I2C_SCL, IXP425_GPIO_OUT);
  149.     IXP425_I2C_SDA_SET_HIGH;   
  150.     ixp425GPIOLineConfig(IXP425_I2C_SDA, IXP425_GPIO_IN);
  151.     IXP425_I2C_SCL_SET_HIGH;
  152.     do
  153.     {
  154.     IXP425_I2C_SDA_GET(&sda);
  155.     retryCnt++;
  156.     }while( (sda != IXP425_GPIO_LOW) && (retryCnt < IXP425_I2C_ACK_RTY) );
  157.     IXP425_I2C_SCL_SET_LOW;    
  158.     if (sda != IXP425_GPIO_LOW)
  159. return (ERROR);
  160.     else
  161. return (OK);
  162.     }
  163. /******************************************************************************
  164. *
  165. * ixp425I2CByteTransmit - Transmit a byte on the I2C bus. All byte transfers are
  166. * Most Significant Bit(MSB) first.
  167. * RETURNS: N/A
  168. */
  169. void ixp425I2CByteTransmit (unsigned char dataByte)
  170.     {
  171.     int bitCnt = 0;
  172.     ixp425GPIOLineConfig(IXP425_I2C_SDA, IXP425_GPIO_OUT);
  173.     ixp425GPIOLineConfig(IXP425_I2C_SCL, IXP425_GPIO_OUT);
  174.     IXP425_I2C_SCL_SET_LOW;
  175.     for (bitCnt = 7; bitCnt >= 0; bitCnt--)
  176.         {
  177.         if (dataByte & BIT(bitCnt))
  178.             {
  179.     IXP425_I2C_SDA_SET_HIGH;
  180.             }
  181.         else
  182.             {
  183.             IXP425_I2C_SDA_SET_LOW;
  184.             }
  185. IXP425_I2C_SCL_SET_HIGH;
  186. IXP425_I2C_SCL_SET_LOW;
  187. }
  188.     }
  189. /******************************************************************************
  190. *
  191. * ixp425I2CByteReceive - Receive a byte on the I2C bus.
  192. *
  193. * RETURNS: N/A
  194. */
  195. void ixp425I2CByteReceive (unsigned char *dataByte)
  196.     {
  197.     IXP425_GPIO_SIG sda = 0;
  198.     unsigned char tmpByte = 0;
  199.     int bitCnt = 0;
  200.     ixp425GPIOLineConfig(IXP425_I2C_SDA, IXP425_GPIO_IN);
  201.     ixp425GPIOLineConfig(IXP425_I2C_SCL, IXP425_GPIO_OUT);
  202.     IXP425_I2C_SCL_SET_LOW;
  203.     for (bitCnt = 7; bitCnt >= 0; bitCnt--)
  204.         {
  205.         IXP425_I2C_SCL_SET_HIGH;
  206.         IXP425_I2C_SDA_GET(&sda);     /* Get the data bit */
  207.         tmpByte |= (sda << bitCnt);
  208.         IXP425_I2C_SCL_SET_LOW;
  209.         }
  210.     ixp425GPIOLineConfig(IXP425_I2C_SDA, IXP425_GPIO_OUT);
  211.     IXP425_I2C_SDA_SET_LOW;
  212.     *dataByte = tmpByte;
  213.     }
  214. /******************************************************************************
  215. *
  216. * ixp425I2CBusFree - determine if the I2C bus is in use or not.
  217. *
  218. * RETURNS: OK if the bus is free, ERROR otherwise.
  219. */
  220. LOCAL STATUS ixp425I2CBusFree ()
  221.     {
  222.     IXP425_GPIO_SIG sda = 0;
  223.     IXP425_GPIO_SIG scl = 0;
  224.     /* 
  225.      * Listen in on the data (SDA), and clock (SCL) lines. If both
  226.      * are high then the bus is free.
  227.      */
  228.     IXP425_I2C_SDA_GET(&sda);
  229.     IXP425_I2C_SCL_GET(&scl);
  230.     if( (sda == IXP425_GPIO_HIGH) && (scl == IXP425_GPIO_HIGH) )
  231. return (OK);
  232.     else
  233. return (ERROR);
  234.     }
  235. /******************************************************************************
  236. *
  237. * ixp425I2CWriteTransfer - This function writes num bytes to a slave device with 
  238. * address devAddr.
  239. *
  240. * RETURNS: the number of bytes actually written; ERROR otherwise
  241. */
  242. int ixp425I2CWriteTransfer (UINT8 devAddr, UINT8 *buffer, UINT32 num, UINT8 offset)
  243.     {
  244.     int byteCnt = 0;
  245.     if (buffer == NULL)
  246. return (ERROR);
  247.     if (ixp425I2CStart() == OK)
  248.         {
  249.         ixp425I2CByteTransmit((devAddr & IXP425_I2C_WRITE_MSK));
  250.         if(ixp425I2CAckReceive() != OK)
  251.     {
  252.     ixp425I2CStop();
  253.     return (ERROR);
  254.     }
  255. ixp425I2CByteTransmit(offset);
  256.         if(ixp425I2CAckReceive() != OK)
  257.     {
  258.     ixp425I2CStop();
  259.     return (ERROR);
  260.     }
  261. for(byteCnt=0; byteCnt<num; byteCnt++)
  262.     {
  263.     ixp425I2CByteTransmit(*buffer);     
  264.     if(ixp425I2CAckReceive() != OK)
  265.         {
  266. ixp425I2CStop();
  267. return (byteCnt);
  268.         }
  269.     buffer++;
  270.     }
  271. ixp425I2CStop();
  272. return (byteCnt);
  273. }
  274.         
  275.     return (ERROR);
  276.     }
  277. /******************************************************************************
  278. *
  279. * ixp425I2CReadTransfer - This function reads num bytes from the device with 
  280. * address devAddr and places it into the area pointed to by buffer.
  281. *
  282. * RETURNS: the number of bytes actually read; ERROR otherwise
  283. */
  284. int ixp425I2CReadTransfer (UINT8 devAddr, UINT8 *buffer, UINT32 num, UINT8 offset)
  285.     {
  286.     int byteCnt = 0;
  287.     int key;
  288.     if (buffer == NULL)
  289. return (ERROR);
  290.     if (ixp425I2CStart() == OK)
  291.         {
  292.         ixp425I2CByteTransmit((devAddr & IXP425_I2C_WRITE_MSK));
  293.         if(ixp425I2CAckReceive() != OK)
  294.     {
  295.     ixp425I2CStop();
  296.     return(ERROR);
  297.     }
  298. ixp425I2CByteTransmit(offset);
  299.         if(ixp425I2CAckReceive() != OK)
  300.    {
  301.    ixp425I2CStop();
  302.    return(ERROR);
  303.    }
  304.         /* Switch to read mode */
  305. key = intLock();
  306. IXP425_I2C_SCL_SET_HIGH;
  307.         IXP425_I2C_SDA_SET_HIGH;
  308. intUnlock(key);
  309.         if(ixp425I2CStart() != OK)
  310.     {
  311.     ixp425I2CStop();
  312.     
  313.     return(ERROR);
  314.     }
  315.         ixp425I2CByteTransmit((devAddr | IXP425_I2C_READ_FLAG));
  316.         if(ixp425I2CAckReceive() != OK)
  317.    {
  318.    ixp425I2CStop();
  319.    return (ERROR);
  320.    }
  321. for(byteCnt=0; byteCnt<num; byteCnt++)
  322.     {
  323.             ixp425I2CByteReceive(buffer);
  324.             buffer++;
  325.     /* Prevent giving an ACK on the last byte */
  326.             if (byteCnt < (num - 1))
  327.                 ixp425I2CAckSend();
  328.     }
  329. ixp425I2CStop();
  330. return (byteCnt);
  331. }
  332.     return (ERROR);
  333.     }