sysI2CDrv.c
上传用户:yingyi0918
上传日期:2022-06-26
资源大小:214k
文件大小:25k
源码类别:

VxWorks

开发平台:

C/C++

  1. /* sysI2CDrv.c - I2C driver */
  2.  
  3. /* Copyright 1984-2002 Wind River Systems, Inc. */
  4. #include "copyright_wrs.h"
  5. /*
  6.  * This file has been developed or significantly modified by the
  7.  * MIPS Center of Excellence Dedicated Engineering Staff.
  8.  * This notice is as per the MIPS Center of Excellence Master Partner
  9.  * Agreement, do not remove this notice without checking first with
  10.  * WR/Platforms MIPS Center of Excellence engineering management.
  11.  */
  12. /*
  13. modification history
  14. --------------------
  15. 01c,18sep02,slk  Cleanup for refgen use on file
  16. 01b,25jun02,d_c  Further cleanup
  17. 01a,19Jun02,d_c  Code from IDT modified to approach C of E standards.
  18. */
  19. /*
  20. DESCRIPTION
  21. This module contains the functions to access the 24AA64 EEPROM via the I2C
  22. interface on the IDT79EB355, and IDT79RP355 boards.
  23. INCLUDE FILES : sysI2CDrv.h
  24. */
  25. /* includes */
  26. #include "sysI2CDrv.h"
  27. /* defines */
  28. #undef I2C_DEBUG /* Enable debug routines if defined */
  29. /*
  30.  * uSecs to wait for I2C done condition.
  31.  *
  32.  * NOTE: If you change this value, you must also change function
  33.  * documentation for sysI2CInit and sysI2CAckPollOnWrite.
  34.  */
  35. #define I2C_DONE_TIMEOUT        3000000
  36. /* Number of bits required to address a page - used to allign
  37.  * data on page boundaries.
  38.  */
  39. #define I2C_EEPROM_PAGE_BITS    (I2C_EEPROM_PAGE_SIZE - 1)
  40. /* typedefs */
  41. /* globals */
  42. /* locals */
  43. /* forward declaration */
  44. /******************************************************************************
  45. *
  46. * sysI2CInit - initialize the I2C interface.
  47. *
  48. * This routine initializes I2C interface & GPIO pins.
  49. *
  50. * RETURNS: N/A
  51. */
  52. void sysI2CInit (void)
  53.     {
  54.     
  55.  
  56.     /* Enable Master interface */
  57.     
  58.     I2C.i2cc = I2CC_MEN; 
  59.     I2C.i2ccp = I2C_CPP;
  60.     /* Mask off the I2C interrupts : Master/ Slave      */
  61.     
  62.     I2C.i2cmsm = I2C_MASTER_INT_MASK;
  63.     I2C.i2cssm = I2C_SLAVE_INT_MASK;
  64.     sysWbFlush ();
  65.     }
  66.  
  67. /*****************************************************************************
  68. *
  69. * sysI2CChkDone - check if the I2C device has done condition 
  70. *
  71. * This function polls the I2C command status register to check if the DONE
  72. * bit is set.
  73. *
  74. * RETURNS: OK if acknowledged within 500 milliseconds, ERROR otherwise
  75. */
  76. STATUS sysI2CChkDone (void)
  77.     {
  78.     unsigned int devStatus = 0;         /* device status */
  79.     UINT32       startCount;            /* Starting count for timeout */
  80.     /* Wait for Acknowledge from the Device */
  81.     startCount = sysUSecTimoutStart ();
  82.     while (!sysUSecTimoutExpired (startCount, I2C_DONE_TIMEOUT))
  83.         {
  84.         devStatus = I2C.i2cms;
  85.         /* Check DONE status - return OK if done */
  86.     
  87. if ((devStatus & I2CMS_MASK) == I2CMS_D)
  88.     return (OK);
  89. }
  90.     /* Timeout expired */
  91.     return ERROR;
  92.     }
  93. /*****************************************************************************
  94. *
  95. * sysI2CStart - issue a start command to the I2C slave device
  96. *
  97. * This routine Issues a start command to the I2C slave device. It
  98. * is used to initiate reads and writes to an I2C device.
  99. *
  100. * RETURNS: OK on success, ERROR otherwise
  101. */
  102. STATUS sysI2CStart (void)
  103.     {
  104.     I2C.i2cmcmd = I2CMCMD_CMD (START);
  105.     sysWbFlush ();
  106.     return sysI2CChkDone ();
  107.     }
  108. /*****************************************************************************
  109. *
  110. * sysI2CByteWrite - write a byte into the I2C EEPROM device
  111. *
  112. * This function writes <byte> into the I2C EEPROM at <address>.
  113. *
  114. * RETURNS: OK on completion, ERROR otherwise.
  115. */
  116. STATUS sysI2CByteWrite 
  117.     (
  118.     unsigned short address,           /* I2C Address */
  119.     unsigned char  byte               /* data to write */
  120.     )
  121.     {
  122.     STATUS status;                    /* used to check the I2C Status state */
  123.     /* Issue a Start command to I2C */
  124.     
  125.     status = sysI2CStart ();
  126.     if (status == ERROR)
  127.         return (ERROR);
  128.     /* Write Control Byte */
  129.     
  130.     I2C.i2cdo = (unsigned int) (I2C_24LC64_CNTL_BYTE);
  131.     I2C.i2cmcmd = I2CMCMD_CMD (WD);
  132.     sysWbFlush ();
  133.     status = sysI2CChkDone ();
  134.     if (status == ERROR)
  135.         return (ERROR);
  136.     /* Address - upper bits */
  137.     
  138.     I2C.i2cdo = (unsigned int) ((address >> I2CDO_DATA_WIDTH)
  139. & I2CDO_DATA_MASK);
  140.     I2C.i2cmcmd = I2CMCMD_CMD (WD);
  141.     sysWbFlush ();
  142.     status = sysI2CChkDone ();
  143.     if (status == ERROR)
  144.         return (ERROR);
  145.     /* Address - lower bits */
  146.     
  147.     I2C.i2cdo = (unsigned int) (address & I2CDO_DATA_MASK);
  148.     I2C.i2cmcmd = I2CMCMD_CMD (WD);
  149.     sysWbFlush ();
  150.     status = sysI2CChkDone ();
  151.     if (status == ERROR)
  152.         return (ERROR);
  153.     /* Write Data */
  154.     
  155.     I2C.i2cdo   = byte;
  156.     I2C.i2cmcmd = I2CMCMD_CMD (WD);
  157.     sysWbFlush ();
  158.     status = sysI2CChkDone ();
  159.     if (status == ERROR)
  160.         return (ERROR);
  161.                 
  162.     /* Generate Stop Command to make the write byte to 
  163.      * written internally. Wait for some time to let this
  164.      * internal operation finish 
  165.      */
  166.      
  167.     status = sysI2CStop ();
  168.     if (status != OK)
  169.         return (ERROR);
  170.     
  171.     /* Wait for some time for the internal operation to finish */
  172.     
  173.     sysUSecDelay (I2C_DELAY_MULT * 40000);
  174.     return (OK);
  175.     }
  176. /****************************************************************************
  177. *
  178. * sysI2CPageWriteOpen - open a 32-byte page in I2C EEPROM
  179. * This function initiates a page write operation to I2C EEPROM at <address>.
  180. * It may be followed by upto 32 sysI2CInPageWrite() operations and terminated
  181. * with the sysI2CStop() command.
  182. *
  183. * RETURNS: OK on completion, ERROR otherwise
  184. *
  185. * SEE ALSO: sysI2CInPageWrite(), sysI2CStop() 
  186. */
  187. STATUS sysI2CPageWriteOpen
  188.     (
  189.     unsigned short    address         /* I2C Address */
  190.     )
  191.     {
  192.     STATUS            status;         /* used to check the I2C Status state */
  193.  
  194.     /* Send a Start command */
  195.     
  196.     status = sysI2CStart ();
  197.     if (status == ERROR)
  198.         return (ERROR);
  199.     
  200.     /* Write Control Byte */
  201.     I2C.i2cdo = (unsigned int) (I2C_24LC64_CNTL_BYTE);
  202.     I2C.i2cmcmd = I2CMCMD_CMD (WD);
  203.     sysWbFlush ();
  204.     status = sysI2CChkDone ();
  205.     if (status == ERROR)
  206.         return (ERROR);
  207.     /* Address - upper 8 bits */
  208.     I2C.i2cdo = (unsigned int) ((address >> I2CDO_DATA_WIDTH)
  209. & I2CDO_DATA_MASK);
  210.     I2C.i2cmcmd = I2CMCMD_CMD (WD);
  211.     sysWbFlush ();
  212.     status = sysI2CChkDone ();
  213.     if (status == ERROR)
  214.         return (ERROR);
  215.     /* Address - lower 8 bits */
  216.     
  217.     I2C.i2cdo = (unsigned int) (address & I2CDO_DATA_MASK);
  218.     I2C.i2cmcmd = I2CMCMD_CMD (WD);
  219.     sysWbFlush ();
  220.     status = sysI2CChkDone ();
  221.     if (status == ERROR)
  222.         return (ERROR);
  223.     return (OK);
  224.     }
  225. /******************************************************************************
  226. *
  227. * sysI2CInPageWrite - write a byte to an already opened I2C EEPROM page
  228. * This function writes <byte> to a I2C page that has already been opened
  229. * by sysI2CPageWriteOpen(). The address is maintained and automatically
  230. * incremented by I2C.
  231. *
  232. * RETURNS: OK on completion, ERROR otherwise
  233. */
  234. STATUS sysI2CInPageWrite
  235.     (
  236.     unsigned char byte               /* data to be written */
  237.     )
  238.     {
  239.     STATUS        status;            /* used to check the I2C Status state */
  240.         
  241.     /* Write Data */
  242.     
  243.     I2C.i2cdo   =  byte;
  244.     I2C.i2cmcmd =  I2CMCMD_CMD (WD);
  245.     sysWbFlush ();
  246.     status = sysI2CChkDone ();
  247.     if (status == ERROR)
  248.         return (ERROR);
  249.     sysUSecDelay (I2C_DELAY_MULT * 600);
  250.     return (OK);
  251.     }
  252. /*****************************************************************************
  253. *
  254. * sysI2CStop - Issue a stop command to the I2C bus interface
  255. * This function issues a stop command to the I2C bus bus interface. It is
  256. * used to complete writes to the I2C EEPROM.
  257. *
  258. * RETURNS: OK on success, ERROR otherwise
  259. */
  260. STATUS sysI2CStop (void)
  261.     {
  262.     unsigned int devStatus;            /* I2C device status */
  263.     STATUS       status;               /* I2C module status state */
  264.     
  265.     /* Issue Stop Command */
  266.     
  267.     I2C.i2cmcmd = I2CMCMD_CMD (STOP);
  268.     sysWbFlush ();
  269.     sysUSecDelay (I2C_DELAY_MULT * 5000);
  270.     /* Check the I2C device status */
  271.     
  272.     devStatus = I2C.i2cms;
  273.     if (((devStatus & I2CMS_MASK) == I2CMS_D)
  274. || ((devStatus & I2CMS_MASK) == (I2CMS_D | I2CMS_NACK)))
  275. {
  276.         return OK;
  277. }
  278.     else
  279.         {
  280.         /* Check for Error Condition */
  281.         if ((devStatus & I2CMS_ERR))
  282.             {
  283.     
  284.             /* Clear Error Condition by Start Command */
  285.     
  286.             status = sysI2CStart ();
  287.             if (status != OK)
  288.                 {
  289.                 /* Something really bad, should'nt happen
  290.                  * Try starting once again & return with error
  291.                  */
  292.                 sysI2CStart ();
  293.                 return (ERROR);
  294.                 }
  295.             }
  296.         /* Okay we could start but caller should still be returned Error */
  297.         return (ERROR);
  298.         }
  299.     }
  300. /******************************************************************************
  301. *
  302. * sysI2CAckPollOnWrite - Wait for acknowledge from the I2C EEPROM.
  303. *                      
  304. * This routine waits for a Done/Acknowledge from the I2C EEPROM. It is
  305. * used to determine the completion of an internal EEPROM write
  306. * operation after a stop command has been issued.
  307. *
  308. * RETURNS: OK if acknowledged within 500 milliseconds, ERROR otherwise
  309. *
  310. * SEE ALSO: sysI2CStop()
  311. */
  312. STATUS sysI2CAckPollOnWrite (void)
  313.     {
  314.     unsigned int devStatus;             /* I2C device status */
  315.     UINT32       startCount;            /* Starting count for timeout */
  316.     /* Wait for Acknowledge from the Device */
  317.     startCount = sysUSecTimoutStart ();
  318.     while (!sysUSecTimoutExpired (startCount, I2C_DONE_TIMEOUT))
  319.         {
  320.         I2C.i2cdo = (unsigned int) (I2C_24LC64_CNTL_BYTE);
  321.         I2C.i2cmcmd = I2CMCMD_CMD (WD);
  322.         sysWbFlush ();
  323.         /* Send a start command & wait for Ack */
  324.         
  325.         I2C.i2cmcmd = I2CMCMD_CMD (START);
  326.         sysWbFlush ();
  327.         /* Read the status register */
  328.         
  329.         devStatus = I2C.i2cms;
  330.         if ((devStatus & I2CMS_MASK) == I2CMS_D) /* Done, Ack & no errors */
  331.             return OK;
  332.         } /* end of for loop of iterative checks on the status */
  333.     
  334.     /* I2C is taking quite some time to complete internal writes,
  335.      * return ERROR
  336.      */
  337.     
  338.     return (ERROR);
  339.     } 
  340.         
  341. /******************************************************************************
  342. *
  343. * sysI2CByteRead - Read a byte from the specified location in the I2C EEPROM
  344. *
  345. * This routine reads a byte from the location in the I2C EEPROM
  346. * specified by <address>.
  347. * RETURNS: OK on success, ERROR otherwise
  348. */
  349. STATUS sysI2CByteRead
  350.     (
  351.     unsigned short address,       /* I2C Address from where byte is read */
  352.     int *          byte           /* pointer to location for returned byte */
  353.     )
  354.     {
  355.     STATUS         status;        /* used to check the I2C status state */
  356.     unsigned int   devStatus;     /* I2C device status */
  357.     /* Send a Start Command */
  358.     
  359.     status = sysI2CStart ();
  360.     if (status == ERROR)
  361.         return (ERROR);
  362.     
  363.     /* Write Control Byte */
  364.     
  365.     I2C.i2cdo = (unsigned int) (I2C_24LC64_CNTL_BYTE);
  366.     I2C.i2cmcmd = I2CMCMD_CMD (WD);
  367.     sysWbFlush ();
  368.     
  369.     status = sysI2CChkDone ();
  370.     if (status == ERROR)
  371.         return (ERROR);
  372.     
  373.     /* Address - upper 8 bits */
  374.     
  375.     I2C.i2cdo = (unsigned int) ((address >> I2CDO_DATA_WIDTH)
  376. & I2CDO_DATA_MASK);
  377.     I2C.i2cmcmd = I2CMCMD_CMD (WD);
  378.     sysWbFlush ();
  379.     status = sysI2CChkDone ();
  380.     if (status == ERROR)
  381.         return (ERROR);
  382.     
  383.     /* Address - lower 8 bits */
  384.     
  385.     I2C.i2cdo = (unsigned int) (address & I2CDO_DATA_MASK);
  386.     I2C.i2cmcmd = I2CMCMD_CMD (WD);
  387.     sysWbFlush ();
  388.     status = sysI2CChkDone ();
  389.     if (status == ERROR)
  390.         return (ERROR);
  391.  
  392.     /* Send Start command once again */
  393.     
  394.     sysI2CStart ();
  395.     /* Send the Read Command Control Byte */
  396.     
  397.     I2C.i2cdo = (unsigned int) (I2C_24LC64_CNTL_BYTE | I2C_24LC64_RD_EN);
  398.     I2C.i2cmcmd = I2CMCMD_CMD (WD);
  399.     sysWbFlush ();
  400.     status = sysI2CChkDone ();
  401.     if (status == ERROR)
  402.         return (ERROR);
  403.  
  404.     /* Read data */
  405.     
  406.     I2C.i2cmcmd = I2CMCMD_CMD (RD);
  407.     sysWbFlush ();
  408.     devStatus = I2C.i2cms;
  409.     if (!(devStatus & I2CMS_D))
  410.         {
  411.         
  412.         /* Should have been done. Give some more time */
  413.          
  414.         sysUSecDelay (I2C_DELAY_MULT * 2500);
  415.         devStatus = I2C.i2cms;
  416.         if (!(devStatus & I2CMS_D))
  417.             {
  418.             
  419.             /* waited long enough return ERROR */
  420.              
  421.             return (ERROR);
  422.             }
  423.         }
  424.  
  425.     /* Return the byte read */
  426.     
  427.     *byte = (int) I2C.i2cdi;
  428.     return (OK);
  429.     }
  430. /*****************************************************************************
  431. * sysI2CSeqReadStart - Start a sequential read of I2C EEPROM.
  432. *                      
  433. * This function starts a bulk read from I2C EEPROM from the location
  434. * specified by <address>.  Typically the call to this function would
  435. * be followed by up to (I2C Memory space in bytes - starting address)
  436. * reads. Its left to the caller to ensure that no rollover (reading
  437. * beyond the capacity of I2C) occurs.
  438. *
  439. * RETURNS: OK on success, ERROR otherwise
  440. *
  441. * SEE ALSO: sysI2CSeqRead(), sysI2CSeqReadLast()
  442. */
  443. STATUS sysI2CSeqReadStart
  444.     (
  445.     unsigned short address            /* address of I2C beginning address */
  446.     )
  447.     {
  448.     STATUS status;                    /* used to check the I2C status state */
  449.     /* Send a Start command to I2C */
  450.     
  451.     status = sysI2CStart ();
  452.     if (status == ERROR)
  453.         return (ERROR);
  454.     /* Write Control Byte */
  455.     
  456.     I2C.i2cdo = (unsigned int) (I2C_24LC64_CNTL_BYTE);
  457.     I2C.i2cmcmd = I2CMCMD_CMD (WD);
  458.     sysWbFlush ();
  459.     status = sysI2CChkDone ();
  460.     if (status == ERROR)
  461.         return (ERROR);
  462.     /* Address - upper 8 bits */
  463.     
  464.     I2C.i2cdo = (unsigned int) ((address >> I2CDO_DATA_WIDTH)
  465. & I2CDO_DATA_MASK);
  466.     I2C.i2cmcmd = I2CMCMD_CMD (WD);
  467.     sysWbFlush ();
  468.     status = sysI2CChkDone ();
  469.     if (status == ERROR)
  470.         return (ERROR);
  471.     /* Address - lower 8 bits */
  472.     I2C.i2cdo = (unsigned int) (address & I2CDO_DATA_MASK);
  473.     I2C.i2cmcmd = I2CMCMD_CMD (WD);
  474.     sysWbFlush ();
  475.     status = sysI2CChkDone ();
  476.     if (status == ERROR)
  477.         return (ERROR);
  478.     /* Send another start command */
  479.     
  480.     status = sysI2CStart ();
  481.     if (status == ERROR)
  482.         return (ERROR);
  483.     /* Read Command */
  484.     
  485.     I2C.i2cdo   = (unsigned int) (I2C_24LC64_CNTL_BYTE | I2C_24LC64_RD_EN);
  486.     I2C.i2cmcmd = I2CMCMD_CMD (WD);
  487.     sysWbFlush ();
  488.     status = sysI2CChkDone ();
  489.     if (status == ERROR)
  490.         return (ERROR);
  491.     return (OK);
  492.     }
  493. /*****************************************************************************
  494. *
  495. * sysI2CSeqRead - Read a sequential byte from I2C EEPROM
  496. * This function reads a byte from the I2C internally maintained
  497. * address.  A call to this function is part of sequential bulk data read
  498. * from I2C, beginning at an address specified by the previous call to
  499. * the sysI2CSeqReadStart() function.
  500. *
  501. * RETURNS: OK on success, ERROR otherwise
  502. *
  503. * SEE ALSO: sysI2CSeqReadStart(), sysI2CSeqReadLast()
  504. */
  505. STATUS sysI2CSeqRead
  506.     (
  507.     int *          byte           /* pointer to location for returned byte */
  508.     )
  509.     {
  510.     STATUS         status;        /* used to check the I2C status state */
  511.     
  512.     /* Read data */
  513.     
  514.     I2C.i2cmcmd = I2CMCMD_CMD (RDACK);
  515.     sysWbFlush ();
  516.     status = sysI2CChkDone ();
  517.     if (status == ERROR)
  518.         return (ERROR);
  519.     sysUSecDelay (I2C_DELAY_MULT * 600);
  520.     
  521.     *byte = (int) I2C.i2cdi;
  522.     
  523.     return (OK);
  524.     
  525.     }
  526. /******************************************************************************
  527. *
  528. * sysI2CSeqReadLast - Perform last sequential read from I2C EEPROM
  529. *
  530. * This function reads the last byte in a sequential read from I2C.
  531. *
  532. * RETURNS: OK on success, ERROR otherwise
  533. */
  534. STATUS sysI2CSeqReadLast
  535.     (
  536.     int *          byte           /* Pointer to location for returned byte */
  537.     )
  538.     {
  539.     unsigned int   devStatus;     /* I2C device status */
  540.     UINT32         startCount;    /* Starting count for timeout */
  541.     /* Read data */
  542.     
  543.     I2C.i2cmcmd = I2CMCMD_CMD (RD);
  544.     sysWbFlush ();
  545.     /* Check if Done flag is set in I2C Status, Please note that the slave
  546.      * would not send the Ack for RD command
  547.      */
  548.     
  549.     startCount = sysUSecTimoutStart ();
  550.     while (!sysUSecTimoutExpired (startCount, I2C_DONE_TIMEOUT))
  551. {
  552.         devStatus = I2C.i2cms;
  553. if (devStatus & I2CMS_D)
  554.     {
  555.     *byte = (int) I2C.i2cdi;
  556.     return (OK);
  557.     }
  558.         }
  559.     /* timed out */
  560.     
  561.     return (ERROR);
  562.     }
  563. /******************************************************************************
  564. *
  565. * sysI2CPageWrite - Write a 32-byte page of data to I2C EEPROM
  566. *
  567. * This function writes a 32-bytes to the I2C at the specified address.
  568. *
  569. * RETURNS: OK on success, ERROR otherwise
  570. */
  571. STATUS sysI2CPageWrite
  572.     (
  573.     unsigned short  address,    /* address in the I2C to write */
  574.     unsigned char * buffer      /* pointer to a 32-byte buffer */
  575.     )
  576.     {
  577.     STATUS          status;     /* used to check the status of I2C */
  578.     int             iCount;     /* loop count */
  579.     status = sysI2CPageWriteOpen (address);
  580.     if (status != OK)
  581.         return (ERROR);
  582.     for (iCount = 0; iCount < I2C_EEPROM_PAGE_SIZE; iCount++)
  583.         {
  584.         status = sysI2CInPageWrite (buffer[iCount]);
  585.         if (status != OK)
  586.            return (ERROR);
  587.         sysUSecDelay (I2C_DELAY_MULT * 5000);
  588.         }
  589.     /* Generate Stop to allow writing of data from the I2C internal 
  590.      * buffer to the EEPROM
  591.      */
  592.     
  593.     sysI2CStop ();
  594.     /* Perform Write Acknowledge Poll */
  595.     
  596.     sysUSecDelay (I2C_DELAY_MULT * 60000);
  597.     
  598.     return (OK);
  599.     }
  600. /*****************************************************************************
  601. *
  602. * sysI2CByteWrite - Write up to 32 bytes to I2C EEPROM
  603. *
  604. * This function writes up to 32 bytes to the specified I2C EEPROM
  605. * location (<address>).
  606. *
  607. * RETURNS: OK on success, ERROR otherwise
  608. */
  609. STATUS sysI2CByteWrites
  610.     (
  611.     unsigned short  address,   /* address of I2C */
  612.     unsigned char * buffer,    /* input buffer, <numBytes> in length */
  613.     unsigned int    numBytes   /* number of bytes to be written */
  614.     )
  615.     {
  616.     STATUS          status;    /* Used to check the status of I2C */
  617.     int             iCount;    /* loop count */
  618.     status = sysI2CPageWriteOpen (address);
  619.     if (status != OK)
  620.         return (ERROR);
  621.     for (iCount = 0;
  622.  (iCount < numBytes) && (iCount < I2C_EEPROM_PAGE_SIZE);
  623.  iCount++)
  624.         {
  625.         status = sysI2CInPageWrite (buffer[iCount]);
  626.         if (status != OK) 
  627.             return (ERROR);
  628.         sysUSecDelay (I2C_DELAY_MULT * 5000);
  629.         }
  630.     /* Generate Stop to allow writing of data from the I2C internal 
  631.      * buffer to the Eeprom
  632.      */
  633.      
  634.     sysI2CStop ();
  635.     sysUSecDelay (I2C_DELAY_MULT * 60000);
  636.     return (OK);
  637.     }
  638. /******************************************************************************
  639. *
  640. * sysI2CStringRead - Read a string from I2C EEPROM
  641. *
  642. * This function reads a string of length <numBytes> from the specified
  643. * <address> in I2C EEPROM, and adds an EOS to the return <string>. The
  644. * return <string> must be at least <numBytes> + 1 in length.
  645. *
  646. * RETURNS: OK on success, ERROR otherwise
  647. *
  648. * SEE ALSO: sysI2CStringWrite() */
  649. STATUS sysI2CStringRead
  650.     (
  651.     unsigned short  address,   /* address of I2C */ 
  652.     UINT8 *         string,    /* output string  */
  653.     unsigned int    numBytes   /* number of bytes to read */
  654.     )
  655.     {
  656.     STATUS          status;    /* used to check the status of I2C */
  657.     int             iCount;    /* loop count */
  658.     int             byte;      /* byte read */
  659.     /* Sanity check */
  660.     
  661.     if (numBytes < 1)          /* At least 1 byte must be read */
  662.         return (ERROR);
  663.     if (string == NULL)        /* Null input string */
  664.         return (ERROR);
  665.     /* Check address range */
  666.     
  667.     if ((address + (UINT16) numBytes) > (UINT16) I2C_MEM_SIZE)
  668.         return (ERROR);
  669.     status = sysI2CSeqReadStart (address);
  670.     /* check the returned status */
  671.     
  672.     if (status != OK)
  673.         return (ERROR);
  674.     for (iCount = 0; iCount < (numBytes - 1); iCount++)
  675.         {
  676. status = sysI2CSeqRead (&byte);
  677. if (status != OK)
  678.     return (ERROR);
  679.         string[iCount] = byte;
  680.         }
  681.     sysUSecDelay (I2C_DELAY_MULT * 5000);
  682.     /* Perform the last read operation */
  683.     
  684.     status = sysI2CSeqReadLast (&byte);
  685.     if (status != OK)
  686. return (ERROR);
  687.     string [numBytes - 1] = (char) byte;
  688.     /* Append End of String */
  689.     
  690.     string [numBytes] = EOS;
  691.     return (OK);   
  692.     }
  693. /******************************************************************************
  694. *
  695. * sysI2CStringWrite - Write a string to I2C EEPROM
  696. *
  697. * This function writes a string of length <numBytes> to the specified
  698. * <address> in I2C EEPROM. The EOS character is not written.
  699. *
  700. * RETURNS : OK on success, ERROR otherwise
  701. *
  702. * SEE ALSO: sysI2CStringRead()
  703. */
  704. STATUS sysI2CStringWrite
  705.     (
  706.     unsigned short  address,       /* address of I2C */ 
  707.     UINT8 *         string,        /* input string */
  708.     unsigned int    numBytes       /* number of bytes */
  709.     )
  710.     {
  711.     STATUS          status;        /* Used to check the status of I2C */
  712.     int             iCount;        /* loop count */
  713.     unsigned int    numOfPages;    /* To determine no of pages */
  714.     unsigned int    numOfRemWrites;/* remaining byte writes */
  715.     unsigned int    memI2CRef = 0; /* To reference I2C memory */
  716.     unsigned int    pageAlign;     /* used for data page aligning */
  717.     unsigned int    numOfPageAlignWrites = 0; 
  718.     status = ERROR;
  719.     
  720.     /* Sanity check */
  721.     
  722.     if (string == NULL)         /* Null input string */
  723.         return (ERROR);
  724.     /* Check address  */
  725.     
  726.     if (address > (UINT16) I2C_MEM_SIZE)
  727.         return (ERROR);
  728.     /* Check address range */
  729.     
  730.     if ((address + numBytes) > (UINT16) I2C_MEM_SIZE)
  731.         return (ERROR);
  732.     /* Align the input data correctly on page boundary */
  733.     
  734.     pageAlign = (unsigned int) (address & I2C_EEPROM_PAGE_BITS);
  735.     numOfPageAlignWrites = I2C_EEPROM_PAGE_SIZE - pageAlign;
  736.     if (numOfPageAlignWrites > numBytes)
  737.         { 
  738. /* call writeBytes and return*/
  739. status = sysI2CByteWrites (address, &string[0], numBytes);
  740. return (status);
  741.         }
  742.     else
  743.         { 
  744.         
  745.         /* first write numOfPageAlign bytes */
  746.         
  747.         status = sysI2CByteWrites (address, &string[0],
  748.                                   numOfPageAlignWrites);
  749.         /* bump up I2C memory address reference */
  750.         
  751.         memI2CRef += numOfPageAlignWrites;
  752.         }
  753.     /* Proceed with the remaining writes */ 
  754.     numOfPages = (numBytes - numOfPageAlignWrites) / I2C_EEPROM_PAGE_SIZE;
  755.     numOfRemWrites = (numBytes - numOfPageAlignWrites)
  756.       % I2C_EEPROM_PAGE_SIZE;
  757.     /* Start writing the pages first */
  758.     
  759.     for (iCount = 0; iCount < numOfPages; iCount++)
  760.         {
  761.         status = sysI2CPageWrite ((address + memI2CRef),&string[memI2CRef]);
  762.         if (status != OK)
  763.     {
  764.             return (ERROR);
  765.     }
  766.         memI2CRef += I2C_EEPROM_PAGE_SIZE;
  767.         }
  768.     /* Now write the remaining bytes */
  769.     
  770.     if (numOfRemWrites)
  771.         {
  772.         status = sysI2CByteWrites ((address + memI2CRef),
  773.       (&string[memI2CRef]), numOfRemWrites);
  774.         }
  775.     return (status);
  776.     }
  777. #ifdef I2C_DEBUG
  778. /*****************************************************************************
  779. *
  780. * i2cTestSingleWrites - Perform single byte writes to I2C EEPROM
  781. *
  782. * This routine performs single bytes writes. Used to test atomic
  783. * writes to I2C.
  784. *
  785. * RETURNS : N/A
  786. *
  787. * NOMANUAL
  788. */
  789. void testSingleWrites
  790.     (
  791.     unsigned short  address,    /* I2C Address to write to */
  792.     unsigned char * string,     /* String data for writes */
  793.     unsigned int    numBytes    /* number of bytes */
  794.     )
  795.     {
  796.     STATUS          status;  /* to check I2C Status */
  797.     int             iCount;  /* loop count */
  798.     for (iCount = 0; iCount < numBytes; iCount++)
  799.         {
  800.         status = sysI2CByteWrite (address,string[iCount]);
  801.         if (status != OK)
  802.             {
  803.             printf (" Single Write test failed !!! n");
  804.             break;
  805.             }
  806.         printf (" Wrote character %dn", iCount);
  807.         address += 1;
  808.         }/* end of for loop */
  809.     }
  810. /****************************************************************************
  811. *
  812. * i2cTestSingleRead - Perform single byte reads from I2C EEPROM.
  813. * This routine performs single bytes reads. Used to test atomic reads to I2C
  814. *
  815. * RETURNS: N/A
  816. *
  817. * NOMANUAL
  818. */ 
  819. void testSingleReads
  820.     (
  821.     unsigned short  address,   /* I2C Address to write to */
  822.     unsigned char * string,    /* String data for writes */
  823.     unsigned int    numBytes   /* number of bytes */
  824.     )
  825.     {
  826.     STATUS          status;    /* to check I2C Status */
  827.     int             iCount;    /* loop count */
  828.     int             byte;      /* byte read */
  829.     for (iCount = 0; iCount < numBytes;  iCount++)
  830.         {
  831.         status = sysI2CByteRead (address, &byte);
  832.         if (status == ERROR)
  833.             {
  834.             printf (" Single Read test failed !!! n");
  835.             break;
  836.             }
  837.         string[iCount] = (char) byte;
  838.         address += 1;
  839.         } /* end of for loop */
  840.     }
  841. #endif /* I2C_DEBUG */