TJ-WW03-H03/APP_smoke_N_V1.3/HARDWARE/SIM_EEPROM/sim_eeprom.c

628 lines
17 KiB
C
Raw Permalink Blame History

////////////////////////////////////////////////////////////////////////////////
/// @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.
///
/// <H2><CENTER>&COPY; COPYRIGHT MINDMOTION </CENTER></H2>
////////////////////////////////////////////////////////////////////////////////
// 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<><31> 13371 //2 <20><> 12928 // 4<><34> 12597 3<><33> 13477 5 <20><> 13602
// g_work.m_set.m_set._down_R = 8531; // 1<><31> 14047 //2 <20><> 14502 // 4<><34> 14387 3<><33> 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; //<2F>϶<EFBFBD><CFB6><EFBFBD><EFBFBD><EFBFBD>
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() // <20><>ȡ<EFBFBD><C8A1>ֵ<EFBFBD>ж<EFBFBD>
{
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 ) // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ 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 ) // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 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();
}