#include "inflash.h"
#include "stm32l4xx_hal.h"
#include "pdebug.h"
#include "assertions.h"

/* 默认参数 */
usr_config_info g_usrConfigInfo={
    .flag_head              = FLAG_SAVE_INFLASH_HEAD,
    
    .addr                   = 0x30,                         /* 默认地址              */
    .uart_baud              = 9600,                         /* 默认波特率            */
    .speed_average_time     = 600,                          /* 平均风速默认10分钟更新 */
    .temp_hum_update_time   = 600,                          /* 温湿度更新时间        */
    
    .flag_end             = FLAG_SAVE_INFLASH_END,
};

/* 默认参数 */
factory_config_info g_stConfigInfo={
    .flag_head              = FLAG_SAVE_INFLASH_HEAD,
    
//    .transducer_cfg_1R5     = 15,                           /* 大宇换能器参数        */
//    .transducer_cfg_4R5     = 45,                           /* 大宇换能器参数        */
//    .transducer_cfg_8R0     = 80,                           /* 大宇换能器参数        */
    .transducer_cfg_1R5     = 10,                           /* 无锡电声换能器参数        */
    .transducer_cfg_4R5     = 35,                           /* 无锡电声换能器参数        */
    .transducer_cfg_8R0     = 65,                           /* 无锡电声换能器参数        */
    .RSSI_range             = 20,                           /* RSSI大于0.2有效      */
    .Coefficient            = 11201,                        /* 粘度修正系数      */
	.transducer_distace_NS  = 57560,						/* 换能器探头表面距离      */
    .transducer_distace_WE  = 57560,						/* 换能器探头表面距离      */
    
    .linear_point_1_x       = 0,                            /* 线性插值点1 */
    .linear_point_1_y       = 0,                            /* 线性插值点1 */
    .linear_point_2_x       = 0,                            /* 线性插值点2 */
    .linear_point_2_y       = 0,                            /* 线性插值点2 */
    .linear_point_3_x       = 0,                            /* 线性插值点3 */
    .linear_point_3_y       = 0,                            /* 线性插值点3 */
    .linear_point_4_x       = 0,                            /* 线性插值点4 */
    .linear_point_4_y       = 0,                            /* 线性插值点4 */
    .linear_point_5_x       = 0,                            /* 线性插值点5 */
    .linear_point_5_y       = 0,                            /* 线性插值点5 */
    .linear_enable          = 0,                            /* 线性插值使能 */
    .encrypt_0              = 0,                            /* 密文         */
    .encrypt_1              = 0,                            /* 密文         */
    .flag_end             = FLAG_SAVE_INFLASH_END,
};

/**
  * @brief 擦除多页flash 
  * @param  
  * @retval 
  */
void InFlash_Erase_Pages(u_int16_t PageBeginNum, u_int16_t NbPages)
{  	
  
    FLASH_EraseInitTypeDef EraseInitStruct;
    u_int32_t PAGEError = 0;

    EraseInitStruct.Banks       = FLASH_BANK_2;
    EraseInitStruct.TypeErase   = FLASH_TYPEERASE_PAGES;
    EraseInitStruct.Page        = PageBeginNum;
    EraseInitStruct.NbPages     = NbPages;
    
   if (HAL_FLASHEx_Erase(&EraseInitStruct, &PAGEError) != HAL_OK)  
	 {
		  log_error("inflash erase error!");
	 }
}

/**
  * @brief  写数据
  * @param  
  * @retval 
  */
void InFlash_Write(u_int32_t addr, u_int64_t *pBuffer,u_int32_t  NumToWrite)
{
      int i = 0;
      while( i < NumToWrite){
        if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, addr, pBuffer[i]) != HAL_OK){
//		        log_error("inflash write error!");
            return;
        }else{
            addr += 8;
            i++;
        }
      }
}
 
 /**
  * @brief  存入用户配置信息
  * @param  
  * @retval 
  */
void save_usr_config_info(usr_config_info save_config_info)
{
      HAL_FLASH_Unlock();
      InFlash_Write(STM32_INFLASH_SAVE_ADDR_1_BEGIN, (u_int64_t*)&save_config_info, (sizeof(save_config_info)+7)/8);
      InFlash_Erase_Pages(STM32_INFLASH_SAVE_PAGE_1, 1);
      InFlash_Write(STM32_INFLASH_SAVE_ADDR_1_BEGIN, (u_int64_t*)&save_config_info, (sizeof(save_config_info)+7)/8);
      HAL_FLASH_Lock();
}

 /**
  * @brief  存入出厂配置信息
  * @param  
  * @retval 
  */
void save_factory_config_info(factory_config_info save_config_info)
{
      HAL_FLASH_Unlock();
      InFlash_Write(STM32_INFLASH_SAVE_ADDR_2_BEGIN, (u_int64_t*)&save_config_info, (sizeof(save_config_info)+7)/8);
      InFlash_Erase_Pages(STM32_INFLASH_SAVE_PAGE_2, 1);
      InFlash_Write(STM32_INFLASH_SAVE_ADDR_2_BEGIN, (u_int64_t*)&save_config_info, (sizeof(save_config_info)+7)/8);
      HAL_FLASH_Lock();
}

 /**
  * @brief  读取用户配置信息
  * @param  
  * @retval 
  */
BOOL read_usr_config_info()
{    
     usr_config_info temp_config_info={0x00};
     
     memcpy((u_int8_t*)&temp_config_info,(u_int8_t*) STM32_INFLASH_SAVE_ADDR_1_BEGIN, sizeof(usr_config_info));
//     term_printf("%d", temp_config_info.addr);
     if((temp_config_info.flag_head == FLAG_SAVE_INFLASH_HEAD) && (temp_config_info.flag_end == FLAG_SAVE_INFLASH_END)){
        memcpy((u_int8_t*)&g_usrConfigInfo, (u_int8_t*)&temp_config_info, sizeof(usr_config_info));
//        term_printf("Addr:%d, speed_average_time:%dmin\r\n", g_usrConfigInfo.addr, g_usrConfigInfo.speed_average_time);
        return TRUE;
     }
     
//     term_printf("!get config info from inflash error,use default parameter.\r\n");
//      term_printf("Addr:%d, speed_average_time:%dmin\r\n", g_usrConfigInfo.addr, g_usrConfigInfo.speed_average_time);
     return FALSE;
}

 /**
  * @brief  读取出厂配置信息
  * @param  
  * @retval 
  */
BOOL read_factory_config_info()
{    
     factory_config_info temp_config_info={0x00};
     
     memcpy((u_int8_t*)&temp_config_info,(u_int8_t*) STM32_INFLASH_SAVE_ADDR_2_BEGIN, sizeof(factory_config_info));
//     term_printf("%d", temp_config_info.addr);
     if((temp_config_info.flag_head == FLAG_SAVE_INFLASH_HEAD) && (temp_config_info.flag_end == FLAG_SAVE_INFLASH_END)){
        memcpy((u_int8_t*)&g_stConfigInfo, (u_int8_t*)&temp_config_info, sizeof(factory_config_info));
//        term_printf("Addr:%d, speed_average_time:%dmin\r\n", g_stConfigInfo.addr, g_stConfigInfo.speed_average_time);
        return TRUE;
     }
     
//     term_printf("!get config info from inflash error,use default parameter.\r\n");
//      term_printf("Addr:%d, speed_average_time:%dmin\r\n", g_stConfigInfo.addr, g_stConfigInfo.speed_average_time);
     return FALSE;
}

 /**
  * @brief  读取所有配置信息
  * @param  
  * @retval 
  */
BOOL read_config_info()
{    
     read_usr_config_info();
     read_factory_config_info();
}

 /**
  * @brief  删除用户配置信息
  * @param  
  * @retval 
  */
void delete_config_info()
{
      usr_config_info delete_config_info = {0};
      HAL_FLASH_Unlock();
      InFlash_Write(STM32_INFLASH_SAVE_ADDR_1_BEGIN, (u_int64_t*)&delete_config_info, (sizeof(delete_config_info)+7)/8);
      InFlash_Erase_Pages(STM32_INFLASH_SAVE_PAGE_1, 1);
      InFlash_Write(STM32_INFLASH_SAVE_ADDR_1_BEGIN, (u_int64_t*)&delete_config_info, (sizeof(delete_config_info)+7)/8);
      HAL_FLASH_Lock();
}



#if 0
 /**
  * @brief  测试
  * @param  
  * @retval 
  */
u_int8_t buff[100]={0x00};
void TEST_config_info()
{
  g_stConfigInfo.x_angle_adjust = 2;
  g_stConfigInfo.y_angle_adjust =3;
  save_config_info(g_stConfigInfo);
  memcpy(buff,(u_int8_t*) STM32_INFLASH_SAVE_ADDR_BEGIN, sizeof(g_stConfigInfo));
     
}
#endif