#include "EEPROM_24Cxx_Remap.h" EEPROMDataWrCtrlStruct EEPROMDataWrCtrl; EEPROMAccessStatusEnum EEPROM_Data_Write ( uint8_t Type, uint16_t Addr, uint8_t *pData, uint8_t Len ) { if ( EEPROMDataWrCtrl.Busy ) //����������д����,����д��ʧ�� return EEPROM_DATA_RW_FAIL; switch ( Type ) { case EEPROM_HIREL_DATA_TYPE : return EEPROM_HiRel_Data_Write ( Addr, pData, Len ); break; case EEPROM_EXTLIFE_DATA_TYPE : return EEPROM_DATA_RW_FAIL; break; case EEPROM_NORMAL_DATA_TYPE : return EEPROM_Normal_Data_Write ( Addr, pData, Len ); break; default : return EEPROM_DATA_RW_FAIL; break; } } EEPROMAccessStatusEnum EEPROM_Get_Data_Write_Status ( void ) { return EEPROMDataWrCtrl.Result; } EEPROMAccessStatusEnum EEPROM_Startup_Data_Read ( uint8_t Type, uint16_t Addr, uint8_t *pData, uint8_t Len ) { switch ( Type ) { case EEPROM_HIREL_DATA_TYPE : return EEPROM_Startup_HiRel_Data_Read ( Addr, pData, Len ); break; case EEPROM_EXTLIFE_DATA_TYPE : return EEPROM_DATA_RW_FAIL; break; case EEPROM_NORMAL_DATA_TYPE : return EEPROM_Startup_Normal_Data_Read ( Addr, pData, Len ); break; default : return EEPROM_DATA_RW_FAIL; break; } } void EEPROM_Access_Service ( void ) { //д����� if ( EEPROMDataWrCtrl.Busy ) { switch ( EEPROMDataWrCtrl.Type ) { case EEPROM_HIREL_DATA_TYPE : EEPROM_HiRel_Data_Write_Service(); break; case EEPROM_EXTLIFE_DATA_TYPE : break; case EEPROM_NORMAL_DATA_TYPE : EEPROM_Normal_Data_Write_Service(); break; default : break; } } //�������� } /****************************************************************************** HiRel�������ݶ�д ******************************************************************************/ EEPROMAccessStatusEnum EEPROM_HiRel_Data_Write ( uint16_t Addr, uint8_t *pData, uint8_t Len ) { uint8_t i; if ( Addr >= EEPPROM_HIREL_DATA_NUM ) return EEPROM_DATA_ADDR_ERR; if ( ( Len == 0 ) || ( Len > EEPPROM_HIREL_DATA_MAX_LEN ) ) return EEPROM_DATA_LEN_ERR; EEPROMDataWrCtrl.Type = EEPROM_HIREL_DATA_TYPE; for ( i = 0; i < Len; i++ ) { EEPROMDataWrCtrl.Data[i] = pData[i]; EEPROMDataWrCtrl.Data[Len + i] = ~pData[i]; } EEPROMDataWrCtrl.DataLen = Len * 2; EEPROMDataWrCtrl.Row = ( uint8_t ) Addr; EEPROMDataWrCtrl.Col = 1; //0�б�����ʹ�� EEPROMDataWrCtrl.Offset = 0; EEPROMDataWrCtrl.Retry = 3; //ÿҳ�������д������ EEPROMDataWrCtrl.WrLen = 0; EEPROMDataWrCtrl.WrCnt = 0; //����ɹ�д����� EEPROMDataWrCtrl.Busy = 1; EEPROMDataWrCtrl.Result = EEPROM_MEMORY_BUSY; return EEPROM_DATA_OK; } EEPROMAccessStatusEnum EEPROM_Startup_HiRel_Data_Read ( uint16_t Addr, uint8_t *pData, uint8_t Len ) { uint8_t Row; uint8_t Col; uint8_t ValidDataCnt; uint8_t Data[EEPPROM_HIREL_DATA_MAX_LEN]; EEPROMAccessStatusEnum Result; if ( Addr >= EEPPROM_HIREL_DATA_NUM ) return EEPROM_DATA_ADDR_ERR; if ( ( Len == 0 ) || ( Len > EEPPROM_HIREL_DATA_MAX_LEN ) ) return EEPROM_DATA_LEN_ERR; Row = ( uint8_t ) Addr; ValidDataCnt = 0; //��δ�յ�����Ч���� for ( Col = 1; Col <= 3; Col++ ) //д��˳��ΪCol1 -> Col3, Col1�н����п��������µ�����(����д������жϵ�����) { Result = EEPROM_Startup_HiRel_Page_Read ( Row, Col, Data, Len ); if ( Result == EEPROM_DATA_OK ) //��������Ч������ { if ( ValidDataCnt == 0 ) //������ǵ�һ�ζ�����Ч������ { EEPROM_Copy_Data ( pData, Data, Len ); //������������� ValidDataCnt++; //�յ���Ч������ } else //����Ѿ��յ�����Ч������ { if ( EEPROM_Compare_Data ( Data, pData, Len ) == 0 ) ValidDataCnt++; } } else if ( ( Result == EEPROM_MEMORY_ABSENT ) || ( Result == EEPROM_DATA_ADDR_ERR ) || ( Result == EEPROM_DATA_LEN_ERR ) ) return Result; //�쳣״̬��ֱ�ӷ��� } if ( ValidDataCnt == 3 ) return EEPROM_DATA_OK; else if ( ( ValidDataCnt == 2 ) || ( ValidDataCnt == 1 ) ) return EEPROM_DATA_PARTIAL_LOST; else return EEPROM_DATA_LOST; } EEPROMAccessStatusEnum EEPROM_Startup_HiRel_Page_Read ( uint8_t Row, uint8_t Col, uint8_t *pData, uint8_t Len ) { uint8_t ReadCnt; uint8_t RetryCnt; uint8_t NVMAbsentCnt; uint8_t PageData[EEPROM_PAGE_SIZE]; uint16_t PhyAddr; EEPROMErrEnum ReadResult; RetryCnt = 3; //�������3�� NVMAbsentCnt = 0; //����洢��δ���Ӽ��� PhyAddr = ( EEPPROM_TOTAL_ROW_NUM * Col + Row ) * EEPROM_PAGE_SIZE; while ( RetryCnt ) { RetryCnt--; ReadCnt = 255; //���Զ�ȡ�������255�� while ( ReadCnt ) { ReadResult = EEPROM_Instant_Sequential_Read ( EEPPROM_DEVICE_ADDR, PhyAddr, PageData, Len * 2 ); if ( ReadResult == EEPROM_OK ) break; else if ( ( ReadResult == EEPROM_INVALID_DEVICE_ADDR ) || ( ReadResult == EEPROM_INVALID_DATA_ADDR ) ) return EEPROM_DATA_ADDR_ERR; else if ( ReadResult == EEPROM_DATA_LENGTH_ERR ) return EEPROM_DATA_LEN_ERR; ReadCnt--; } if ( ReadResult == EEPROM_OK ) //�ɹ��Ӵ洢���ж��������� { if ( EEPROM_HiRel_Data_Check ( PageData, Len ) == 0 ) { EEPROM_Copy_Data ( pData, PageData, Len ); return EEPROM_DATA_OK; //����������ͨ����У��,�����ش����� } } else //255�����Զ�δ�ܴӴ洢���ж������� NVMAbsentCnt++; } if ( NVMAbsentCnt >= 3 ) //3�����Զ�û���Ӵ洢���ж������� return EEPROM_MEMORY_ABSENT; //����Ϊ�洢������Ӳ������ else return EEPROM_DATA_RW_FAIL; //������Ϊ�洢���ڵ������쳣 } uint8_t EEPROM_HiRel_Data_Check ( uint8_t *pData, uint8_t Len ) { uint8_t i; for ( i = 0; i < Len; i++ ) { if ( pData[i] + pData[Len + i] != 0xFF ) return 1; } return 0; } void EEPROM_HiRel_Data_Write_Service ( void ) { uint16_t PhyAddr; EEPROMErrEnum WriteErr; EEPROMRWResultEnum WriteResult; if ( EEPROMDataWrCtrl.Busy > 1 ) //�����״�д�� { WriteResult = EEPROM_Get_Write_Result(); switch ( WriteResult ) { case EEPROM_RW_NONE : //������������д�뷢��ʧ�ܻ�д����������Ӧ�ýػ������ȷ���д��״̬,�ж�д�� EEPROMDataWrCtrl.Busy = 0; EEPROMDataWrCtrl.Result = EEPROM_DATA_RW_FAIL; return; break; case EEPROM_RW_DONE : //д��ɹ� EEPROMDataWrCtrl.WrCnt++; //�ɹ�д��һҳ EEPROMDataWrCtrl.Col++; //д��һ�� EEPROMDataWrCtrl.Retry = 3; //ÿҳ�������д������ if ( EEPROMDataWrCtrl.Col > 3 ) //3��ȫ��д�� { EEPROMDataWrCtrl.Busy = 0; //д����� if ( EEPROMDataWrCtrl.WrCnt == 3 ) //3ҳȫ��д��ɹ�,���ݳɹ�д�� EEPROMDataWrCtrl.Result = EEPROM_DATA_OK; else //�������ݲ���д��ʧ�� EEPROMDataWrCtrl.Result = EEPROM_DATA_PARTIAL_LOST; return; } break; case EEPROM_RW_FAIL : //д��ʧ�� EEPROMDataWrCtrl.Retry--; if ( EEPROMDataWrCtrl.Retry == 0 ) //����3����Ȼδ�ܳɹ�д�� { EEPROMDataWrCtrl.Col++; //����д��һ�� EEPROMDataWrCtrl.Retry = 3; //ÿҳ�������д������ if ( EEPROMDataWrCtrl.Col > 3 ) //3��ȫ��д�� { EEPROMDataWrCtrl.Busy = 0; //д����� if ( EEPROMDataWrCtrl.WrCnt == 0 ) //3ҳȫ��д��ʧ��,��������д��ʧ�� EEPROMDataWrCtrl.Result = EEPROM_DATA_RW_FAIL; else //�������ݲ���д��ʧ�� EEPROMDataWrCtrl.Result = EEPROM_DATA_PARTIAL_LOST; return; } } break; case EEPROM_RW_IN_PROGRESS : //ǰһ��д����δ���,�����ȴ� return; break; default : EEPROMDataWrCtrl.Busy = 0; EEPROMDataWrCtrl.Result = EEPROM_DATA_RW_FAIL; return; break; } } PhyAddr = ( EEPPROM_TOTAL_ROW_NUM * EEPROMDataWrCtrl.Col + EEPROMDataWrCtrl.Row ) * EEPROM_PAGE_SIZE; WriteErr = EEPROM_Page_Write ( EEPPROM_DEVICE_ADDR, PhyAddr, EEPROMDataWrCtrl.Data, ( uint8_t ) ( EEPROMDataWrCtrl.DataLen ) ); EEPROMDataWrCtrl.Busy = 2; if ( WriteErr != EEPROM_OK ) { EEPROMDataWrCtrl.Busy = 0; //��ֹд�벢������� if ( ( WriteErr == EEPROM_INVALID_DEVICE_ADDR ) || ( WriteErr == EEPROM_INVALID_DATA_ADDR ) ) EEPROMDataWrCtrl.Result = EEPROM_DATA_ADDR_ERR; else if ( WriteErr == EEPROM_DATA_LENGTH_ERR ) EEPROMDataWrCtrl.Result = EEPROM_DATA_LEN_ERR; else EEPROMDataWrCtrl.Result = EEPROM_DATA_RW_FAIL; } } /****************************************************************************** ExtLife�������ݶ�д ******************************************************************************/ /****************************************************************************** Normal�������ݶ�д ******************************************************************************/ EEPROMAccessStatusEnum EEPROM_Normal_Data_Write ( uint16_t Addr, uint8_t *pData, uint16_t Len ) { uint8_t i; uint16_t PageNum; if ( Addr > EEPPROM_DATA_MAX_ADDR ) return EEPROM_DATA_ADDR_ERR; if ( ( Len == 0 ) || ( Len > EEPPROM_DATA_MAX_ADDR - Addr + 1 ) ) return EEPROM_DATA_LEN_ERR; EEPROMDataWrCtrl.Type = EEPROM_NORMAL_DATA_TYPE; for ( i = 0; i < Len; i++ ) { EEPROMDataWrCtrl.Data[i] = pData[i]; } EEPROMDataWrCtrl.DataLen = Len; PageNum = Addr / EEPROM_PAGE_SIZE; EEPROMDataWrCtrl.Row = ( uint8_t ) ( PageNum / 4 ) + EEPPROM_DATA_ROW_OFFSEET; EEPROMDataWrCtrl.Col = ( uint8_t ) ( PageNum % 4 ); EEPROMDataWrCtrl.Offset = ( uint8_t ) ( Addr % EEPROM_PAGE_SIZE ); EEPROMDataWrCtrl.Retry = 3; //ÿҳ�������д������ EEPROMDataWrCtrl.WrLen = 0; EEPROMDataWrCtrl.WrCnt = 0; //����ɹ�д����� EEPROMDataWrCtrl.Busy = 1; EEPROMDataWrCtrl.Result = EEPROM_MEMORY_BUSY; return EEPROM_DATA_OK; } EEPROMAccessStatusEnum EEPROM_Startup_Normal_Data_Read ( uint16_t Addr, uint8_t *pData, uint8_t Len ) { uint8_t Row; uint8_t Col; uint8_t Offset; uint16_t PageNum; uint16_t RemLen; //ʣ��δ��ȡ���� uint8_t RetryCnt; //���Դ��� uint16_t PhyAddr; //�洢��������ַ uint8_t CurrentLen; //��ǰ���ζ�ȡ���� EEPROMErrEnum ReadResult; if ( Addr > EEPPROM_DATA_MAX_ADDR ) return EEPROM_DATA_ADDR_ERR; if ( ( Len == 0 ) || ( Len > EEPPROM_DATA_MAX_ADDR - Addr + 1 ) ) return EEPROM_DATA_LEN_ERR; RemLen = Len; PageNum = Addr / EEPROM_PAGE_SIZE; Row = ( uint8_t ) ( PageNum / 4 ) + EEPPROM_DATA_ROW_OFFSEET; Col = ( uint8_t ) ( PageNum % 4 ); Offset = ( uint8_t ) ( Addr % EEPROM_PAGE_SIZE ); while ( RemLen ) { PhyAddr = ( EEPPROM_TOTAL_ROW_NUM * Col + Row ) * EEPROM_PAGE_SIZE + Offset; CurrentLen = EEPROM_PAGE_SIZE - Offset; //ÿ������ȡһҳ RetryCnt = 3; //ÿ��Page������Զ�ȡ3�� if ( CurrentLen > RemLen ) //���һҳ,ʣ��Ĵ���ȡ�ֽ�������һҳ CurrentLen = ( uint8_t ) RemLen; while ( RetryCnt ) { ReadResult = EEPROM_Instant_Sequential_Read ( EEPPROM_DEVICE_ADDR, PhyAddr, &pData[Len - RemLen], CurrentLen ); if ( ReadResult == EEPROM_OK ) break; else if ( ( ReadResult == EEPROM_INVALID_DEVICE_ADDR ) || ( ReadResult == EEPROM_INVALID_DATA_ADDR ) ) return EEPROM_DATA_ADDR_ERR; else if ( ReadResult == EEPROM_DATA_LENGTH_ERR ) return EEPROM_DATA_LEN_ERR; RetryCnt--; } if ( ReadResult != EEPROM_OK ) //3�ζ�δ�ܳɹ��Ӵ洢���ж������� return EEPROM_DATA_RW_FAIL; Offset = 0; //Offsetֻ���ڵ�����ҳƫ���� Col++; //ת����һҳ if ( Col > 3 ) { Col = 0; Row++; } RemLen -= CurrentLen; //�۳��Ѷ�ȡ�ֽ��� } return EEPROM_DATA_OK; } void EEPROM_Normal_Data_Write_Service ( void ) { uint16_t PhyAddr; EEPROMErrEnum WriteErr; EEPROMRWResultEnum WriteResult; if ( EEPROMDataWrCtrl.Busy > 1 ) //�����״�д�� { WriteResult = EEPROM_Get_Write_Result(); switch ( WriteResult ) { case EEPROM_RW_NONE : //������������д�뷢��ʧ�ܻ�д����������Ӧ�ýػ������ȷ���д��״̬,�ж�д�� EEPROMDataWrCtrl.Busy = 0; EEPROMDataWrCtrl.Result = EEPROM_DATA_RW_FAIL; return; break; case EEPROM_RW_DONE : //д��ɹ� EEPROMDataWrCtrl.Offset = 0; //Offsetֻ���ڵ�����ҳƫ���� EEPROMDataWrCtrl.Col++; //ת����һҳ if ( EEPROMDataWrCtrl.Col > 3 ) { EEPROMDataWrCtrl.Col = 0; EEPROMDataWrCtrl.Row++; } EEPROMDataWrCtrl.WrCnt += EEPROMDataWrCtrl.WrLen; EEPROMDataWrCtrl.Retry = 3; //ÿҳ�������д������ if ( EEPROMDataWrCtrl.WrCnt >= EEPROMDataWrCtrl.DataLen ) { EEPROMDataWrCtrl.Busy = 0; //д����� EEPROMDataWrCtrl.Result = EEPROM_DATA_OK; return; } break; case EEPROM_RW_FAIL : //д��ʧ�� EEPROMDataWrCtrl.Retry--; if ( EEPROMDataWrCtrl.Retry == 0 ) //����3����Ȼδ�ܳɹ�д�� { EEPROMDataWrCtrl.Busy = 0; //��ֹд�벢����д��ʧ�� EEPROMDataWrCtrl.Result = EEPROM_DATA_RW_FAIL; return; } break; case EEPROM_RW_IN_PROGRESS : //ǰһ��д����δ���,�����ȴ� return; break; default : EEPROMDataWrCtrl.Busy = 0; EEPROMDataWrCtrl.Result = EEPROM_DATA_RW_FAIL; return; break; } } PhyAddr = ( EEPPROM_TOTAL_ROW_NUM * EEPROMDataWrCtrl.Col + EEPROMDataWrCtrl.Row ) * EEPROM_PAGE_SIZE + EEPROMDataWrCtrl.Offset; EEPROMDataWrCtrl.WrLen = EEPROM_PAGE_SIZE - EEPROMDataWrCtrl.Offset; //ÿ�����д��һҳ if ( EEPROMDataWrCtrl.WrLen > EEPROMDataWrCtrl.DataLen - EEPROMDataWrCtrl.WrCnt ) //���һҳ,ʣ��Ĵ�д���ֽ�������һҳ EEPROMDataWrCtrl.WrLen = EEPROMDataWrCtrl.DataLen - EEPROMDataWrCtrl.WrCnt; WriteErr = EEPROM_Page_Write ( EEPPROM_DEVICE_ADDR, PhyAddr, &EEPROMDataWrCtrl.Data[EEPROMDataWrCtrl.WrCnt], EEPROMDataWrCtrl.WrLen ); EEPROMDataWrCtrl.Busy = 2; if ( WriteErr != EEPROM_OK ) { EEPROMDataWrCtrl.Busy = 0; //��ֹд�벢������� if ( ( WriteErr == EEPROM_INVALID_DEVICE_ADDR ) || ( WriteErr == EEPROM_INVALID_DATA_ADDR ) ) EEPROMDataWrCtrl.Result = EEPROM_DATA_ADDR_ERR; else if ( WriteErr == EEPROM_DATA_LENGTH_ERR ) EEPROMDataWrCtrl.Result = EEPROM_DATA_LEN_ERR; else EEPROMDataWrCtrl.Result = EEPROM_DATA_RW_FAIL; } } void EEPROM_Copy_Data ( uint8_t *pDstData, uint8_t *pSrcData, uint8_t Len ) { uint8_t i; for ( i = 0; i < Len; i++ ) pDstData[i] = pSrcData[i]; } uint8_t EEPROM_Compare_Data ( uint8_t *pDstData, uint8_t *pSrcData, uint8_t Len ) { uint8_t i; for ( i = 0; i < Len; i++ ) { if ( pDstData[i] - pSrcData[i] ) return 1; } return 0; }