//////////////////////////////////////////////////////////////////////////////// /// @file sim_eeprom.c /// @author AE TEAM /// @brief THIS FILE PROVIDES SIM-EEPROM FUNCTIONS. //////////////////////////////////////////////////////////////////////////////// /// @attention /// /// THE EXISTING FIRMWARE IS ONLY FOR REFERENCE, WHICH IS DESIGNED TO PROVIDE /// CUSTOMERS WITH CODING INFORMATION ABOUT THEIR PRODUCTS SO THEY CAN SAVE /// TIME. THEREFORE, MINDMOTION SHALL NOT BE LIABLE FOR ANY DIRECT, INDIRECT OR /// CONSEQUENTIAL DAMAGES ABOUT ANY CLAIMS ARISING OUT OF THE CONTENT OF SUCH /// HARDWARE AND/OR THE USE OF THE CODING INFORMATION CONTAINED HEREIN IN /// CONNECTION WITH PRODUCTS MADE BY CUSTOMERS. /// ///

© COPYRIGHT MINDMOTION

//////////////////////////////////////////////////////////////////////////////// // Define to prevent recursive inclusion #define _SIM_EEPROM_C_ // Files includes #include "hal_conf.h" #include "sim_eeprom.h" #include "uart.h" #include "public.h" #include "stdlib.h" #include "CRC.h" #define M8(adr) (*((vu8 *) (adr))) #define M16(adr) (*((vu16 *) (adr))) #define BASED_FLASH_SECTOR_ADDRESS 0x0800F400 #define BASED_FLASH_SECTOR_ADDRESS_1 0x0800F000 #define BASED_FLASH_SECTOR_ADDRESS_2 0x0800F800 //////////////////////////////////////////////////////////////////////////////// /// @addtogroup MM32_Example_Layer /// @{ //////////////////////////////////////////////////////////////////////////////// /// @addtogroup SIM_EEPROM /// @{ //////////////////////////////////////////////////////////////////////////////// /// @addtogroup SIM_EEPROM_Exported_Constants /// @{ //////////////////////////////////////////////////////////////////////////////// /// @brief Erases a specified FLASH page. /// @note This function can be used for all MM32 devices. /// @param Page_Address: The page address to be erased. /// @retval None. //////////////////////////////////////////////////////////////////////////////// static void FLASH_SIM_EraseEE(u32 pageAddress) { FLASH_Unlock(); FLASH_ErasePage(pageAddress); FLASH_Lock(); } //////////////////////////////////////////////////////////////////////////////// /// @brief Programs a buffer at a specified address. /// @note This function can be used for all MM32 devices. /// @param *buf: the pointer of the buffer to be programmed. /// @param addr: specifies the address to be programmed. /// @param len: the number of bytes in the buffer. /// This parameter can only be even. /// @retval None. //////////////////////////////////////////////////////////////////////////////// static void FLASH_SIM_ProgramEE(u16* buf, u32 addr, u16 len) { u16 i; FLASH_Unlock(); WWDG_SetCounter(0x7e); for ( i = 0; i < len / 2; i++) { FLASH_ProgramHalfWord(addr, *buf); addr += 2; buf++; } FLASH_Lock(); } //////////////////////////////////////////////////////////////////////////////// /// @brief Determine if the data that at the ptr address with the length is len /// is empty. /// @note This function can be used for all MM32 devices. /// @param *ptr: the pointer of the starting address. /// @param len: the number of bytes. /// This parameter can only be even. /// @retval True presents the data is empty, /// false presents the data has been written. //////////////////////////////////////////////////////////////////////////////// static u8 FLASH_SIM_FindEmpty(u32 ptr, u16 len) { u16 i, readdata; u8 ret = 1; for (i = 0; i < (len / 2); i++) { readdata = M16(ptr + i * 2); if ( readdata != 0xffff) { ret = 0; break; } } return ret; } //////////////////////////////////////////////////////////////////////////////// /// @brief Locate the writable area on the specified address. /// @note This function can be used for all MM32 devices. /// @param pageAddress: specifies the beginning of the EEprom. /// The EEprom can be some continuously pages in the flash. /// @param len: the number of bytes to be written. /// This parameter can only be even. /// @retval the pointer of the starting address. //////////////////////////////////////////////////////////////////////////////// u32 FLASH_SIM_WriteLocate(u32 pageAddress, u16 len) { u16 i; u32 ptr = pageAddress; if( (pageAddress % 2 ) != 0) { while(1); } if((0x800 % len) != 0) { while(1); } for (i = 0; i < (0x0800 / len); i++) { ptr = (pageAddress + i * len); if (FLASH_SIM_FindEmpty(ptr, len) == 1) { break; } } if(i == (0x0800 / len)) ptr = 0; return ptr; } //////////////////////////////////////////////////////////////////////////////// /// @brief Programs a buffer at a specified address. /// @note This function can be used for all MM32 devices. /// @param *buf: the pointer of the buffer to be programmed. /// @param pageAddress: specifies the beginning of the EEprom. /// The EEprom can be some continuously pages in the flash. /// @param len: the number of bytes in the buffer. /// This parameter can only be even. /// @retval None. //////////////////////////////////////////////////////////////////////////////// static void FLASH_SIM_WriteEE(u16* buf, u32 pageAddress, u16 len) { u32 ptr = FLASH_SIM_WriteLocate(pageAddress, len); if (ptr == 0) { FLASH_SIM_EraseEE(pageAddress + 0x000); FLASH_SIM_EraseEE(pageAddress + 0x400); FLASH_SIM_ProgramEE(buf, pageAddress, len); } else { if (ptr == (pageAddress + 0x0400 - len)) { FLASH_SIM_EraseEE(pageAddress + 0x400); FLASH_SIM_ProgramEE(buf, (u32)ptr, len); } else if (ptr == (pageAddress + 0x0800 - len)) { FLASH_SIM_EraseEE(pageAddress + 0x000); FLASH_SIM_ProgramEE(buf, (u32)ptr, len); } else { FLASH_SIM_ProgramEE(buf, (u32)ptr, len); } } } //////////////////////////////////////////////////////////////////////////////// /// @brief Initialize eeprom. /// @note This function can be used for all MM32 devices. /// @note Erases the pages for EEPROM or continue to operate EEPROM. /// @param None. /// @retval None. //////////////////////////////////////////////////////////////////////////////// void FLASH_SIM_EEPROM_Init(void) { WWDG_SetCounter(0x7e); FLASH_SIM_EraseEE((u32)(BASED_FLASH_SECTOR_ADDRESS) + 0x0000); //FLASH_SIM_EraseEE((u32)(BASED_FLASH_SECTOR_ADDRESS) + 0x0400); WWDG_SetCounter(0x7e); FLASH_SIM_EraseEE((u32)(BASED_FLASH_SECTOR_ADDRESS_1) + 0x0000); WWDG_SetCounter(0x7e); } //////////////////////////////////////////////////////////////////////////////// /// @brief read the last set of data that was written in the specified EEPROM. /// @note This function can be used for all MM32 devices. /// @param ptr: the buffer to store the last set of data in EEPROM /// @param len: the length of data that the user wants to get /// @note The actual length is the minimum of len and the EEPROM blockSize /// @retval s32: -1: the EEPROM is empty /// 0: the instance does not exist /// 1: Read data operation succeeded //////////////////////////////////////////////////////////////////////////////// s32 EEPROM_Read(u8* ptr, u16 len) { u32 pAddr; pAddr = FLASH_SIM_WriteLocate((u32)BASED_FLASH_SECTOR_ADDRESS, len); //u16* pAddr = FLASH_SIM_Locate((u32)(BASED_FLASH_SECTOR_ADDRESS), len); if (pAddr == 0) { return -1; } else if (pAddr == BASED_FLASH_SECTOR_ADDRESS) { pAddr = (BASED_FLASH_SECTOR_ADDRESS + 0x0800 - len); } else { pAddr -= len; } memcpy(ptr, (s8*)pAddr, len); return len; } s32 EEPROM_Read_1(u8* ptr, u16 len) { u32 pAddr; pAddr = FLASH_SIM_WriteLocate((u32)BASED_FLASH_SECTOR_ADDRESS_1, len); //u16* pAddr = FLASH_SIM_Locate((u32)(BASED_FLASH_SECTOR_ADDRESS), len); if (pAddr == 0) { return -1; } else if (pAddr == BASED_FLASH_SECTOR_ADDRESS_1) { pAddr = (BASED_FLASH_SECTOR_ADDRESS_1 + 0x0800 - len); } else { pAddr -= len; } memcpy(ptr, (s8*)pAddr, len); return len; } s32 EEPROM_Read_2(u8* ptr, u16 len) { u32 pAddr; pAddr = FLASH_SIM_WriteLocate((u32)BASED_FLASH_SECTOR_ADDRESS_2, len); //u16* pAddr = FLASH_SIM_Locate((u32)(BASED_FLASH_SECTOR_ADDRESS), len); if (pAddr == 0) { return -1; } else if (pAddr == BASED_FLASH_SECTOR_ADDRESS_2) { pAddr = (BASED_FLASH_SECTOR_ADDRESS_2 + 0x0800 - len); } else { pAddr -= len; } memcpy(ptr, (s8*)pAddr, len); return len; } //////////////////////////////////////////////////////////////////////////////// /// @brief write the set of data in the specified EEPROM. /// @note This function can be used for all MM32 devices. /// @param ptr: the buffer that store the data to be written in EEPROM /// @note the data cannot be all 0xFF /// @param len: the length of ptr /// @note The actual length is the minimum of len and the EEPROM blockSize /// @retval s32: false: the EEPROM_Instance does not exist /// true: Write data operation succeeded //////////////////////////////////////////////////////////////////////////////// s32 EEPROM_Write(u8* ptr, u16 len) { FLASH_SIM_WriteEE((u16*)ptr, (u32)(BASED_FLASH_SECTOR_ADDRESS), len); return len; } s32 EEPROM_Write_1(u8* ptr, u16 len) { FLASH_SIM_WriteEE((u16*)ptr, (u32)(BASED_FLASH_SECTOR_ADDRESS_1), len); return len; } //////////////////////////////////////////////////////////////////////////////// /// @brief run the test that use FLASH simulate EEPROM /// @note it need to be careful to the write data can not be all 0xFFFF ; /// @param None. /// @retval None. //////////////////////////////////////////////////////////////////////////////// s32 FLASH_SIM_EEPROM_Test(void) { u16 testwrdata[128]; u16 testrddata[128]; //g_work.m_set_other_hot.add ++; // // // flash_wite(); EEPROM_Read((u8*)(testrddata ),256); for(int i = 0 ; i < 128; i ++ ) { // printf("test : 0x%X -- value%d \r\n",testrddata[i],i); //printf("P : 0x%X -- value%d \r\n",*P++,i); } // P = (u16 *)(&g_work.m_set_other_hot); // // for(int i = 0 ; i < 128; i ++ ) // { // printf("P : 0x%X -- value%d \r\n",*P++,i); // } return 0; } u16 add(u16 *p, u16 len) { u16 value = 0; if( len == 0 ) { return 0; } while(len --) { value+= *p++; } return value; } void m_mset( u16 *P , u16 num, u16 len ) { while( len -- ) { *P++ = num; } } void init_value() { // g_work.m_set.m_set._head = 0xAAFB; // g_work.m_set.m_set._one_High_temp = 270; // g_work.m_set.m_set._one_High_time = 10; // g_work.m_set.m_set._one_low_temp = 160; // // g_work.m_set.m_set._one_keep_temp = 200; // g_work.m_set.m_set._one_Keep_time = 120; // // g_work.m_set.m_set._two_keep_temp = 178; // g_work.m_set.m_set._two_keep_time = 50; // g_work.m_set.m_set._two_up_temp = 190; // g_work.m_set.m_set._up_R = 8568; //A // 1号 13371 //2 号 12928 // 4号 12597 3号 13477 5 号 13602 // g_work.m_set.m_set._down_R = 8531; // 1号 14047 //2 号 14502 // 4号 14387 3号 13403 5 14075 // // // g_work.m_set.m_set._Hight_adjust = 5; // g_work.m_set.m_set._Keep_adjust = 10; // g_work.m_set.m_set._Two_keep_adjust = 10; // // g_work.m_set.m_set._K_18_Value = 4100; //3423; // g_work.m_set.m_set._K_18_Value_1 = 4100; //3891; // g_work.m_set.m_set._K_24_Value = 4100; //3514; // g_work.m_set.m_set._K_24_Value_1 = 4100; //4013; // g_work.m_set.m_set.add = add((u16 *)&g_work.m_set.m_set, sizeof( g_work.m_set.m_set)/2 - 1); int i = 0; g_work.m_set_other_hot.head = 0xAAFB; g_work.m_set_other_hot.set_all_time = 40; g_work.m_set_other_hot.set_order_time = 20; g_work.m_set_other_hot.set_up_num = 2; g_work.m_set_other_hot.normal_T_Value = 25; g_work.m_set_other_hot.normal_R_Value = 750; g_work.m_set_other_hot.TCR_vlaue = 3000; for( i = 0; i < 28 ; i ++ ) { g_work.m_set_other_hot.m_set_down[i]._time = 0; g_work.m_set_other_hot.m_set_down[i]._temp = 0; g_work.m_set_other_hot.m_set_up[i]._time = 0; g_work.m_set_other_hot.m_set_up[i]._temp = 0; } g_work.m_set_other_hot.m_set_up[0]._time = 0; g_work.m_set_other_hot.m_set_up[0]._temp = 250; g_work.m_set_other_hot.m_set_up[1]._time = 20; g_work.m_set_other_hot.m_set_up[1]._temp = 250; g_work.m_set_other_hot.m_set_down[0]._time = 0; g_work.m_set_other_hot.m_set_down[0]._temp = 250; g_work.m_set_other_hot.m_set_down[1]._time = 20; g_work.m_set_other_hot.m_set_down[1]._temp = 250; } void BubbleSort(Other_oder *a, int len) { int i, j; Other_oder temp; for (j = 0; j < len - 1; j++) { for (i = 0; i < len - 1 - j; i++) if (a[i]._time > a[i + 1]._time) { temp = a[i]; a[i] = a[i + 1]; a[i + 1] = temp; } } } void flash_wite() { FLASH_SIM_EEPROM_Init(); g_work.m_set_other_hot.head = 0xAAFB; if( g_work.m_set_other_hot.set_up_num < 28 ) { BubbleSort(g_work.m_set_other_hot.m_set_up,g_work.m_set_other_hot.set_up_num); for( int i = g_work.m_set_other_hot.set_up_num; i < sizeof(g_work.m_set_other_hot.m_set_up )/sizeof(Other_oder); i ++) { g_work.m_set_other_hot.m_set_up[i]._time = 0; //上段清零 g_work.m_set_other_hot.m_set_up[i]._temp = 0; } } else { return; } g_work.m_set_other_hot.crc = CRC16((u8 *)&g_work.m_set_other_hot, sizeof( g_work.m_set_other_hot ) - 2); EEPROM_Write((u8*)(&g_work.m_set_other_hot),256); EEPROM_Write_1((u8*)(&g_work.m_set_other_hot),256); //printf("flash remmer !\r\n"); } void init_conditon() { g_work.m_conditon.m_conditon.head = 0xAAFB; g_work.m_conditon.m_conditon.V_conditon = 0; g_work.m_conditon.m_conditon.nor_R_value = 760; g_work.m_conditon.m_conditon.nor_T_value = 21; g_work.m_conditon.m_conditon.TCR_Value = 95; g_work.m_conditon.m_conditon.lock = 0; } void Write_condtion() { //printf("W:up_hot: %d keep: %d keep: %d \r\n ",g_work.m_conditon.m_conditon.up_hot_adjust,g_work.m_conditon.m_conditon.up_keep_adjust,g_work.m_conditon.m_conditon.down_keep_adjust); WWDG_SetCounter(0x7e); FLASH_SIM_EraseEE((u32)(BASED_FLASH_SECTOR_ADDRESS_2)); g_work.m_conditon.m_conditon.head = 0xAAFB; g_work.m_conditon.m_conditon.add = add((u16 *)&g_work.m_conditon.m_conditon, sizeof( g_work.m_conditon.m_conditon)/2 - 1); FLASH_SIM_WriteEE((u16*)&g_work.m_conditon.m_conditon, (u32)(BASED_FLASH_SECTOR_ADDRESS_2), 64); } void read_condtion() { memset((char *)&g_work.m_conditon.arr,0,64); EEPROM_Read_2((u8 *)&g_work.m_conditon.arr,64); //printf("up_hot: %d keep: %d keep: %d \r\n ",g_work.m_conditon.m_conditon.up_hot_adjust,g_work.m_conditon.m_conditon.up_keep_adjust,g_work.m_conditon.m_conditon.down_keep_adjust); if ( add((u16 *)&g_work.m_conditon.m_conditon, sizeof( g_work.m_conditon.m_conditon)/2 - 1) == g_work.m_conditon.m_conditon.add ) { // printf("OK\r\n"); // for( int i = 0; i < 64; i ++ ) // { // printf("%d %d\r\n ",i,g_work.m_conditon.arr[i]); // } if(g_work.m_conditon.m_conditon.head != 0xAAFB ) { init_conditon(); Write_condtion(); } } else { //printf("NO\r\n"); init_conditon(); Write_condtion(); } } void read_value_jujement() // 读取数值判断 { u8 start_remmer = 0; // if( g_work.m_set_other_hot.normal_R_Value < 700 || g_work.m_set_other_hot.normal_R_Value > 900 ) // 常温阻值 700 ~ 900 // { // // g_work.m_set_other_hot.normal_R_Value = 740; // start_remmer = 1; // } if( g_work.m_set_other_hot.normal_T_Value < 5 || g_work.m_set_other_hot.normal_T_Value > 40 ) // 常温温度 5 ~ 40 { g_work.m_set_other_hot.normal_T_Value = 25; start_remmer = 1; } // if( g_work.m_set_other_hot.TCR_vlaue < 2600 || g_work.m_set_other_hot.TCR_vlaue > 4000 ) // TCR 值 2600 ~ 4000 // { // g_work.m_set_other_hot.TCR_vlaue = 3000; // // start_remmer = 1; // } if( g_work.m_set_other_hot.set_up_num > 29 ) { start_remmer = 1; g_work.m_set_other_hot.set_up_num = 2; } if( start_remmer == 1 ) { flash_wite(); } } void flash_read() { u8 count = 5; while( count -- ) { memset((char *)&g_work.m_set_other_hot,0,sizeof(g_work.m_set_other_hot)); EEPROM_Read((u8 *)&g_work.m_set_other_hot,sizeof(g_work.m_set_other_hot)); if( CRC16( (u8 *)&g_work.m_set_other_hot,sizeof( g_work.m_set_other_hot ) -2 ) == g_work.m_set_other_hot.crc ) { read_value_jujement(); return; } else { } } count = 5; while( count -- ) { memset((char *)&g_work.m_set_other_hot,0,sizeof(g_work.m_set_other_hot)); EEPROM_Read_1((u8 *)&g_work.m_set_other_hot,sizeof(g_work.m_set_other_hot)); if(CRC16( (u8 *)&g_work.m_set_other_hot,sizeof( g_work.m_set_other_hot ) -2 ) == g_work.m_set_other_hot.crc ) { read_value_jujement(); return; } else { } } init_value(); flash_wite(); }