/** ****************************************************************************** * @file xl_eeprom.c * @author xu.wang * @version 4.5.2 * @date Fri Mar 26 17:29:12 2021 * @brief This file provide function about EEPROM firmware program ****************************************************************************** * @attention * * 2019 by Chipways Communications,Inc. All Rights Reserved. * This software is supplied under the terms of a license * agreement or non-disclosure agreement with Chipways. * Passing on and copying of this document,and communication * of its contents is not permitted without prior written * authorization. * *

© COPYRIGHT 2019 Chipways

****************************************************************************** */ #if defined(__cplusplus) extern "C" { #endif /* __cplusplus */ /* Includes ---------------------------------------------------------------*/ #include "xl_eeprom.h" /** @addtogroup XL6600_StdPeriph_Driver * @{ */ /** @defgroup EEPROM EEPROM_Module * @brief EEPROM Driver Modules Library * @{ */ /* Private typedef -----------------------------------------------------------*/ /* Private define ------------------------------------------------------------*/ /* Private macro -------------------------------------------------------------*/ /* Private variables ---------------------------------------------------------*/ static Timer_Type sTimer_Type; #if (USER_HARDWARE_OR_SOFTWARE == 0u) static uint8_t I2C_SEND_SPEED_H; static uint8_t I2C_SEND_SPEED_L; static uint8_t I2C_READ_SPEED_H; static uint8_t I2C_READ_SPEED_L; #endif /* Private function prototypes -----------------------------------------------*/ /* Private functions ---------------------------------------------------------*/ static uint8_t EEPROM_Timeout(uint32_t time); /** @defgroup EEPROM_Private_Functions * @{ */ #if (USER_HARDWARE_OR_SOFTWARE == 0u) static void IO_I2C_Start() { uint16_t i; SET_SDA_OUTPUT(); I2C_SDA_H(); I2C_SCK_H(); for(i=0;i<0x1;i++){}; I2C_SDA_L(); for(i=0;i<0x1;i++){}; I2C_SCK_L(); } static void IO_I2C_Stop() { uint16_t i; SET_SDA_OUTPUT(); I2C_SCK_L(); I2C_SDA_L(); for(i=0;i<0x1;i++){}; I2C_SCK_H(); I2C_SDA_H(); for(i=0;i<0x1;i++){}; } static void IO_I2C_Ack() { uint16_t i; I2C_SCK_L(); SET_SDA_OUTPUT(); I2C_SDA_L(); for(i=0;i<0x1;i++){}; I2C_SCK_H(); for(i=0;i<0x1;i++){}; I2C_SCK_L(); } static void IO_I2C_NAck() { uint16_t i; I2C_SCK_L(); SET_SDA_OUTPUT(); I2C_SDA_H(); for(i=0;i<0x1;i++){}; I2C_SCK_H(); for(i=0;i<0x1;i++){}; I2C_SCK_L(); } static uint8_t IO_I2C_WaitAck(uint32_t time) { uint8_t timeflag = 0; sTimer_Type.timer_cnt = time; SET_SDA_OUTPUT(); I2C_SDA_H(); I2C_SCK_H(); SET_SDA_INPUT(); while(GPIO_ReadPin(GPIO_PTH3)) { if(EEPROM_Timeout(time) == 1u) { timeflag = 1; SET_SDA_OUTPUT(); IO_I2C_Stop(); break; } } if(0 == timeflag) { I2C_SCK_L(); SET_SDA_OUTPUT(); } return timeflag; } static void IO_I2C_Send_Byte(uint8_t data) { uint16_t i; SET_SDA_OUTPUT(); //send bit7 if(data & 0x80) { I2C_SDA_H(); } else { I2C_SDA_L(); } I2C_SCK_H(); for(i=0;i> 1u; I2C_InitStructure.I2C_SpeedMode = I2C_StandardMode;//I2C_FastMode I2C_StandardMode I2C_InitStructure.I2C_SendRestart = I2C_SendRestartDisabled; I2C_EnableCmd(I2C1, DISABLE ); I2C_Init(I2C1, &I2C_InitStructure); I2C_InterruptEn(I2C1 ,I2C_TXEMPTYInterrupt ,DISABLE ); I2C_InterruptEn(I2C1 ,I2C_RXFULLInterrupt ,DISABLE); I2C_EnableCmd(I2C1, ENABLE); #else GPIO_SetPinDir(GPIO_PTH3,GPIO_Direction_Output);//SDA GPIO_SetPinDir(GPIO_PTH4,GPIO_Direction_Output);//SCK PORT_PullPinCmd(PORT_PTH3,ENABLE); PORT_PullPinCmd(PORT_PTH4,ENABLE); switch(systemclk) { case 64000000: I2C_SEND_SPEED_H = 0x07; I2C_SEND_SPEED_L = 0x02; I2C_READ_SPEED_H = 0x02; I2C_READ_SPEED_L = 0x02; break; case 72000000: I2C_SEND_SPEED_H = 0x08; I2C_SEND_SPEED_L = 0x03; I2C_READ_SPEED_H = 0x02; I2C_READ_SPEED_L = 0x03; break; case 96000000: I2C_SEND_SPEED_H = 0x0C; I2C_SEND_SPEED_L = 0x07; I2C_READ_SPEED_H = 0x05; I2C_READ_SPEED_L = 0x07; break; case 60000000: I2C_SEND_SPEED_H = 0x08; I2C_SEND_SPEED_L = 0x04; I2C_READ_SPEED_H = 0x02; I2C_READ_SPEED_L = 0x02; break; case 90000000: I2C_SEND_SPEED_H = 0x0E; I2C_SEND_SPEED_L = 0x09; I2C_READ_SPEED_H = 0x04; I2C_READ_SPEED_L = 0x04; break; default: I2C_SEND_SPEED_H = 0x07; I2C_SEND_SPEED_L = 0x02; I2C_READ_SPEED_H = 0x02; I2C_READ_SPEED_L = 0x02; break; } #endif } /** * @brief EEPROM»Ø¸´Î´³õʼ»¯×´Ì¬ºÍ¹Ø±Õ¹¦ÄÜ * @param None * @retval None */ void EEPROM_DeInit(void) { #if (USER_HARDWARE_OR_SOFTWARE == 1u) I2C_InterruptEn(I2C1 ,I2C_TXEMPTYInterrupt ,DISABLE ); I2C_InterruptEn(I2C1 ,I2C_RXFULLInterrupt ,DISABLE); I2C_EnableCmd(I2C1, DISABLE); SIM_SCGC_Cmd(SIM_SCGC_I2C1, DISABLE); PORT_PullPinCmd(PORT_PTH4, DISABLE); PORT_PullPinCmd(PORT_PTH3, DISABLE); #endif } /** * @brief EEPROMд±£»¤ * @param NewState£ºENABLE£º´ò¿ªÐ´±£»¤£¬²»ÄÜдÈëÊý¾Ý£¬Ö»ÄܶÁ¡£DISABLE£º¹Ø±Õд±£»¤£¬ÄÜдÈëÊý¾Ý * @retval None */ void EEPROM_WriteProtectEn(FunctionalState NewState) { if(NewState == ENABLE) { GPIO_SetPin(GPIO_PTE4); } else { GPIO_ClrPin(GPIO_PTE4); } } static uint8_t EEPROM_Timeout(uint32_t time) { uint8_t ret; if((sTimer_Type.timer_cnt<10u)||(sTimer_Type.timer_cnt>time)) { ret = 1u; } else { sTimer_Type.timer_cnt--; ret = 0u; } return ret; } /** * @brief EEPROMдһ¸ö×Ö½ÚÊý¾Ý * @param address£ºÐ´ÈëµÄµØÖ· * @param data£ºÐ´ÈëµÄÊý¾Ý * @param time£º³¬Ê±Ê±¼ä (time>20) * @retval д״̬ */ uint8_t EEPROM_WriteByte(uint32_t address,uint8_t data,uint32_t time) { EEPROM_Status status; uint32_t add ; status = EEPROM_OK; add = address - EEPROM_BASE_ADDRESS; #if (USER_HARDWARE_OR_SOFTWARE == 1u) sTimer_Type.timer_cnt = time; while((uint8_t)0 == I2C_GetStatus(I2C1 ,I2C_TransmitFIFOEmptyStatus)) { if(1u == EEPROM_Timeout(time)) { status = EEPROM_ADDRESS_TIMEOUT; break; } } if(status != EEPROM_ADDRESS_TIMEOUT) { I2C1->DBC = (uint32_t)((add>>8)&0x000000FFu); sTimer_Type.timer_cnt = time; while((uint8_t)0 == I2C_GetStatus(I2C1 ,I2C_TransmitFIFOEmptyStatus)) { if(1u == EEPROM_Timeout(time)) { status = EEPROM_ADDRESS_TIMEOUT; break; } } if(status != EEPROM_ADDRESS_TIMEOUT) { I2C1->DBC = (uint8_t)add; sTimer_Type.timer_cnt = time; while((uint8_t)0 == I2C_GetStatus(I2C1 ,I2C_TransmitFIFOEmptyStatus)) { if(1u == EEPROM_Timeout(time)) { status = EEPROM_DATA_TIMEOUT; break; } } if(status != EEPROM_ADDRESS_TIMEOUT) { I2C1->DBC = ((uint32_t)data | I2C_DBC_STOP_MASK); } } } #else IO_I2C_Start(); IO_I2C_Send_Byte(0xA0); if( 1u == IO_I2C_WaitAck(time)) { status = EEPROM_SlaveID_TIMEOUT; } else { IO_I2C_Send_Byte(add>>8); if( 1u == IO_I2C_WaitAck(time)) { status = EEPROM_ADDRESS_TIMEOUT; } else { IO_I2C_Send_Byte(add); if( 1u == IO_I2C_WaitAck(time)) { status = EEPROM_ADDRESS_TIMEOUT; } else { IO_I2C_Send_Byte(data); if( 1u == IO_I2C_WaitAck(time)) { status = EEPROM_DATA_TIMEOUT; } else { IO_I2C_Stop(); } } } } #endif return (uint8_t)status; } /** * @brief EEPROMдbuffÊý¾Ý£¬ * @param address£ºÐ´ÈëµÄµØÖ· * @param *data£ºÐ´ÈëµÄÊý¾ÝµÄÊ×µØÖ· * @param *lenght£ºÊý¾Ý³¤¶È£¬²»Äܳ¬¹ý64×Ö½Ú * @param time£º³¬Ê±Ê±¼ä (time>20) * @retval д״̬ */ EEPROM_Status EEPROM_WriteBuff(uint32_t address,const uint8_t *data,uint8_t lenght,uint32_t time) { uint8_t i=0; EEPROM_Status status = EEPROM_OK; uint32_t add = address - EEPROM_BASE_ADDRESS; #if (USER_HARDWARE_OR_SOFTWARE == 1u) sTimer_Type.timer_cnt = time; while(0u == I2C_GetStatus(I2C1 ,I2C_TransmitFIFOEmptyStatus)) { if(EEPROM_Timeout(time) == 1u) { status = EEPROM_ADDRESS_TIMEOUT; break; } } if(status != EEPROM_ADDRESS_TIMEOUT) { I2C1->DBC = (uint32_t)(add>>8); sTimer_Type.timer_cnt = time; while(0u == I2C_GetStatus(I2C1 ,I2C_TransmitFIFOEmptyStatus)) { if(1u == EEPROM_Timeout(time)) { status = EEPROM_ADDRESS_TIMEOUT; break; } } if(status != EEPROM_ADDRESS_TIMEOUT) { I2C1->DBC = (uint8_t)add; for(i=0; iDBC = data[i]; } } else { if(status != EEPROM_ADDRESS_TIMEOUT) { sTimer_Type.timer_cnt = time; while(0u == I2C_GetStatus(I2C1 ,I2C_TransmitFIFOEmptyStatus)) { if(1u == EEPROM_Timeout(time)) { status = EEPROM_DATA_TIMEOUT; break; } } I2C1->DBC = ((uint32_t)data[i]| I2C_DBC_STOP_MASK); } } } } } #else IO_I2C_Start(); IO_I2C_Send_Byte(0xA0); if( 1u == IO_I2C_WaitAck(time)) { status = EEPROM_SlaveID_TIMEOUT; } else { IO_I2C_Send_Byte(add>>8); if( 1u == IO_I2C_WaitAck(time)) { status = EEPROM_ADDRESS_TIMEOUT; } else { IO_I2C_Send_Byte(add); if( 1u == IO_I2C_WaitAck(time)) { status = EEPROM_ADDRESS_TIMEOUT; } else { for(i=0; i= lenght-1u) IO_I2C_Stop(); } } } } } #endif return status; } /** * @brief EEPROMдһҳÊý¾Ý,Ò³Êý¾Ý´óС64byte * @param address£ºÐ´ÈëµÄµØÖ· * @param *data£ºÐ´ÈëµÄÊý¾ÝµÄÊ×µØÖ· * @param time£º³¬Ê±Ê±¼ä (time>20) * @retval д״̬ */ EEPROM_Status EEPROM_WritePage(uint8_t page,const uint8_t *data,uint32_t time) { uint8_t i=0; EEPROM_Status status = EEPROM_OK; uint32_t add = (uint32_t)page*64u; #if (USER_HARDWARE_OR_SOFTWARE == 1u) sTimer_Type.timer_cnt = time; while(0u == I2C_GetStatus(I2C1 ,I2C_TransmitFIFOEmptyStatus)) { if(1u == EEPROM_Timeout(time)) { status = EEPROM_ADDRESS_TIMEOUT; break; } } if(status != EEPROM_ADDRESS_TIMEOUT) { I2C1->DBC = (uint32_t)(add>>8u); sTimer_Type.timer_cnt = time; while(0u == I2C_GetStatus(I2C1 ,I2C_TransmitFIFOEmptyStatus)) { if(1u == EEPROM_Timeout(time)) { status = EEPROM_ADDRESS_TIMEOUT; break; } } if(status != EEPROM_ADDRESS_TIMEOUT) { I2C1->DBC = (uint8_t)add; for(i=0; i<64u; i++) { if(i < (64u-1u)) { if(status != EEPROM_ADDRESS_TIMEOUT) { sTimer_Type.timer_cnt = time; while(0u == I2C_GetStatus(I2C1 ,I2C_TransmitFIFOEmptyStatus)) { if(1u == EEPROM_Timeout(time)) { status = EEPROM_DATA_TIMEOUT; break; } } I2C1->DBC = data[i];// } } else { if(status != EEPROM_ADDRESS_TIMEOUT) { sTimer_Type.timer_cnt = time; while(0u == I2C_GetStatus(I2C1 ,I2C_TransmitFIFOEmptyStatus)) { if(1u == EEPROM_Timeout(time)) { status = EEPROM_DATA_TIMEOUT; break; } } I2C1->DBC = ((uint32_t)data[i]| I2C_DBC_STOP_MASK); } } } } } #else IO_I2C_Start(); IO_I2C_Send_Byte(0xA0); if( 1u == IO_I2C_WaitAck(time)) { status = EEPROM_SlaveID_TIMEOUT; } else { IO_I2C_Send_Byte(add>>8); if( 1u == IO_I2C_WaitAck(time)) { status = EEPROM_ADDRESS_TIMEOUT; } else { IO_I2C_Send_Byte(add); if( 1u == IO_I2C_WaitAck(time)) { status = EEPROM_ADDRESS_TIMEOUT; } else { for(i=0; i<64; i++) { IO_I2C_Send_Byte(data[i]); if( 1u == IO_I2C_WaitAck(time)) { status = EEPROM_DATA_TIMEOUT; break; } else { if(i >= 64-1u) IO_I2C_Stop(); } } } } } #endif return status; } /** * @brief EEPROM¶ÁÒ»¸ö×Ö½Ú * @param address£º¶ÁÊý¾ÝµÄµØÖ· * @param data£ºÐ´ÈëµÄÊý¾Ý * @param time£º³¬Ê±Ê±¼ä (time>20) * @retval ¶Á״̬ */ EEPROM_Status EEPROM_ReadByte(uint32_t address,uint8_t *data,uint32_t time) { EEPROM_Status status = EEPROM_OK; uint32_t add = address - EEPROM_BASE_ADDRESS; #if (USER_HARDWARE_OR_SOFTWARE == 1u) sTimer_Type.timer_cnt = time; while(0u == I2C_GetStatus(I2C1 ,I2C_TransmitFIFOEmptyStatus)) { if(1u == EEPROM_Timeout(time)) { status = EEPROM_ADDRESS_TIMEOUT; break; } } if(status != EEPROM_ADDRESS_TIMEOUT) { I2C1->DBC = (uint32_t)(add>>8u); sTimer_Type.timer_cnt = time; while(0u == I2C_GetStatus(I2C1 ,I2C_TransmitFIFOEmptyStatus)) { if(1u == EEPROM_Timeout(time)) { status = EEPROM_ADDRESS_TIMEOUT; break; } } if(status != EEPROM_ADDRESS_TIMEOUT) { I2C1->DBC = ((uint32_t)add|I2C_DBC_STOP_MASK); I2C1->DBC |= I2C_DBC_CMD_MASK|I2C_DBC_STOP_MASK; sTimer_Type.timer_cnt = time; while(0u == I2C_GetStatus(I2C1 ,I2C_ReceiveFIFONotEmptyStatus)) { if(1u == EEPROM_Timeout(time)) { status = EEPROM_DATA_TIMEOUT; break; } } *data = (uint8_t)(I2C1->DBC); } } #else IO_I2C_Start(); IO_I2C_Send_Byte(0xA0); if( 1u == IO_I2C_WaitAck(time)) { status = EEPROM_SlaveID_TIMEOUT; } else { IO_I2C_Send_Byte(add>>8); if( 1u == IO_I2C_WaitAck(time)) { status = EEPROM_ADDRESS_TIMEOUT; } else { IO_I2C_Send_Byte(add); if( 1u == IO_I2C_WaitAck(time)) { status = EEPROM_ADDRESS_TIMEOUT; } else { IO_I2C_Start(); IO_I2C_Send_Byte(0xA1); if( 1u == IO_I2C_WaitAck(time)) { status = EEPROM_SlaveID_TIMEOUT; } else { *data = IO_I2C_Read_Byte(0); IO_I2C_Stop(); } } } } #endif return status; } /** * @brief EEPROM¶ÁBUFFÊý¾Ý * @param address£ºÐ´ÈëµÄµØÖ· * @param *data£º¶ÁÈëµÄÊý¾ÝÊ×µØÖ· * @param *data£º¶ÁÈëµÄÊý¾ÝµÄ³¤¶È * @param time£º³¬Ê±Ê±¼ä (time>20) * @retval д״̬ */ EEPROM_Status EEPROM_ReadBuff(uint32_t address,uint8_t *data,uint16_t lenght,uint32_t time) { uint8_t i=0; EEPROM_Status status = EEPROM_OK; uint32_t add = address - EEPROM_BASE_ADDRESS; #if (USER_HARDWARE_OR_SOFTWARE == 1u) sTimer_Type.timer_cnt = time; while(0u == I2C_GetStatus(I2C1 ,I2C_TransmitFIFOEmptyStatus)) { if(1u == EEPROM_Timeout(time)) { status = EEPROM_ADDRESS_TIMEOUT; break; } } if(status != EEPROM_ADDRESS_TIMEOUT) { I2C1->DBC = (uint32_t)(add>>8u); sTimer_Type.timer_cnt = time; while(0u == I2C_GetStatus(I2C1 ,I2C_TransmitFIFOEmptyStatus)) { if(1u == EEPROM_Timeout(time)) { status = EEPROM_ADDRESS_TIMEOUT; break; } } if(status != EEPROM_ADDRESS_TIMEOUT) { I2C1->DBC = ((uint32_t)(add&0xFFu)|I2C_DBC_STOP_MASK); I2C1->DBC |= I2C_DBC_CMD_MASK; while(i < lenght) { if(i< (lenght-1u)) { if(status != EEPROM_ADDRESS_TIMEOUT) { I2C1->DBC |= I2C_DBC_CMD_MASK; sTimer_Type.timer_cnt = time; while(0u == I2C_GetStatus(I2C1 ,I2C_ReceiveFIFONotEmptyStatus)) { if(1u == EEPROM_Timeout(time)) { status = EEPROM_DATA_TIMEOUT; break; } } data[i] = (uint8_t)(I2C1->DBC); i++; } } else if(i< lenght) { if(status != EEPROM_ADDRESS_TIMEOUT) { I2C1->DBC |= (I2C_DBC_CMD_MASK|I2C_DBC_STOP_MASK); sTimer_Type.timer_cnt = time; while(0u == I2C_GetStatus(I2C1 ,I2C_ReceiveFIFONotEmptyStatus)) { if(1u == EEPROM_Timeout(time)) { status = EEPROM_DATA_TIMEOUT; break; } } data[i] = (uint8_t)(I2C1->DBC); i++; } } else { break; } } } } #else IO_I2C_Start(); IO_I2C_Send_Byte(0xA0); if( 1u == IO_I2C_WaitAck(time)) { status = EEPROM_SlaveID_TIMEOUT; } else { IO_I2C_Send_Byte(add>>8); if( 1u == IO_I2C_WaitAck(time)) { status = EEPROM_ADDRESS_TIMEOUT; } else { IO_I2C_Send_Byte(add); if( 1u == IO_I2C_WaitAck(time)) { status = EEPROM_ADDRESS_TIMEOUT; } else { IO_I2C_Start(); IO_I2C_Send_Byte(0xA1); if( 1u == IO_I2C_WaitAck(time)) { status = EEPROM_SlaveID_TIMEOUT; } else { for(i=0; i