免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2597 | 回复: 0
打印 上一主题 下一主题

自己写的GPIO模拟I2C驱动 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2011-12-20 09:44 |只看该作者 |倒序浏览
这个可以算是我来到新公司写的第一个驱动吧,在之前公司写过spi的驱动,这个跟spi比较类似,只不过只有两跟线,scl(时钟)和sda(数据),写的时候有代码参照,just easy job,调试的时候也只碰到几个小障碍:
1. iic_write的时候漏了一个i2c_start(),造成写入时序不正确,这时可以通过示波器抓波形查出来,波形中在sda改变输入输出方向时会出现一些毛刺,属正常现象,数据改变发生在scl为低的时候。
2.i2c_simu_read_byte的时候数据移位和取bit值的的顺序搞反了,应该是先移位,再取值!道理很简单,第一次移位是无效值,最后那次移位是有效值
3.GPIO pin角属性定义,当时是sfp设备不能scan到,但其他I2C设备正常,里面代码都是一样的,还是叶大师提醒才去看了连到sfp上的pin角属性定义,发现这些pin被定义成非GPIO的了,那当然是不行啦!
下面是正确属性值:
/* I2c BUS */
/*PA0 */ {PORTA,  0, IO_OUT,   0, GPIO,  1},/* SFP0_SCL */
/*PA1 */ {PORTA,  1, IO_OUT,   0, GPIO,  1},/*SFP0_SDA */
/*PA2 */ {PORTA,  2, IO_OUT,   0  , GPIO,  1},/*SFP1_SCL */
/*PA4 */ {PORTA,  4, IO_OUT,   0  , GPIO,  1},/*SFP1_SDA */
/*PA5 */ {PORTA,  5, IO_OUT,   0  , GPIO,  1},/*CPU_SCL */
/*PA6 */ {PORTA,  6, IO_OUT,   0  , GPIO,  1},/*CPU_SDA */
 
一。先上王道
二.GPIO pin 定义

PA0

 

GPI

F0_SCL

PA1

 

GPI

F0_SDA

PA2

 

GPI

F1_SCL

PA4

 

GPI

F1_SDA

PA5

 

GPI

GPIO CPU_SCK

PA6

 

GPI

GPIO CPU_SDA

 
 
 
 
 
 
 
 
三源代码
1,i2cbussimu.c
  1. /**********************************************************************************
  2. Module:
  3.     i2cbussimu.c

  4. History:
  5.     xu xinlin created in 2011.3.7

  6. Description:
  7.     This file define the interface to operate I2C, simulated by GPIO.
  8. ***********************************************************************************/

  9. #include <vxWorks.h>
  10. #include <string.h>
  11. #include "immap_83xx.h"
  12. #include "rdb8323.h"
  13. #include "gpio.h"
  14. #include "i2cbussimu.h"
  15. #include "i2cDevices.h"

  16. extern void sysUsDelay(int delay);
  17. #define i2c_debug 0
  18. #define i2c_printf(fmt,arg...) {if(i2c_debug)printf(fmt,##arg);}
  19. #define I2CBUS_FREN (85937) /* Hz */
  20. #define I2CBUS_CYCLE ((1000000+I2CBUS_FREN)/I2CBUS_FREN) /* In Us */
  21. #define BYTE_TRANSFER_TIME (I2CBUS_CYCLE*15) /* I2CBUS_CYCLE * 9 */
  22. #define BYTE_TRANSFER_TIME2 (I2CBUS_CYCLE*50) /* I2CBUS_CYCLE * 9 */

  23. #define I2CDELAY     sysUsDelay(I2CBUS_CYCLE/4)

  24. const UINT8 aI2cDevAddr[] =
  25. {
  26.                          /* i2c line 0 */
  27.     /*I2C_MB_EEPROM */ 0xAE, /* 0 device number for eeprom in main board */
  28.     /*I2C_PM_SENSOR */ 0x30, /* 1 Thermal Sensor for Power module */
  29.     /*I2C_CPU_SENSOR */ 0x98, /* 2 Thermal Sensor for CPU */
  30.     /*I2C_AD */ 0x90, /* 3 A/D ADS7830IPWR */
  31.     /*I2C_ZL30142 */ 0xCE, /* 4 ZL30142 */
  32.     
  33.                        /* i2c line 1 */
  34.     /*I2C_SFP0_EL */ 0xA0, /* 5 SFP0 electric port*/
  35.     /*I2C_SFP0_FB */ 0xA2, /* 6 SFP0 fiber port */
  36.     
  37.                         /* i2c line 2 */
  38.     /*I2C_SFP1_EL */ 0xA0, /* 7 SFP1 electric port */
  39.     /*I2C_SFP1_FB */ 0xA2, /* 8 SFP1 fiber port */
  40. };


  41. /* Proto definition */
  42. LOCAL void      SDA_OUTPUT_ACTIVE(struct i2c_simu_dev i2c_dev);
  43. LOCAL void SDA_OUTPUT_ACTIVE(struct i2c_simu_dev i2c_dev);
  44. LOCAL void SDA_INPUT_ACTIVE(struct i2c_simu_dev i2c_dev);
  45. LOCAL void SCL_OUTPUT_ACTIVE(struct i2c_simu_dev i2c_dev);
  46. LOCAL void SCL_INPUT_ACTIVE(struct i2c_simu_dev i2c_dev);
  47. LOCAL void SCL_WRITE(struct i2c_simu_dev i2c_dev, UINT8 bitval);
  48. LOCAL STATUS SCL_READ(struct i2c_simu_dev i2c_dev);
  49. LOCAL void SDA_WRITE(struct i2c_simu_dev i2c_dev, UINT8 bitval);
  50. LOCAL STATUS SDA_READ(struct i2c_simu_dev i2c_dev);
  51. LOCAL STATUS i2c_start(struct i2c_simu_dev i2c_dev);
  52. LOCAL void i2c_stop(struct i2c_simu_dev i2c_dev);
  53. LOCAL STATUS receive_i2c_ack(struct i2c_simu_dev i2c_dev);
  54. LOCAL STATUS send_i2c_ack(struct i2c_simu_dev i2c_dev);
  55. LOCAL STATUS send_i2c_nack(struct i2c_simu_dev i2c_dev);
  56. LOCAL STATUS i2c_simu_read_byte (struct i2c_simu_dev i2c_dev, UINT8 *data,UINT32 length);
  57. LOCAL STATUS i2c_simu_write_byte (struct i2c_simu_dev i2c_dev, UINT8 writeData);
  58. LOCAL STATUS i2c_stat_check(struct i2c_simu_dev i2c_dev);

  59. LOCAL void SDA_OUTPUT_ACTIVE(struct i2c_simu_dev i2c_dev)
  60. {
  61.     volatile immap_t * immr =(immap_t *)CCSBAR;
  62.     immr->qepio.ioport[i2c_dev.port].dir1 &= ~(0x80000000 >> (i2c_dev.sda<<1));
  63.     immr->qepio.ioport[i2c_dev.port].dir1 |= (0x80000000 >> ((i2c_dev.sda<<1) + 1));
  64.     
  65. }

  66. LOCAL void SDA_INPUT_ACTIVE(struct i2c_simu_dev i2c_dev)
  67. {
  68.     volatile immap_t * immr =(immap_t *)CCSBAR;
  69.     immr->qepio.ioport[i2c_dev.port].dir1 &= ~(0x80000000 >> ((i2c_dev.sda<<1) + 1));
  70.     immr->qepio.ioport[i2c_dev.port].dir1 |= (0x80000000 >> (i2c_dev.sda<<1));
  71. }

  72. LOCAL void SCL_OUTPUT_ACTIVE(struct i2c_simu_dev i2c_dev)
  73. {
  74.     volatile immap_t * immr =(immap_t *)CCSBAR;
  75.     immr->qepio.ioport[i2c_dev.port].dir1 &= ~(0x80000000 >> (i2c_dev.scl<<1));
  76.     immr->qepio.ioport[i2c_dev.port].dir1 |= (0x80000000 >> ((i2c_dev.scl<<1) + 1));
  77. }

  78. LOCAL void SCL_INPUT_ACTIVE(struct i2c_simu_dev i2c_dev)
  79. {
  80.     volatile immap_t * immr =(immap_t *)CCSBAR;
  81.     immr->qepio.ioport[i2c_dev.port].dir1 &= ~(0x80000000 >> ((i2c_dev.scl<<1) + 1));
  82.     immr->qepio.ioport[i2c_dev.port].dir1 |= (0x80000000 >> (i2c_dev.scl<<1));
  83. }


  84. LOCAL void SCL_WRITE(struct i2c_simu_dev i2c_dev, UINT8 bitval)
  85. {    
  86.     volatile immap_t * immr =(immap_t *)CCSBAR;
  87.     if(bitval)
  88.         immr->qepio.ioport[i2c_dev.port].pdat |= 0x80000000 >> i2c_dev.scl;
  89.     else
  90.         immr->qepio.ioport[i2c_dev.port].pdat &= ~(0x80000000>> i2c_dev.scl);
  91. }

  92. LOCAL STATUS SCL_READ(struct i2c_simu_dev i2c_dev)
  93. {    
  94.     volatile immap_t * immr =(immap_t *)CCSBAR;
  95.     return (((immr->qepio.ioport[i2c_dev.port].pdat) & (0x80000000 >> i2c_dev.scl)) != 0);
  96. }

  97. LOCAL void SDA_WRITE(struct i2c_simu_dev i2c_dev, UINT8 bitval)
  98. {    
  99.     volatile immap_t * immr =(immap_t *)CCSBAR;
  100.     if(bitval)
  101.         immr->qepio.ioport[i2c_dev.port].pdat |= 0x80000000 >> i2c_dev.sda;
  102.     else
  103.         immr->qepio.ioport[i2c_dev.port].pdat &= ~(0x80000000>> i2c_dev.sda);
  104. }


  105. LOCAL STATUS SDA_READ(struct i2c_simu_dev i2c_dev)
  106. {    
  107.     volatile immap_t * immr =(immap_t *)CCSBAR;
  108.     return (((immr->qepio.ioport[i2c_dev.port].pdat) & (0x80000000 >> i2c_dev.sda)) != 0);
  109.         
  110. }


  111. /* -------------------------------------------------------------------------*
  112.  * Function : i2cDrvInit *
  113.  * Description: i2c device initial, configure i2c port/pin *
  114.  * Parameters : i2c device structure & device number *
  115.  * Return : OK if i2c start successfully,or I2C_ERROR_UNKNOW_DEVICE *
  116.  * -------------------------------------------------------------------------*/
  117. STATUS i2cDrvInit(UINT8 devNum,struct i2c_simu_dev *i2c_dev)
  118. {
  119.     /*****************************************************
  120.     PA0--->F0_SCL
  121.     PA1--->F0_SDA :SFP0
  122.     
  123.     PA2--->F1_SCL
  124.     PA4--->F1_SDA :SFP1    

  125.     PA5--->CPU_SCL
  126.     PA6--->CPU_SDA :I2C_MB_EEPROM,I2C_PM_SENSOR,I2C_CPU_SENSOR,I2C_AD,I2C_ZL30142
  127.     ******************************************************/
  128.     if ((devNum <= I2C_ZL30142) && (devNum >= I2C_MB_EEPROM))
  129.     {
  130.         i2c_dev->port = 0;
  131.         i2c_dev->scl = 5;
  132.         i2c_dev->sda = 6;
  133.     }
  134.     else if ((devNum <= I2C_SFP0_FB) && (devNum >= I2C_SFP0_EL))
  135.     {
  136.         i2c_dev->port = 0;
  137.         i2c_dev->scl = 0;
  138.         i2c_dev->sda = 1;
  139.     }
  140.     else if ((devNum <= I2C_SFP1_FB) && (devNum >= I2C_SFP1_EL))
  141.     {
  142.         i2c_dev->port = 0;
  143.         i2c_dev->scl = 2;
  144.         i2c_dev->sda = 4;        
  145.     }
  146.     else
  147.     {
  148.         return I2C_ERROR_UNKNOW_DEVICE;
  149.     }
  150.     /* Get the device address */
  151.     i2c_dev->i2cDevAddr = aI2cDevAddr[devNum];
  152.     /* set sda&scl output mode */
  153.     SCL_OUTPUT_ACTIVE(*i2c_dev);
  154.     SDA_OUTPUT_ACTIVE(*i2c_dev);
  155.     /* pull sda&scl high */
  156.     SDA_WRITE(*i2c_dev, 1);
  157.     SCL_WRITE(*i2c_dev, 1);        
  158.     return OK;    
  159. }


  160. /* -------------------------------------------------------------------------*
  161.  * Function : i2c_stat_check *
  162.  * Description: restore I2C bus from dead lock by sending 9 clocks pusle *
  163.  * Parameters : i2c device structure *
  164.  * Return : OK if i2c start successfully,or I2C_ERROR_TIME_OUT *
  165.  * -------------------------------------------------------------------------*/
  166. LOCAL STATUS i2c_stat_check(struct i2c_simu_dev i2c_dev)
  167. {
  168.     UINT32 j = 0;             /* counter */
  169.     
  170.     /* check scl&sda status,if it's low ,send 9 clocks pusle to restore it */
  171.     if((!SDA_READ(i2c_dev)) || (!SCL_READ(i2c_dev)))
  172.     {
  173.         SDA_INPUT_ACTIVE (i2c_dev);
  174.         for (j=0; j<9; j++)
  175.         {
  176.             SCL_WRITE(i2c_dev, 0); /* pull SCL low */
  177.             I2CDELAY;
  178.             I2CDELAY;
  179.             SCL_WRITE(i2c_dev, 1); /* pull SCL high */
  180.             I2CDELAY;
  181.             I2CDELAY;
  182.         }    
  183.         i2c_stop(i2c_dev);
  184.         SDA_INPUT_ACTIVE (i2c_dev);        
  185.     }
  186.     return OK;
  187. }



  188. /* -------------------------------------------------------------------------*
  189.  * Function : i2c_start *
  190.  * Description: SDA change from high to low when SCL keep in high. *
  191.  * Parameters : i2c device structure *
  192.  * Return : OK if i2c start successfully,or I2C_ERROR_TIME_OUT *
  193.  * -------------------------------------------------------------------------*/
  194. LOCAL STATUS i2c_start(struct i2c_simu_dev i2c_dev)
  195. {
  196.     I2CDELAY;
  197.     SDA_WRITE (i2c_dev, 1); /* pull SDA high */
  198.     SDA_OUTPUT_ACTIVE(i2c_dev); /* driver GPIO direction:output */
  199.     I2CDELAY;
  200.     SCL_WRITE(i2c_dev, 1); /* pull SCL high */
  201.     I2CDELAY;        
  202.     SDA_WRITE (i2c_dev, 0); /* pull SDA low */
  203.     I2CDELAY;        
  204.     return OK;
  205. }


  206. /* -------------------------------------------------------------------------*
  207.  * Function : i2c_stop *
  208.  * Description: SDA change from low to high when SCL keep in high. *
  209.  * Parameters : i2c device structure *
  210.  * Return : NULL                                                 *
  211.  * -------------------------------------------------------------------------*/
  212. void i2c_stop(struct i2c_simu_dev i2c_dev)
  213. {
  214.     SCL_WRITE(i2c_dev, 0); /* pull SCL low */
  215.     I2CDELAY;
  216.     SDA_WRITE (i2c_dev, 0); /* pull SDA low */
  217.     SDA_OUTPUT_ACTIVE(i2c_dev); /* driver GPIO direction:output */
  218.     I2CDELAY;
  219.     SCL_WRITE (i2c_dev, 1); /* pull SCL high */
  220.     I2CDELAY;
  221.     SDA_WRITE (i2c_dev, 1); /* pull SDA high */
  222.     I2CDELAY;
  223.     SDA_INPUT_ACTIVE(i2c_dev); /* driver GPIO direction:input */    
  224. }


  225. /* -------------------------------------------------------------------------*
  226.  * Function : receive_i2c_ack *
  227.  * Description: During SCL high, when SDA holds low is ACK otherwise NACK. *
  228.  * Parameters : i2c device structure *
  229.  * Return : OK is ACK, or is NACK. *
  230.  * Notes : This function gets the ACK signal from the slave. *
  231.  * -------------------------------------------------------------------------*/
  232. LOCAL STATUS receive_i2c_ack(struct i2c_simu_dev i2c_dev)
  233. {
  234.     INT32 isAck = 0;    
  235.     SCL_WRITE (i2c_dev, 0); /* pull SCL low */
  236.     I2CDELAY;
  237.     SDA_WRITE (i2c_dev, 1);                  /* pull SDA high */
  238.     SDA_INPUT_ACTIVE(i2c_dev); /* driver GPIO direction:input */
  239.     I2CDELAY;
  240.     SCL_WRITE (i2c_dev, 1);                          /* pull SCL high */
  241.     I2CDELAY;
  242.     I2CDELAY;
  243.     if(SDA_READ(i2c_dev))
  244.     {
  245.         isAck = I2C_ERROR_CYCLE_ACKIN;
  246.     }
  247.     else
  248.     {
  249.         isAck = OK;
  250.     }
  251.     SCL_WRITE (i2c_dev, 0);
  252.     I2CDELAY;
  253.     SDA_OUTPUT_ACTIVE(i2c_dev); /* driver GPIO direction:output */
  254.     return isAck;
  255. }

  256. /* -------------------------------------------------------------------------*
  257.  * Function : send_i2c_ack *
  258.  * Description: During SCL high, when SDA holds low is ACK otherwise NACK. *
  259.  * Parameters : i2c device structure         *
  260.  * Return : OK if success,or I2C_ERROR_ACK *
  261.  * Notes : This function send ACK to slave device         *
  262.  * -------------------------------------------------------------------------*/
  263. LOCAL STATUS send_i2c_ack(struct i2c_simu_dev i2c_dev)
  264. {
  265.     SCL_WRITE (i2c_dev, 0); /* pull SCL low */
  266.     I2CDELAY;
  267.     SDA_OUTPUT_ACTIVE(i2c_dev); /* driver GPIO direction:output */    
  268.     SDA_WRITE (i2c_dev, 0); /* pull SDA low */
  269.     I2CDELAY;    
  270.     SCL_WRITE (i2c_dev, 1); /* pull SCL high */
  271.     I2CDELAY;
  272.     I2CDELAY;
  273.     SCL_WRITE (i2c_dev, 0); /* pull SCL low */
  274.     I2CDELAY;    
  275.     return OK;
  276. }

  277. /* -------------------------------------------------------------------------*
  278.  * Function : send_i2c_nack *
  279.  * Description: During SCL high, when SDA holds low is ACK otherwise NACK. *
  280.  * Parameters : i2c device structure         *
  281.  * Return : OK if success,or I2C_ERROR_NACK *
  282.  * Notes : This function send NACK to slave device         *
  283.  * -------------------------------------------------------------------------*/
  284. LOCAL STATUS send_i2c_nack(struct i2c_simu_dev i2c_dev)
  285. {
  286.     SCL_WRITE (i2c_dev, 0); /* pull SCL low */
  287.     I2CDELAY;
  288.     SDA_OUTPUT_ACTIVE(i2c_dev);/* driver GPIO direction:output */    
  289.     SDA_WRITE (i2c_dev, 1); /* pull SDA high */
  290.     I2CDELAY;    
  291.     SCL_WRITE (i2c_dev, 1); /* pull SCL high */
  292.     I2CDELAY;
  293.     I2CDELAY;
  294.     SCL_WRITE (i2c_dev, 0); /* pull SCL low */
  295.     I2CDELAY;    
  296.     return OK;
  297. }

  298. /*-------------------------------------------------------------------*
  299. * Probe to see if a chip is present. Also good for checking for the *
  300. * completion of EEPROM writes since the chip stops responding until *
  301. * the write completes (typically 10mSec).                              *
  302. * -------------------------------------------------------------------*/
  303. STATUS i2c_probe (struct i2c_simu_dev i2c_dev)
  304. {
  305.     INT32 iRc = 0;    
  306.     
  307.     if (i2c_stat_check(i2c_dev) != OK)
  308.     {
  309.         return I2C_ERROR_KNOWN_STATE;
  310.     }
  311.     if (i2c_start(i2c_dev) != OK)
  312.     {
  313.         (void)i2c_stop(i2c_dev);
  314.         return I2C_ERROR_CYCLE_START;
  315.     }    
  316.     iRc = (i2c_simu_write_byte(i2c_dev, (i2c_dev.i2cDevAddr)) != OK) ? I2C_ERROR_CYCLE_WRITE:OK;        
  317.     (void)i2c_stop(i2c_dev);
  318.     return (iRc);
  319. }


  320. /* -------------------------------------------------------------------------*
  321.  * Function : i2c_simu_read_byte *
  322.  * Description: Get the Data from slave device *
  323.  * Parameters : i2c device structure,data buffer for loading data *
  324.  * Return : OK if read byte successfully,or failure *
  325.  * -------------------------------------------------------------------------*/
  326. LOCAL STATUS i2c_simu_read_byte (struct i2c_simu_dev i2c_dev, UINT8 *data,UINT32 length)
  327. {
  328.     UINT8 i = 0,j = 0,input_byte = 0;            /* counter */
  329.         
  330.     /* set GPIO pin direction:input */
  331.     I2CDELAY;
  332.     
  333.     /* receive bytes of data */
  334.     for (i = 0; i < length; i++)
  335.     {
  336.         SDA_INPUT_ACTIVE(i2c_dev);
  337.         input_byte = 0x00;
  338.         /*SCL(i2c_dev, 1);*/
  339.         for (j = 0; j < 8; j++)
  340.         {
  341.             SCL_WRITE(i2c_dev, 0);
  342.             I2CDELAY;
  343.             I2CDELAY;
  344.             SCL_WRITE (i2c_dev, 1);
  345.             I2CDELAY;
  346.             input_byte <<= 1;
  347.             if (SDA_READ(i2c_dev))
  348.             {
  349.                 input_byte++;
  350.             }             
  351.             I2CDELAY;                        
  352.             
  353.         }
  354.         data[i] = input_byte;
  355.         if (i == length - 1)
  356.         {
  357.             break;
  358.         }
  359.         if (send_i2c_ack(i2c_dev)) /* always return OK */
  360.         {
  361.             i2c_stop(i2c_dev);
  362.             return I2C_ERROR_CYCLE_ACKOUT;
  363.         }        
  364.     }    
  365.     return OK;
  366. }


  367. /* -------------------------------------------------------------------------*
  368.  * Function : i2c_simu_write_byte *
  369.  * Description: Send the byte output of gpio, MSB first. *
  370.  * Parameters : i2c device structure,data to be shifted. *
  371.  * Return : OK if write byte successfully,or failure *
  372.  * -------------------------------------------------------------------------*/
  373. LOCAL STATUS i2c_simu_write_byte (struct i2c_simu_dev i2c_dev, UINT8 writeData)
  374. {
  375.     UINT8 j = 0; /* counter */
  376.     
  377.     /* set GPIO pin direction:output */
  378.     SDA_OUTPUT_ACTIVE(i2c_dev);

  379.     for (j = 0; j < 8; j++)
  380.     {
  381.         SCL_WRITE (i2c_dev, 0);
  382.         I2CDELAY;    
  383.         if ((writeData & 0x80) == 0)
  384.         {
  385.             SDA_WRITE (i2c_dev, 0);
  386.         }
  387.         else
  388.         {
  389.             SDA_WRITE (i2c_dev, 1);
  390.         }
  391.         I2CDELAY;
  392.         
  393.         SCL_WRITE (i2c_dev, 1);            
  394.         I2CDELAY;
  395.         I2CDELAY;        
  396.         writeData <<= 1;
  397.     }
  398.     if (receive_i2c_ack(i2c_dev))
  399.     {
  400.         i2c_stop(i2c_dev);
  401.         return I2C_ERROR_CYCLE_ACKIN;
  402.     }
  403.     return OK;
  404. }

  405. void i2cSearch()
  406. {
  407.     UINT32 i = 0, j = 0, iRc = 0;
  408.     struct i2c_simu_dev i2c_dev;
  409.         
  410.     for(i=4; i<11;i++)
  411.     {
  412.         /* i2c device initial */
  413.         if (i2cDrvInit(i,&i2c_dev) != OK)
  414.         {
  415.      printf("\n[i2c]init failed");
  416.             continue;
  417.         }
  418.         /*
  419.         printf("\ndebug_device=%x",aI2cDevAddr[i]);
  420.         if(!i2c_probe(i2c_dev))
  421.         {
  422.             printf("\ndevice=%x",aI2cDevAddr[i]);
  423.         }
  424.         */
  425.         for(j = 0; j < 128; j++)
  426.         {
  427.             if (i2c_stat_check(i2c_dev) != OK)
  428.             {
  429.                 return I2C_ERROR_KNOWN_STATE;
  430.             }
  431.             if (i2c_start(i2c_dev) != OK)
  432.             {
  433.                 (void)i2c_stop(i2c_dev);
  434.                 return I2C_ERROR_CYCLE_START;
  435.             }            
  436.             iRc = (i2c_simu_write_byte(i2c_dev, j<<1) != OK) ? I2C_ERROR_CYCLE_WRITE:OK;
  437.             (void)i2c_stop(i2c_dev);
  438.             if (OK == iRc)
  439.             {
  440.                 printf("\ndevice=%x", j<<1);
  441.             }
  442.         }
  443.     }
  444. }

  445. /* -------------------------------------------------------------------------*
  446.  * Function : iic_read             *
  447.  * Description: Read slave datas from gpio, MSB first     *
  448.  * Parameters : i2c device structure,slave address,data buffer to be loaded.*
  449.  * Return : the amount of reading bytes ,or failure *
  450.  * -------------------------------------------------------------------------*/
  451. STATUS iic_read(struct i2c_simu_dev i2c_dev, UINT32 addr, UINT32 alen, UINT8 *buffer, UINT32 len)
  452. {
  453.     INT32 shift,iRc;
  454.     i2c_printf("iic_read: chip %02X addr %02X alen %d buffer %p len %d\n",
  455.              i2c_dev.i2cDevAddr, addr, alen, buffer, len);    
  456.     /*
  457.      * Do the addressing portion of a write cycle to set the
  458.      * chip's address pointer. If the address length is zero,
  459.      * don't do the normal write cycle to set the address pointer,
  460.      * there is no address pointer in this chip.
  461.      */    
  462.     if (i2c_stat_check(i2c_dev) != OK)
  463.     {
  464.         return I2C_ERROR_KNOWN_STATE;
  465.     }

  466.     /* Send the chip address for a read cycle. */
  467.     if(alen > 0)
  468.     {    
  469.         if (i2c_start(i2c_dev) != OK)
  470.         {
  471.             (void)i2c_stop(i2c_dev);
  472.             return I2C_ERROR_CYCLE_START;
  473.         }
  474.         /* write slave address */
  475.         if(i2c_simu_write_byte(i2c_dev, i2c_dev.i2cDevAddr))
  476.         {    /* write cycle */    
  477.             (void)i2c_stop(i2c_dev);
  478.             i2c_printf("iic_read, no chip responded %02X\n", i2c_dev.i2cDevAddr);
  479.             return I2C_ERROR_CYCLE_WRITE;
  480.         }
  481.         
  482.         shift = (alen-1) * 8;
  483.         while(alen-- > 0)
  484.         {
  485.             if(i2c_simu_write_byte(i2c_dev, (addr >> shift)))
  486.             {    
  487.                 (void)i2c_stop(i2c_dev);
  488.                 i2c_printf("iic_read, address not <ACK>ed\n");
  489.                 return I2C_ERROR_CYCLE_WRITE;
  490.             }
  491.             shift -= 8;
  492.         }
  493.         i2c_stop(i2c_dev);    /* reportedly some chips need a full stop */        
  494.     }

  495.     /*
  496.      * Send the chip address again, this time for a read cycle.
  497.      * Then read the data. On the last byte, we do a NACK instead
  498.      * of an ACK(len == 0) to terminate the read.
  499.      */    
  500.     if (i2c_start(i2c_dev) != OK)
  501.     {
  502.         (void)i2c_stop(i2c_dev);
  503.         return I2C_ERROR_CYCLE_START;
  504.     }
  505.         
  506.     if(i2c_simu_write_byte(i2c_dev, ((i2c_dev.i2cDevAddr) | 1)))
  507.     {    
  508.         (void)i2c_stop(i2c_dev);            
  509.         return I2C_ERROR_CYCLE_WRITE;
  510.     }        
  511.     
  512.     iRc = (i2c_simu_read_byte(i2c_dev, buffer,len) == len) ? OK : ERROR;

  513.     (void)i2c_stop(i2c_dev);

  514.     return iRc;
  515.     
  516. }

  517. /*-----------------------------------------------------------------------
  518.  * Write bytes
  519.  */
  520. /* -------------------------------------------------------------------------*
  521.  * Function : iic_write             *
  522.  * Description: Send the bytes out to gpio, MSB first. *
  523.  * Parameters : i2c device structure,slave address,data to be shifted. *
  524.  * Return : OK if write bytes successfully,or failure times *
  525.  * -------------------------------------------------------------------------*/
  526. STATUS iic_write(struct i2c_simu_dev i2c_dev, UINT32 addr, UINT32 alen, UINT8 *buffer, UINT32 len)
  527. {
  528.     INT32 shift,failures = 0;
  529.     i2c_printf("iic_write: chip %02X addr %02X alen %d buffer %p len %d\n",
  530.              i2c_dev.i2cDevAddr, addr, alen, buffer, len);
  531.     if (i2c_stat_check(i2c_dev) != OK)
  532.     {
  533.         return I2C_ERROR_KNOWN_STATE;
  534.     }

  535.     if (i2c_start(i2c_dev) != OK)
  536.     {
  537.         (void)i2c_stop(i2c_dev);
  538.         return I2C_ERROR_CYCLE_START;
  539.     }

  540.     
  541.     if (i2c_simu_write_byte(i2c_dev, i2c_dev.i2cDevAddr) != OK)
  542.     {
  543.         (void)i2c_stop(i2c_dev);
  544.         i2c_printf("iic_write, no chip responded %02X\n", i2c_dev.i2cDevAddr);    
  545.         return I2C_ERROR_CYCLE_START;
  546.     }
  547.             
  548.     shift = (alen-1) * 8;
  549.     while(alen-- > 0)
  550.     {
  551.         if(i2c_simu_write_byte(i2c_dev, (addr >> shift)))
  552.         {
  553.             (void)i2c_stop(i2c_dev);
  554.             i2c_printf("iic_write, address not <ACK>ed\n");
  555.             return I2C_ERROR_CYCLE_WRITE;
  556.         }
  557.         shift -= 8;
  558.     }

  559.     while(len-- > 0)
  560.     {
  561.         if(i2c_simu_write_byte(i2c_dev, *buffer++))
  562.         {
  563.             failures--;/* negative value */
  564.         }
  565.     }
  566.     i2c_stop(i2c_dev);
  567.     return(failures);
  568. }
2.i2cDevices.c
 
  1. #include <vxWorks.h>
  2. #include <stdio.h>
  3. #include <semLib.h>
  4. #include "i2cbussimu.h"
  5. #include "i2cDevices.h"
  6. #include "bsp.h"

  7. #define AT24C02_BUF_LEN 0x8
  8. #define MIN(a,b) ((a) < (b) ? (a) : (b))

  9. #define i2c_debug 0

  10. #define i2c_printf(fmt,arg...) {if(i2c_debug)printf(fmt,##arg);}

  11. extern SEM_ID i2cMutex;
  12. extern void sysUsDelay(int delay);

  13. LOCAL int at24c02_read(struct i2c_simu_dev i2c_dev,void *dst, UINT32 src,int cnt)
  14. {
  15.     if(((int)src+cnt>0x100) || (cnt<0)||(dst == 0))
  16.     {
  17.         return ERROR;
  18.     }

  19.     if(iic_read(i2c_dev,src,1,(UINT8 *)dst,cnt)!=OK)
  20.     {
  21.         return ERROR;
  22.     }

  23.     return cnt;
  24. }

  25. LOCAL int progDone(INT32 i2c_dev_addr, INT32 dummy)
  26. {
  27.     return (!i2c_probe(*((struct i2c_simu_dev *)i2c_dev_addr)));
  28. }

  29. LOCAL int at24c02_write(struct i2c_simu_dev i2c_dev, UINT32 offset,void *buffer,int byteCnt)
  30. {
  31.     UINT32 dst,src,cnt;
  32.     int iRc;
  33.     dst = offset;
  34.     src = (UINT32)buffer;
  35.     iRc = byteCnt;

  36.     do{
  37.         cnt = MIN(AT24C02_BUF_LEN-((UINT32)dst & (AT24C02_BUF_LEN-1)),byteCnt);

  38.         if((OK != iic_write(i2c_dev,dst,1,(UINT8 *)src,cnt)) ||
  39.            (OK != sysUsDelayPoll(20000, progDone,(INT32)&i2c_dev,0))) /* Self-timed Write Cycle (12 ms Max) */
  40.         {
  41.             return ERROR;
  42.         }

  43.         dst += cnt;
  44.         src += cnt;
  45.         byteCnt -= cnt;
  46.     }while(byteCnt>0);

  47.     return iRc;
  48. }

  49. /*
  50. @devNum: device number for FPH800H from 0 to 11
  51. @cmd: IIC_READ or IIC_WEITW
  52. @offset:I2C device register address
  53. @buffer :buffer address provided by user
  54. @bufLen: the length of buffer
  55. */
  56. UINT32 i2c_dev_access (UINT32 devNum,UINT32 cmd, UINT32 offset, void *buffer, UINT32 bufLen)
  57. {

  58.     UINT8 i2cDevAddr;

  59.     int alen,iRc=0;

  60.     if(devNum < I2C_MB_EEPROM || devNum > I2C_SFP1_FB || !(cmd == I2C_READ || cmd == I2C_WRITE) || !buffer )
  61.     {
  62.         return ERROR;
  63.     }
  64.     
  65.     i2c_printf("\n[i2c]begin,DevNum=%d,cmd=%d,offset=%d,buffer=0x%x,bufLen=%d",
  66.                                    devNum, cmd, offset,(int)buffer, bufLen);

  67.     if(i2cMutex)
  68.     {
  69.         semTake (i2cMutex,WAIT_FOREVER);
  70.     }

  71.     struct i2c_simu_dev i2c_dev;
  72.     
  73.     /* i2c device initial */
  74.     if (i2cDrvInit(devNum,&i2c_dev) != OK)
  75.     {
  76.         i2c_printf("\n[i2c]init failed");
  77.         goto IIC_END;        
  78.     }

  79.     /* Get the register address length */
  80.     alen = 1; /* currently, It seems that the length of address is 1 byte */

  81.     if (cmd == I2C_READ)
  82.     {
  83.         if(devNum == I2C_MB_EEPROM)
  84.         {
  85.             iRc = at24c02_read(i2c_dev,(void *)buffer,offset,bufLen); /* error or count */
  86.         }
  87.         else
  88.         {
  89.             iRc = iic_read(i2c_dev,offset,alen,buffer,bufLen); /* OK or error */
  90.         }
  91.     }
  92.     else /* cmd == IIC_WRITE */
  93.     {
  94.         if(devNum == I2C_MB_EEPROM)
  95.         {
  96.             iRc = at24c02_write(i2c_dev,offset,(void *)buffer,bufLen); /* error or count */
  97.         }
  98.         else
  99.         {
  100.             iRc = iic_write(i2c_dev,offset,alen,buffer,bufLen);/*OK or negative count */
  101.         }
  102.     }

  103. IIC_END:
  104.     if(i2cMutex)
  105.     {
  106.         semGive (i2cMutex);
  107.     }

  108.     i2c_printf("\n[i2c]end, iRc=0x%X",iRc);
  109.   
  110.     return iRc;
  111. }
 
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP