PDL for FM0+  Version1.0
Peripheral Driverl Library for FM0+
C:/pdl_v10/library/utility/at24cxx/i2c_polling_at24cxx.c
Go to the documentation of this file.
00001 /*******************************************************************************
00002 * Copyright (C) 2013 Spansion LLC. All Rights Reserved. 
00003 *
00004 * This software is owned and published by: 
00005 * Spansion LLC, 915 DeGuigne Dr. Sunnyvale, CA  94088-3453 ("Spansion").
00006 *
00007 * BY DOWNLOADING, INSTALLING OR USING THIS SOFTWARE, YOU AGREE TO BE BOUND 
00008 * BY ALL THE TERMS AND CONDITIONS OF THIS AGREEMENT.
00009 *
00010 * This software contains source code for use with Spansion 
00011 * components. This software is licensed by Spansion to be adapted only 
00012 * for use in systems utilizing Spansion components. Spansion shall not be 
00013 * responsible for misuse or illegal use of this software for devices not 
00014 * supported herein.  Spansion is providing this software "AS IS" and will 
00015 * not be responsible for issues arising from incorrect user implementation 
00016 * of the software.  
00017 *
00018 * SPANSION MAKES NO WARRANTY, EXPRESS OR IMPLIED, ARISING BY LAW OR OTHERWISE,
00019 * REGARDING THE SOFTWARE (INCLUDING ANY ACOOMPANYING WRITTEN MATERIALS), 
00020 * ITS PERFORMANCE OR SUITABILITY FOR YOUR INTENDED USE, INCLUDING, 
00021 * WITHOUT LIMITATION, THE IMPLIED WARRANTY OF MERCHANTABILITY, THE IMPLIED 
00022 * WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE OR USE, AND THE IMPLIED 
00023 * WARRANTY OF NONINFRINGEMENT.  
00024 * SPANSION SHALL HAVE NO LIABILITY (WHETHER IN CONTRACT, WARRANTY, TORT, 
00025 * NEGLIGENCE OR OTHERWISE) FOR ANY DAMAGES WHATSOEVER (INCLUDING, WITHOUT 
00026 * LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS, BUSINESS INTERRUPTION, 
00027 * LOSS OF BUSINESS INFORMATION, OR OTHER PECUNIARY LOSS) ARISING FROM USE OR 
00028 * INABILITY TO USE THE SOFTWARE, INCLUDING, WITHOUT LIMITATION, ANY DIRECT, 
00029 * INDIRECT, INCIDENTAL, SPECIAL OR CONSEQUENTIAL DAMAGES OR LOSS OF DATA, 
00030 * SAVINGS OR PROFITS, 
00031 * EVEN IF SPANSION HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 
00032 * YOU ASSUME ALL RESPONSIBILITIES FOR SELECTION OF THE SOFTWARE TO ACHIEVE YOUR
00033 * INTENDED RESULTS, AND FOR THE INSTALLATION OF, USE OF, AND RESULTS OBTAINED 
00034 * FROM, THE SOFTWARE.  
00035 *
00036 * This software may be replicated in part or whole for the licensed use, 
00037 * with the restriction that this Disclaimer and Copyright notice must be 
00038 * included with each copy of this software, whether used in part or whole, 
00039 * at all times.  
00040 */
00041 
00042 /******************************************************************************/
00053 /******************************************************************************/
00054 /* Include files                                                              */
00055 /******************************************************************************/
00056 #include "i2c_at24cxx.h"
00057 
00058 #if (PDL_UTILITY_ENABLE_I2C_POLLING_AT24CXX == PDL_ON)
00059 
00060 /*****************************************************************************/
00061 /* Local pre-processor symbols/macros ('#define')                            */
00062 /*****************************************************************************/
00063 /*****************************************************************************/
00064 /* Global variable definitions (declared in header file with 'extern')       */
00065 /*****************************************************************************/
00066 /*****************************************************************************/
00067 /* Local type definitions ('typedef')                                        */
00068 /*****************************************************************************/
00069 /*****************************************************************************/
00070 /* Local variable definitions ('static')                                     */
00071 /*****************************************************************************/
00080 static boolean_t I2cCheckErrorStatus(void)
00081 {    
00082     if(TRUE == Mfs_I2c_GetStatus(EE_I2C_CH, I2cBusErr))
00083     {
00084         return TRUE; /* Bus error occurs? */
00085     }
00086     
00087     if(TRUE == Mfs_I2c_GetStatus(EE_I2C_CH, I2cOverrunError))
00088     {
00089         return TRUE; /* Overrun error occurs? */
00090     }
00091     
00092     return FALSE;
00093 }
00094 
00106 static en_result_t I2cStart(uint8_t u8DevAddr)
00107 {
00108     /* Prepare I2C device address */
00109     Mfs_I2c_SendData(EE_I2C_CH, u8DevAddr);
00110     
00111     /* Enable ACK */
00112     Mfs_I2c_ConfigAck(EE_I2C_CH, I2cAck);
00113     
00114     /* Generate I2C start signal */
00115     if(Ok != Mfs_I2c_GenerateStart(EE_I2C_CH))
00116     {
00117         return ErrorTimeout; /* Timeout or other error */
00118     }
00119 
00120     /* Wait until data transfer finish */
00121     while(1)
00122     {
00123         if(TRUE != Mfs_I2c_GetStatus(EE_I2C_CH, I2cRxTxInt))
00124         {
00125             break;
00126         }
00127     }
00128     
00129     /* Check ACK */
00130     if(I2cNAck == Mfs_I2c_GetAck(EE_I2C_CH))
00131     {
00132         return Error;   /* NACK */
00133     }
00134     
00135     /* Check error status of I2C */
00136     if(TRUE == I2cCheckErrorStatus())
00137     {
00138         return Error;
00139     }
00140     
00141     return Ok;
00142 }
00143 
00155 static en_result_t I2cRestart(uint8_t u8Addr)
00156 {
00157     /* Prepare I2C device address */
00158     Mfs_I2c_SendData(EE_I2C_CH, u8Addr);
00159     
00160     /* Enable ACK */
00161     Mfs_I2c_ConfigAck(EE_I2C_CH, I2cAck);
00162     
00163     /* Generate I2C start signal */
00164     if(Ok != Mfs_I2c_GenerateRestart(EE_I2C_CH))
00165     {
00166         return ErrorTimeout; /* Timeout or other error */
00167     }
00168 
00169     /* Wait until data transfer finish */
00170     while(1)
00171     {
00172         if(TRUE != Mfs_I2c_GetStatus(EE_I2C_CH, I2cRxTxInt))
00173         {
00174             break;
00175         }
00176     }
00177     
00178     /* Check ACK */
00179     if(I2cNAck == Mfs_I2c_GetAck(EE_I2C_CH))
00180     {
00181         return Error;   /* NACK */
00182     }
00183     
00184     /* Check error status of I2C */
00185     if(TRUE == I2cCheckErrorStatus())
00186     {
00187         return Error;
00188     }
00189     
00190     return Ok;
00191 }
00192 
00204 static en_result_t I2cSendData(uint8_t* pu8Data, uint8_t u8Size) 
00205 {
00206     uint8_t i = 0;
00207     
00208     for(i=0;i<u8Size;i++)
00209     {
00210         /* Wait for end of transmission */
00211         while(1)
00212         {
00213             if(TRUE == Mfs_I2c_GetStatus(EE_I2C_CH, I2cRxTxInt))
00214             {
00215                 break;
00216             }
00217         }
00218       
00219         /* Transmit the data */
00220         Mfs_I2c_SendData(EE_I2C_CH, pu8Data[i]);
00221         Mfs_I2c_ClrStatus(EE_I2C_CH, I2cRxTxInt);
00222         
00223         /* Check until TX finish */
00224         while(1)
00225         {
00226             if(TRUE == Mfs_I2c_GetStatus(EE_I2C_CH, I2cTxEmpty))
00227             {
00228                 break;
00229             }
00230         }
00231        
00232         /* Check ACK */
00233         if(I2cNAck == Mfs_I2c_GetAck(EE_I2C_CH))
00234         {
00235             return Error;   /* NACK */
00236         }
00237         
00238         if(TRUE == I2cCheckErrorStatus())
00239         {
00240             return Error;
00241         }
00242     }
00243     
00244     return Ok;
00245 }
00246 
00258 static en_result_t I2cRead(uint8_t *pRxData, uint8_t u8Size)
00259 {
00260     uint8_t u8i = 0;
00261     uint8_t u8j;
00262        
00263     while(u8i < u8Size)
00264     {   
00265         /* Wait for the receive data */
00266         while(1)
00267         {
00268             if(TRUE == Mfs_I2c_GetStatus(EE_I2C_CH, I2cRxTxInt))
00269             {
00270                 break;
00271             }
00272         }
00273         
00274         u8j = 10;
00275         while(u8j--);
00276         
00277 
00278         if(u8i == u8Size-1)
00279         {
00280             Mfs_I2c_ConfigAck(EE_I2C_CH, I2cNAck); /* Last byte send a NACK */
00281         }
00282         else
00283         {
00284             Mfs_I2c_ConfigAck(EE_I2C_CH, I2cAck);
00285         }
00286         
00287         /* Clear interrupt flag and receive data to RX buffer */
00288         Mfs_I2c_ClrStatus(EE_I2C_CH, I2cRxTxInt);
00289         
00290         /* Wait for the receive data */
00291         while(1)
00292         {
00293             if(TRUE == Mfs_I2c_GetStatus(EE_I2C_CH, I2cRxFull))
00294             {
00295                 break;
00296             }
00297         }
00298          
00299         /* Check error status of I2C */
00300         if(TRUE == I2cCheckErrorStatus())
00301         {
00302             return Error;
00303         }
00304         
00305         pRxData[u8i++] = Mfs_I2c_ReceiveData(EE_I2C_CH);
00306     }
00307     return Ok;
00308 }
00309 
00319 static en_result_t I2cStop(void)
00320 {
00321     /* Generate I2C start signal */
00322     if(Ok != Mfs_I2c_GenerateStop(EE_I2C_CH))
00323     {
00324         return ErrorTimeout; /* Timeout or other error */
00325     }
00326     /* Clear Stop condition flag */
00327     while(1)
00328     {
00329         if(TRUE == Mfs_I2c_GetStatus(EE_I2C_CH, I2cStopDetect))
00330         {
00331             break;
00332         }
00333     }
00334    
00335     if(TRUE == Mfs_I2c_GetStatus(EE_I2C_CH, I2cBusErr))
00336     {
00337         return Error;
00338     }
00339    
00340     Mfs_I2c_ClrStatus(EE_I2C_CH, I2cStopDetect);
00341     Mfs_I2c_ClrStatus(EE_I2C_CH, I2cRxTxInt);
00342     
00343     return Ok;
00344 }
00345 
00354 en_result_t At24cxx_Init(void)
00355 {
00356     stc_mfs_i2c_config_t stcI2cConfig;
00357         
00358     InitI2cIo();
00359     
00360     stcI2cConfig.enMsMode = I2cMaster;
00361     stcI2cConfig.u32BaudRate = 100000u;
00362     stcI2cConfig.bWaitSelection = FALSE;
00363     stcI2cConfig.bDmaEnable = FALSE;
00364     stcI2cConfig.bEnableFifo = FALSE;
00365     
00366     if(Ok != Mfs_I2c_Init(EE_I2C_CH, &stcI2cConfig))
00367     {
00368         return Error;
00369     }
00370     
00371     return Ok;
00372 }
00373 
00386 en_result_t At24cxx_ByteWrite(uint8_t u8DevAddr, uint16_t u16Addr, uint8_t u8Data)
00387 {
00388     uint8_t au8TempData[3];
00389   
00390     if(Ok != I2cStart((u8DevAddr<<1) | 0u))
00391     {
00392         return Error;
00393     }
00394     
00395     /* Send page address */
00396     if(AT24CXX_ADDR_LENGTH == 1)
00397     {
00398         au8TempData[0] = u16Addr & 0x00FFu;
00399     }
00400     else
00401     {
00402         au8TempData[0] = u16Addr & 0x00FFu;
00403         au8TempData[1] = (u16Addr & 0xFF00u) >> 8;
00404     }
00405     
00406     if(Ok != I2cSendData(au8TempData, AT24CXX_ADDR_LENGTH))
00407     {
00408         return Error;
00409     }
00410     
00411     /* Send data */
00412     if(Ok != I2cSendData(&u8Data, 1))
00413     {
00414         return Error;
00415     }
00416     
00417     if(Ok != I2cStop())
00418     {
00419         return Error;
00420     }
00421     
00422     return Ok;
00423 }
00424 
00425 
00439 en_result_t At24cxx_PageWrite(uint8_t u8DevAddr, uint16_t u16PageAddr, uint8_t* pu8Data, uint8_t u8Size)
00440 {
00441     uint8_t au8TempData[2];
00442   
00443     if(u8Size > AT24CXX_PAGE_SIZE)
00444     {
00445         return ErrorInvalidParameter;
00446     }
00447     
00448     if(Ok != I2cStart((u8DevAddr<<1) | 0u))
00449     {
00450         return Error;
00451     }
00452     
00453     /* Send page address */
00454     if(AT24CXX_ADDR_LENGTH == 1)
00455     {
00456         au8TempData[0] = u16PageAddr & 0x00FFu;
00457     }
00458     else
00459     {
00460         au8TempData[0] = u16PageAddr & 0x00FFu;
00461         au8TempData[1] = (u16PageAddr & 0xFF00u) >> 8;
00462     }
00463     
00464     if(Ok != I2cSendData(au8TempData, AT24CXX_ADDR_LENGTH))
00465     {
00466         return Error;
00467     }
00468     
00469     /* Send data */
00470     if(Ok != I2cSendData(pu8Data, u8Size))
00471     {
00472         return Error;
00473     }
00474     
00475     if(Ok != I2cStop())
00476     {
00477         return Error;
00478     }
00479     
00480     return Ok;
00481 }
00482 
00494 en_result_t At24cxx_CurrentAddrRead(uint8_t u8DevAddr, uint8_t* pu8CurData)
00495 {   
00496     if(Ok != I2cStart((u8DevAddr<<1)  | 1u))
00497     {
00498         return Error;
00499     }
00500     
00501     I2cRead(pu8CurData, 1);
00502     
00503     if(Ok != I2cStop())
00504     {
00505         return Error;
00506     }
00507     
00508     return Ok;
00509 }
00510 
00523 en_result_t At24cxx_RandomRead(uint8_t u8DevAddr, uint16_t u16Addr, uint8_t* pu8Data)
00524 {
00525     uint8_t au8TempData[2];
00526     uint32_t u32DelayCnt = SystemCoreClock/10000;
00527     
00528     /* Send start with write flag */
00529     if(Ok != I2cStart((u8DevAddr<<1)  | 0u))
00530     {
00531         return Error;
00532     }
00533     
00534     /* Send address */
00535     if(AT24CXX_ADDR_LENGTH == 1)
00536     {
00537         au8TempData[0] = u16Addr & 0x00FFu;
00538     }
00539     else
00540     {
00541         au8TempData[0] = u16Addr & 0x00FFu;
00542         au8TempData[1] = (u16Addr & 0xFF00u) >> 8;
00543     }
00544     
00545     if(Ok != I2cSendData(au8TempData, AT24CXX_ADDR_LENGTH))
00546     {
00547         return Error;
00548     }
00549     /* Dummy delay */
00550     while(u32DelayCnt--);
00551     
00552     /* Send start with read flag */
00553     if(Ok != I2cRestart((u8DevAddr<<1)  | 1u))
00554     {
00555         return Error;
00556     }
00557        
00558     /* Read address */   
00559     if(Ok != I2cRead(pu8Data, 1))
00560     {
00561         return Error;
00562     }
00563        
00564     if(Ok != I2cStop())
00565     {
00566         return Error;
00567     }
00568     
00569     return Ok;
00570 }
00571 
00584 en_result_t At24cxx_SequentialRead(uint8_t u8DevAddr, uint8_t* pu8Data, uint8_t u8Size)
00585 {
00586     if(Ok != I2cStart((u8DevAddr<<1)  | 1u))
00587     {
00588         return Error;
00589     }
00590     
00591     if(Ok != I2cRead(pu8Data, u8Size))
00592     {
00593         return Error;
00594     }
00595     
00596     if(Ok != I2cStop())
00597     {
00598         return Error;
00599     }
00600     
00601     return Ok;
00602 }
00603 
00611 void At24cxx_Delayms(uint32_t u32Cnt)
00612 {
00613     uint32_t u32i;
00614     
00615     for(;u32Cnt;u32Cnt--)
00616         for(u32i=SystemCoreClock/12000; u32i; u32i--);
00617 }
00618 
00619 #endif // if (PDL_UTILITY_ENABLE_I2C_POLLING_AT24CXX == PDL_ON)
00620 
00621 /******************************************************************************/
00622 /* EOF (not truncated)                                                        */
00623 /******************************************************************************/