PDL for FM0+  Version1.0
Peripheral Driverl Library for FM0+
C:/pdl_v10/library/utility/at24cxx/i2c_int_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 #include <string.h>
00058 
00059 #if (PDL_UTILITY_ENABLE_I2C_INT_AT24CXX == PDL_ON)
00060 
00061 /*****************************************************************************/
00062 /* Local pre-processor symbols/macros ('#define')                            */
00063 /*****************************************************************************/
00064 /*****************************************************************************/
00065 /* Global variable definitions (declared in header file with 'extern')       */
00066 /*****************************************************************************/
00067 /*****************************************************************************/
00068 /* Local type definitions ('typedef')                                        */
00069 /*****************************************************************************/
00074 typedef enum en_i2c_rw_mode
00075 {
00076     I2cTxMode = 0,          
00077     I2cRxMode,              
00078     I2cTxRxMode,            
00079     
00080 }en_i2c_rw_mode_t;
00081 
00086 typedef enum en_i2c_seq
00087 {
00088     I2cSeqStart = 0u,    
00089     I2cSeqWrite,         
00090     I2cSeqRestart,       
00091     I2cSeqRead,          
00092     I2cSeqStop,          
00093     
00094 }en_i2c_seq_t;
00095 
00100 typedef struct stc_i2c_info
00101 {
00102     boolean_t bI2cErrorFlag;      
00103     uint8_t*  pu8TxBuf;           
00104     uint32_t  u32TxSize;          
00105     uint8_t*  pu8RxBuf;           
00106     uint32_t  u32RxSize;          
00107     uint32_t  u32Count;           
00108     en_i2c_seq_t     enSequence;  
00109     uint8_t          u8DevAddr;   
00110     en_i2c_rw_mode_t enRwMode;    
00111     uint32_t  u32TxRxGap;         
00112     
00113 }stc_i2c_info_t;
00114 
00115 /*****************************************************************************/
00116 /* Local variable definitions ('static')                                     */
00117 /*****************************************************************************/
00118 stc_i2c_int_sel_t    stcI2cIntSel;
00119 stc_i2c_int_cb_t     stcI2cIntCb;
00120 stc_i2c_info_t stcI2cInfo;
00121 
00130 static boolean_t I2cCheckErrorStatus(void)
00131 {    
00132     if(TRUE == Mfs_I2c_GetStatus(EE_I2C_CH, I2cBusErr))
00133     {
00134         return TRUE; /* Bus error occurs? */
00135     }
00136     
00137     if(TRUE == Mfs_I2c_GetStatus(EE_I2C_CH, I2cOverrunError))
00138     {
00139         return TRUE; /* Overrun error occurs? */
00140     }
00141     
00142     return FALSE;
00143 }
00144 
00152 static void Delay(uint32_t u32Cnt)
00153 {
00154     for(;u32Cnt;u32Cnt--);
00155 }
00156 
00157 
00163 static void I2cTxCallback(void)
00164 {
00165     if(stcI2cInfo.enSequence == I2cSeqStart)
00166     {
00167         if((stcI2cInfo.enRwMode == I2cTxMode) || (stcI2cInfo.enRwMode == I2cTxRxMode))
00168         {
00169             /* Prepare I2C device address with write flag */
00170             Mfs_I2c_SendData(EE_I2C_CH, ((stcI2cInfo.u8DevAddr<<1)|0u));
00171             
00172             stcI2cInfo.enSequence = I2cSeqWrite;
00173         }
00174         else
00175         {
00176             /* Prepare I2C device address with read flag */
00177             Mfs_I2c_SendData(EE_I2C_CH, ((stcI2cInfo.u8DevAddr<<1)|1u));
00178             
00179             PDL_ZERO_STRUCT(stcI2cIntSel);
00180             stcI2cIntSel.bTxInt = TRUE; 
00181             Mfs_I2c_DisableInt(EE_I2C_CH, &stcI2cIntSel); // Disable TX interrupt when read
00182         }
00183       
00184         /* Enable ACK */
00185         Mfs_I2c_ConfigAck(EE_I2C_CH, I2cAck);
00186         
00187         /* Generate I2C start signal */
00188         if(Ok != Mfs_I2c_GenerateStart(EE_I2C_CH))
00189         {
00190             stcI2cInfo.bI2cErrorFlag = 1;
00191             return; /* Timeout or other error */
00192         }
00193         
00194         
00195     }
00196     else if(stcI2cInfo.enSequence == I2cSeqRestart)
00197     {
00198         /* Sometimes a short time delay is needed before generate restart */
00199         Delay(stcI2cInfo.u32TxRxGap);
00200         /* Prepare I2C device address */
00201         Mfs_I2c_SendData(EE_I2C_CH, ((stcI2cInfo.u8DevAddr<<1)|1u));
00202         
00203         /* Enable ACK */
00204         Mfs_I2c_ConfigAck(EE_I2C_CH, I2cAck);
00205         
00206         /* Generate I2C start signal */
00207         if(Ok != Mfs_I2c_GenerateRestart(EE_I2C_CH))
00208         {
00209             stcI2cInfo.bI2cErrorFlag = 1;
00210             return ; /* Timeout or other error */
00211         }
00212         
00213         if(stcI2cInfo.enRwMode == I2cTxRxMode)
00214         {
00215             PDL_ZERO_STRUCT(stcI2cIntSel);
00216             stcI2cIntSel.bTxInt = TRUE; 
00217             Mfs_I2c_DisableInt(EE_I2C_CH, &stcI2cIntSel); // Disable TX interrupt when read
00218         }
00219         
00220     }
00221     else if(stcI2cInfo.enSequence == I2cSeqWrite)
00222     {
00223         if(stcI2cInfo.u32Count == stcI2cInfo.u32TxSize)
00224         {
00225             if(stcI2cInfo.enRwMode != I2cTxRxMode) 
00226             {
00227                 /* Generate I2C stop signal */
00228                 if(Ok != Mfs_I2c_GenerateStop(EE_I2C_CH))
00229                 {
00230                     stcI2cInfo.bI2cErrorFlag = 1;
00231                     return; /* Timeout or other error */
00232                 }
00233             }
00234             else // Don't generate stop signal if read continues after write
00235             {
00236                 stcI2cInfo.enSequence = I2cSeqRestart;      
00237                 stcI2cInfo.u32Count = 0;
00238             }
00239             return;
00240         }
00241     
00242         Mfs_I2c_SendData(EE_I2C_CH, *stcI2cInfo.pu8TxBuf++);
00243         Mfs_I2c_ClrStatus(EE_I2C_CH, I2cRxTxInt);
00244         
00245         stcI2cInfo.u32Count++;
00246 
00247     }
00248 }
00249 
00255 static void I2cRxCallback(void)
00256 {
00257     if(stcI2cInfo.enSequence == I2cSeqRead)
00258     {
00259         *stcI2cInfo.pu8RxBuf++ = Mfs_I2c_ReceiveData(EE_I2C_CH);
00260         
00261         if(stcI2cInfo.u32Count == stcI2cInfo.u32RxSize)
00262         {
00263             // Generate stop signal
00264             if(Ok != Mfs_I2c_GenerateStop(EE_I2C_CH))
00265             {
00266                 stcI2cInfo.bI2cErrorFlag = 1;
00267                 return; /* Timeout or other error */
00268             }
00269             return;
00270         }
00271         
00272         if(stcI2cInfo.u32Count == stcI2cInfo.u32RxSize-1)   
00273         {
00274            Mfs_I2c_ConfigAck(EE_I2C_CH, I2cNAck); /* Last byte send a NACK */
00275         }
00276         
00277         Mfs_I2c_ClrStatus(EE_I2C_CH, I2cRxTxInt);
00278         
00279         stcI2cInfo.u32Count++;
00280     }
00281 }
00282 
00288 static void I2cIntCallback(void)
00289 { 
00290     if(TRUE == Mfs_I2c_GetStatus(EE_I2C_CH, I2cRxTxInt)) 
00291     {  
00292         /* Check error status of I2C */
00293         if(TRUE == I2cCheckErrorStatus())
00294         {
00295             stcI2cInfo.bI2cErrorFlag = 1;
00296             return;
00297         }
00298       
00299         if((stcI2cInfo.enSequence != I2cSeqStart) && (stcI2cInfo.enSequence != I2cSeqRestart)) // In read or write sequence, clear INT at TX/RX callback
00300         {
00301             return;
00302         }
00303         
00304         /* Check ACK */
00305         if(I2cNAck == Mfs_I2c_GetAck(EE_I2C_CH))
00306         {
00307             stcI2cInfo.bI2cErrorFlag = 1;
00308             return;   /* NACK */
00309         }
00310         
00311         if(stcI2cInfo.enSequence == I2cSeqStart) 
00312         {
00313             if(stcI2cInfo.enRwMode == I2cRxMode)
00314             {   
00315                 if(stcI2cInfo.u32Count == stcI2cInfo.u32RxSize-1)   
00316                 {
00317                     Mfs_I2c_ConfigAck(EE_I2C_CH, I2cNAck); /* Last byte send a NACK */
00318                 }
00319                 /* Receive first data here and receive following data at RX callback */
00320                 Mfs_I2c_ClrStatus(EE_I2C_CH, I2cRxTxInt);
00321                 
00322                 stcI2cInfo.u32Count++;
00323                 
00324                 stcI2cInfo.enSequence = I2cSeqRead; // Start read data
00325             }
00326             else
00327             {
00328                 stcI2cInfo.enSequence = I2cSeqWrite; // Start write data
00329             }
00330         }
00331         
00332         if(stcI2cInfo.enSequence == I2cSeqRestart) 
00333         {
00334             if(stcI2cInfo.u32Count == stcI2cInfo.u32RxSize-1)   
00335             {
00336                 Mfs_I2c_ConfigAck(EE_I2C_CH, I2cNAck); /* Last byte send a NACK */
00337             }
00338             /* Receive first data here and receive following data at RX callback */
00339             Mfs_I2c_ClrStatus(EE_I2C_CH, I2cRxTxInt);
00340             
00341             stcI2cInfo.u32Count++;
00342             
00343             stcI2cInfo.enSequence = I2cSeqRead; // Start read data
00344         }
00345     }
00346 }
00347 
00353 static void I2cStopDetectCallback(void)
00354 {
00355     if(TRUE == Mfs_I2c_GetStatus(EE_I2C_CH, I2cStopDetect))
00356     {
00357         Mfs_I2c_ClrStatus(EE_I2C_CH, I2cStopDetect);
00358         Mfs_I2c_ClrStatus(EE_I2C_CH, I2cRxTxInt);
00359         
00360         stcI2cInfo.enSequence = I2cSeqStop;
00361         
00362         PDL_ZERO_STRUCT(stcI2cIntSel);
00363         stcI2cIntSel.bTxInt = TRUE;
00364         stcI2cIntSel.bRxInt = TRUE;
00365         stcI2cIntSel.bTxRxInt = TRUE;
00366         stcI2cIntSel.bStopDetectInt = TRUE;
00367         
00368         Mfs_I2c_DisableInt(EE_I2C_CH, &stcI2cIntSel); // Disable interrupt      
00369     }
00370 }
00371 
00384 static en_result_t I2cTxData(uint8_t u8DevAddr, uint8_t* pu8Data, uint32_t u32Size)
00385 {    
00386     PDL_ZERO_STRUCT(stcI2cIntSel);
00387     PDL_ZERO_STRUCT(stcI2cIntCb);
00388     PDL_ZERO_STRUCT(stcI2cInfo);
00389     
00390     stcI2cInfo.enSequence = I2cSeqStart;
00391     stcI2cInfo.enRwMode = I2cTxMode;
00392     stcI2cInfo.u8DevAddr = u8DevAddr;
00393     stcI2cInfo.pu8TxBuf = pu8Data;
00394     stcI2cInfo.u32TxSize = u32Size;
00395     stcI2cInfo.u32Count = 0;
00396     stcI2cInfo.bI2cErrorFlag = 0;
00397     
00398     stcI2cIntSel.bTxInt = TRUE;
00399     stcI2cIntSel.bTxRxInt = TRUE;
00400     stcI2cIntSel.bStopDetectInt = TRUE;
00401     
00402     stcI2cIntCb.pfnTxIntCb = I2cTxCallback;
00403     stcI2cIntCb.pfnTxRxCb  = I2cIntCallback;
00404     stcI2cIntCb.pfnStopDetectCb = I2cStopDetectCallback;
00405 
00406     if(Ok != Mfs_I2c_EnableInt(EE_I2C_CH, &stcI2cIntSel, &stcI2cIntCb))
00407     {
00408         return Error;
00409     }
00410     
00411     while(stcI2cInfo.enSequence < I2cSeqStop)
00412     {
00413         if(stcI2cInfo.bI2cErrorFlag == 1)
00414         {
00415             return Error;
00416         }
00417     }
00418    
00419     return Ok;
00420 }
00421 
00436 static en_result_t I2cTxRxData(uint8_t u8DevAddr, 
00437                                uint8_t* pu8TxData, 
00438                                uint32_t u32TxSize, 
00439                                uint8_t* pu8RxData, 
00440                                uint32_t u32RxSize)
00441 {
00442     PDL_ZERO_STRUCT(stcI2cIntSel);
00443     PDL_ZERO_STRUCT(stcI2cIntCb);
00444     PDL_ZERO_STRUCT(stcI2cInfo);
00445   
00446     stcI2cInfo.enSequence = I2cSeqStart;
00447     stcI2cInfo.enRwMode = I2cTxRxMode;
00448     stcI2cInfo.u8DevAddr = u8DevAddr;
00449     stcI2cInfo.pu8TxBuf = pu8TxData;
00450     stcI2cInfo.u32TxSize = u32TxSize;
00451     stcI2cInfo.pu8RxBuf = pu8RxData;
00452     stcI2cInfo.u32RxSize = u32RxSize;
00453     stcI2cInfo.u32Count = 0;
00454     stcI2cInfo.bI2cErrorFlag = 0;
00455     stcI2cInfo.u32TxRxGap = SystemCoreClock/(160000);
00456     
00457     stcI2cIntSel.bTxInt = TRUE;
00458     stcI2cIntSel.bRxInt = TRUE;
00459     stcI2cIntSel.bTxRxInt = TRUE;
00460     stcI2cIntSel.bStopDetectInt = TRUE;
00461     
00462     stcI2cIntCb.pfnTxIntCb = I2cTxCallback;
00463     stcI2cIntCb.pfnRxIntCb = I2cRxCallback;
00464     stcI2cIntCb.pfnTxRxCb  = I2cIntCallback;
00465     stcI2cIntCb.pfnStopDetectCb = I2cStopDetectCallback;
00466   
00467     if(Ok != Mfs_I2c_EnableInt(EE_I2C_CH, &stcI2cIntSel, &stcI2cIntCb))
00468     {
00469         return Error;
00470     }
00471     
00472     while(stcI2cInfo.enSequence < I2cSeqStop)
00473     {
00474         if(stcI2cInfo.bI2cErrorFlag == 1)
00475         {
00476             return Error;
00477         }
00478     }
00479     
00480     return Ok;
00481 }
00482 
00495 static en_result_t I2cRxData(uint8_t u8DevAddr, uint8_t* pu8RxData, uint32_t u32RxSize)
00496 {  
00497     PDL_ZERO_STRUCT(stcI2cIntSel);
00498     PDL_ZERO_STRUCT(stcI2cIntCb);
00499     PDL_ZERO_STRUCT(stcI2cInfo);
00500   
00501     stcI2cInfo.enSequence = I2cSeqStart;
00502     stcI2cInfo.enRwMode = I2cRxMode;
00503     stcI2cInfo.u8DevAddr = u8DevAddr;
00504     stcI2cInfo.pu8RxBuf = pu8RxData;
00505     stcI2cInfo.u32RxSize = u32RxSize;
00506     stcI2cInfo.u32Count = 0;
00507     stcI2cInfo.bI2cErrorFlag = 0;
00508     
00509     stcI2cIntSel.bTxInt = TRUE;
00510     stcI2cIntSel.bRxInt = TRUE;
00511     stcI2cIntSel.bTxRxInt = TRUE;
00512     stcI2cIntSel.bStopDetectInt = TRUE;
00513     
00514     stcI2cIntCb.pfnTxIntCb = I2cTxCallback;
00515     stcI2cIntCb.pfnRxIntCb = I2cRxCallback;
00516     stcI2cIntCb.pfnTxRxCb  = I2cIntCallback;
00517     stcI2cIntCb.pfnStopDetectCb = I2cStopDetectCallback;
00518     
00519     if(Ok != Mfs_I2c_EnableInt(EE_I2C_CH, &stcI2cIntSel, &stcI2cIntCb))
00520     {
00521         return Error;
00522     }
00523   
00524     while(stcI2cInfo.enSequence < I2cSeqStop)
00525     {
00526         if(stcI2cInfo.bI2cErrorFlag == 1)
00527         {
00528             return Error;
00529         }
00530     }
00531     
00532     return Ok;
00533 }
00534 
00543 en_result_t At24cxx_Init(void)
00544 {
00545     stc_mfs_i2c_config_t stcI2cConfig;
00546     PDL_ZERO_STRUCT(stcI2cConfig);
00547     
00548     InitI2cIo();
00549     
00550     stcI2cConfig.enMsMode = I2cMaster;
00551     stcI2cConfig.u32BaudRate = 100000u;
00552     stcI2cConfig.bWaitSelection = FALSE;
00553     stcI2cConfig.bDmaEnable = FALSE;
00554     stcI2cConfig.bEnableFifo = FALSE;
00555     
00556     if(Ok != Mfs_I2c_Init(EE_I2C_CH, &stcI2cConfig))
00557     {
00558         return Error;
00559     }
00560     
00561     return Ok;
00562 }
00563 
00576 en_result_t At24cxx_ByteWrite(uint8_t u8DevAddr, uint16_t u16Addr, uint8_t u8Data)
00577 {
00578     uint8_t au8TempData[3];
00579   
00580     /* Send data address */
00581     if(AT24CXX_ADDR_LENGTH == 1)
00582     {
00583         au8TempData[0] = u16Addr & 0x00FFu;
00584         au8TempData[1] = u8Data;
00585     }
00586     else
00587     {
00588         au8TempData[0] = u16Addr & 0x00FFu;
00589         au8TempData[1] = (u16Addr & 0xFF00u) >> 8;
00590         au8TempData[2] = u8Data;
00591     }
00592   
00593     I2cTxData(u8DevAddr, au8TempData, (AT24CXX_ADDR_LENGTH+1));
00594   
00595     return Ok;
00596 }
00597 
00598 
00612 en_result_t At24cxx_PageWrite(uint8_t u8DevAddr, uint16_t u16PageAddr, uint8_t* pu8Data, uint8_t u8Size)
00613 {
00614     uint8_t au8DataBuf[2+AT24CXX_PAGE_SIZE];
00615   
00616     if(u8Size > AT24CXX_PAGE_SIZE)
00617     {
00618         return ErrorInvalidParameter;
00619     }
00620         
00621     if(AT24CXX_ADDR_LENGTH == 1)
00622     {
00623         au8DataBuf[0] = u16PageAddr & 0x00FFu;
00624         memcpy(&au8DataBuf[1], pu8Data, u8Size);
00625     }
00626     else
00627     {
00628         au8DataBuf[0] = u16PageAddr & 0x00FFu;
00629         au8DataBuf[1] = (u16PageAddr & 0xFF00u) >> 8;
00630         memcpy(&au8DataBuf[2], pu8Data, u8Size);
00631     }
00632     
00633     if(Ok != I2cTxData(u8DevAddr, au8DataBuf, (AT24CXX_ADDR_LENGTH+u8Size)))
00634     {
00635         return Error;
00636     }
00637     
00638     return Ok;
00639 }
00640 
00652 en_result_t At24cxx_CurrentAddrRead(uint8_t u8DevAddr, uint8_t* pu8CurData)
00653 {   
00654     if(Ok != I2cRxData(u8DevAddr, pu8CurData, 1))
00655     {
00656         return Error;
00657     }
00658   
00659     return Ok;
00660 }
00661 
00674 en_result_t At24cxx_RandomRead(uint8_t u8DevAddr, uint16_t u16Addr, uint8_t* pu8Data)
00675 {
00676     uint8_t au8TempData[2];
00677 
00678     /* Send address */
00679     if(AT24CXX_ADDR_LENGTH == 1)
00680     {
00681         au8TempData[0] = u16Addr & 0x00FFu;
00682     }
00683     else
00684     {
00685         au8TempData[0] = u16Addr & 0x00FFu;
00686         au8TempData[1] = (u16Addr & 0xFF00u) >> 8;
00687     }
00688     
00689     I2cTxRxData(u8DevAddr, au8TempData, AT24CXX_ADDR_LENGTH, pu8Data, 1);
00690   
00691     return Ok;
00692 }
00693 
00706 en_result_t At24cxx_SequentialRead(uint8_t u8DevAddr, uint8_t* pu8Data, uint8_t u8Size)
00707 {
00708     if(Ok != I2cRxData(u8DevAddr, pu8Data, u8Size))
00709     {
00710         return Error;
00711     }
00712   
00713     return Ok;
00714 }
00715 
00723 void At24cxx_Delayms(uint32_t u32Cnt)
00724 {
00725     uint32_t u32i;
00726     
00727     for(;u32Cnt;u32Cnt--)
00728         for(u32i=SystemCoreClock/12000; u32i; u32i--);
00729 }
00730 
00731 
00732 #endif // if (PDL_UTILITY_ENABLE_I2C_INT_AT24CXX == PDL_ON)
00733 
00734 /******************************************************************************/
00735 /* EOF (not truncated)                                                        */
00736 /******************************************************************************/