/*
 * ****************************************************
 * @file    : flash.h
 * @brief   : Flash Header
 * @author  : sohee kim / Something by People
 * @data    : 2023. 04. 27
 * ****************************************************
 */
#ifndef __FLASH_H_
#define __FLASH_H_

#ifdef __cplusplus
extern "C" {
#endif

#include "main.h"
#include "WESPION.h"
#include "WESPION_Def.h"

//////////////////    Compiling Options   ////////////////////

/////////////////   COSTANT Declarations  ///////////////////

#define EEPROM  __attribute__((section(".1st_Secter"))) const
#define BACKUP  __attribute__((section(".2nd_Secter"))) const
//#define EEPROM  __attribute__((section(".1st_Secter")))
//#define BACKUP  __attribute__((section(".2nd_Secter")))

#define FLASH_ORIGIN_SECTOR   FLASH_SECTOR_2
#define FLASH_BACKUP_SECTOR   FLASH_SECTOR_3

#define SECTOR_SIZE           0x4000        //16KB
#define FLASH_VALID_CODE      0x12345678


/////////////////    System Constants    ////////////////////
#define HW_MODEL                        0x01    //RoomFit
//#define HW_VER                        3       //in main.h
#define VER_MAJER                       0x00
#define VER_MINER                       0x09
#define VER_SUB                         0x00    //

#define VER_YEAR                        2025
#define VER_MONTH                       0x03
#define VER_DATE                        0x13    //  19

#define MOTOR_PARA_POLE                 10     // BS10510               //uint8_t
//#define MOTOR_PARA_POLE                 8      // JKONG                 //uint8_t
#define MOTOR_PARA_Ld                   0.0f
#define MOTOR_PARA_Lq                   0.0f
#define MOTOR_PARA_Rs                   0.0f
#define MOTOR_PARA_PhaiF                (72.2f * 0.001f * MT_1_OVR_SQ3)     //  BS10510
//#define MOTOR_PARA_PhaiF                (25.3f * 0.001f * MT_1_OVR_SQ3)   //  JKONG

#define MOTOR_GAINCURD_Kp               1.0f
#define MOTOR_GAINCURD_Ki               0.011f
#define MOTOR_GAINCURD_Kaw              (1.0f/MOTOR_GAINCURD_Kp)
#define MOTOR_GAINCURQ_Kp               1.0f
#define MOTOR_GAINCURQ_Ki               0.011f
#define MOTOR_GAINCURQ_Kaw              (1.0f/MOTOR_GAINCURQ_Kp)

#define MOTOR_GAINSPD_Kp                0.0022f
#define MOTOR_GAINSPD_Ki                0.00001f
#define MOTOR_GAINSPD_Kaw               (1.0f/MOTOR_GAINSPD_Kp)

#define MOTOR_GAINFWEAK_Kp              2.0f
#define MOTOR_GAINFWEAK_Ki              0.002f

#define MOTOR_ANG_ENCPULSE              (4096*4)//  BS10510 - TLE5012B    //uint16_t
//#define MOTOR_ANG_ENCPULSE              (1000*4)//  JKONG                 //uint16_t
#define MOTOR_ANG_ANGLESCALE            (360.0f/(float)MOTOR_ANG_ENCPULSE)
#define MOTOR_ANG_SPEEDSCALE            (1000.0f*60.0f/MOTOR_ANG_ENCPULSE)

  //  ENCORDER
  //  BS10510 - check every re-assemble of sensor
  //  PT4B-Sample - 25.02.29
#define MOTOR1_ANG_ANGLEELCOFFSET       183.0f    //
#define MOTOR2_ANG_ANGLEELCOFFSET        20.0f    //
  //  SPOEX#1 (white)
//#define MOTOR1_ANG_ANGLEELCOFFSET       345.0f    // 24.09.23 - Motor#6
//#define MOTOR2_ANG_ANGLEELCOFFSET       330.0f    // 24.09.26 - Motor#7
//  SPOEX#2 (black) - 24.02.21
//#define MOTOR1_ANG_ANGLEELCOFFSET       186.0f    // 24.02.21 - Motor#2
//#define MOTOR2_ANG_ANGLEELCOFFSET        53.0f    // 24.12.13 - Motor#3
  //  SPOEX#3 (naked) - 24.05.03
//#define MOTOR1_ANG_ANGLEELCOFFSET       180.0f    // Motor#5
//#define MOTOR2_ANG_ANGLEELCOFFSET       120.0f    // Motor#3 ??
  //  PT6KC - 24.06.08
//#define MOTOR1_ANG_ANGLEELCOFFSET       132.0f    // MotorV3#1
//#define MOTOR2_ANG_ANGLEELCOFFSET       185.0f    // MotorV3#1 on Inv2
//#define MOTOR2_ANG_ANGLEELCOFFSET       000.0f    // MotorV3#2
//  MR
#define MOTOR_ANG_MR_MAX_SIN            0                               //uint16_t
#define MOTOR_ANG_MR_MAX_COS            0                               //uint16_t
#define MOTOR_ANG_MR_MIN_SIN            4095                            //uint16_t
#define MOTOR_ANG_MR_MIN_COS            4095                            //uint16_t
#define MOTOR_ANG_MR_MID_SIN            0                               //uint16_t
#define MOTOR_ANG_MR_MID_COS            0                               //uint16_t
#define MOTOR_ANG_MR_GAIN_SIN           1.0f
#define MOTOR_ANG_MR_GAIN_COS           1.0f

#define INV_PARA_HWADCSCALE             (3.3f/4095.0f)
#define INV_PARA_HWVDCSCALE             (1.0f/(30.0f+1.0f))
#define INV_PARA_HWISCALE               (0.002f*15.0f/1.0f)

#if   defined(TIM_8KHZ)
  #define INV_PARA_TSAMP                (1.0f/8000.0f)
#elif defined(TIM_10KHZ)
  #define INV_PARA_TSAMP                (1.0f/10000.0f)
#elif defined(TIM_16KHZ)
  #define INV_PARA_TSAMP                (1.0f/16000.0f)
#elif defined(TIM_20KHZ)
  #define INV_PARA_TSAMP                (1.0f/20000.0f)
#else
  #define INV_PARA_TSAMP                (1.0f/10000.0f)
#endif

#define INV_PARA_PWM_MAX                TIM_PERIOD
#define INV_PARA_PWM_MID                ((TIM_PERIOD+1)>>1)
#define INV_PARA_VDCMARGIN              0.90f      // original 0.90f (HSW 24.02.21)

#define LPFVDC_FC                       1000.0f
#define LPFVDC_FS                       (1.0f/INV_PARA_TSAMP)

#define LPFCUR_FC                       10.0f
#define LPFCUR_FS                       (1.0f/INV_PARA_TSAMP)

#define LPFSPD_FC                       100.0f
#define LPFSPD_FS                       1000.0f

#define ERRREF_ISENSOROPEN              3908.0f
#define ERRREF_ISENSORSHORT             186.0f
#define ERRREF_OVERCURRENT              35.0f      // original 30.0 (HSW 24.02.21)
#define ERRREF_OVERSPEED                8000.0f    // original 4000 (HSW 24.02.21)
#define ERRREF_OVERVOLTAGE              70.0
#define ERRREF_UNDERVOLTAGE             30.0
#define ERRREF_ISENSOROFFSETMAX         (2048.0f+50.0f)
#define ERRREF_ISENSOROFFSETMIN         (2048.0f-50.0f)

#define INV_CTRL_VDCLIMFWEAK            49.0f
#define INV_CTRL_ILIMFWEAK              (ERRREF_OVERCURRENT*0.8f)

#define MOTOR_ANG_RPMLIM                (ERRREF_OVERSPEED*0.8f)
#define MOTOR_ANG_SPDCTRLOUTLIM         (ERRREF_OVERCURRENT*0.8f)

#define MACHINE_SENSOR_GEAR_RATIO       3.0f
#define MACHINE_SPOOL_DIAMETER          60.0f         // [mm]
#define MACHINE_MAX_WEIGHT              30.0f         // [kg]인데 현재는 A, 테스트 안전을 위해 막아둠
#define MACHINE_CABLE_MAX_LENGTH        2650          // [mm]
#define MACHINE_SCALE_WEIGHT2CURRENT    0.5f          // [kg/A] -> C샘플, BS-105-10 기준 약 2
#define MACHINE_SOFT_WINDING_HEIGHT     20            // [mm]

#define MACHINE_DEFAULT_WEIGHT          1.0           // [A]
#define MACHINE_FRICTION_WEIGHT         0.45          // [A]
#define MACHINE_FRICTION_SPEED_PLUS     (-20.0f)
#define MACHINE_FRICTION_SPEED_MINUS    90.0f


/////////////////   Structure Declarations  ///////////////////


typedef struct {
  uint8_t model[2];                     //0x0000
  uint8_t VerMajer;
  uint8_t VerMiner;

  uint16_t VerYear;                     //0x0004
  uint8_t VerMonth;
  uint8_t VerDate;

  uint8_t Motor_Para_Pole;              //0x0008
  uint8_t VerSub;                       ///somebp 2024.02.07
  uint16_t Motor_Ang_EncPulse;

  float Motor_Para_Ld;                  //0x000C
  float Motor_Para_Lq;                  //0x0010
  float Motor_Para_Rs;                  //0x0014
  float Motor_Para_Phaif;               //0x0018

  float Motor_GainCurD_Kp;              //0x001C
  float Motor_GainCurD_Ki;              //0x0020
  float Motor_GainCurD_Kaw;             //0x0024
  float Motor_GainCurQ_Kp;              //0x0028
  float Motor_GainCurQ_Ki;              //0x002C
  float Motor_GainCurQ_Kaw;             //0x0030

  float Motor_GainSpd_Kp;               //0x0034
  float Motor_GainSpd_Ki;               //0x0038
  float Motor_Gainspd_Kaw;              //0x003C

  float Motor_GainFweak_Kp;             //0x0040
  float Motor_GainFweak_Ki;             //0x0044

  float Motor_Ang_AngleScale;           //0x0048
  float Motor_Ang_SpeedScale;           //0x004C
  float Motor1_Ang_AngleElecOffset;     //0x0050
  float Motor2_Ang_AngleElecOffset;     //0x0054

  uint16_t Motor_Ang_MR_Max_Sin;        //0x0058
  uint16_t Motor_Ang_MR_Max_Cos;
  uint16_t Motor_Ang_MR_Min_Sin;        //0x005C
  uint16_t Motor_Ang_MR_Min_Cos;
  uint16_t Motor_Ang_MR_Mid_Sin;        //0x0060
  uint16_t Motor_Ang_MR_Mid_Cos;
  float Motor_Ang_MR_Gain_Sin;          //0x0064
  float Motor_Ang_MR_Gain_Cos;          //0x0068

  float Inv_Para_HwAdcScale;            //0x006C
  float Inv_Para_HwVdcScale;            //0x0070
  float Inv_Para_HwiScale;              //0x0074

  float Inv_Para_Tsamp;                 //0x0078

  float Inv_Para_PWM_Max;               //0x007C
  float Inv_Para_PWM_Mid;               //0x0080
  float Inv_Para_VdcMargin;             //0x0084

  float LPFVdc_fc;                      //0x0088
  float LPFVdc_fs;                      //0x008C

  float LPFCur_fc;                      //0x0090
  float LPFCur_fs;                      //0x0094

  float LPFSpd_fc;                      //0x0098
  float LPFSpd_fs;                      //0x009C

  float ErrRef_IsensorOpen;             //0x00A0
  float ErrRef_IsensorShort;            //0x00A4
  float ErrRef_OverCurrent;             //0x00A8
  float ErrRef_OverSpeed;               //0x00AC
  float ErrRef_OverVoltage;             //0x00B0
  float ErrRef_UnderVoltage;            //0x00B4
  float ErrRef_IsensorOffsetMax;        //0x00B8
  float ErrRef_IsensorOffsetMin;        //0x00BC

  float Inv_Ctrl_VdcLimFweak;           //0x00C0
  float Inv_Ctrl_IlimFweak;             //0x00C4

  float Motor_Ang_RpmLim;               //0x00C8
  float Motor_Ang_SpdCtrlOutLim;        //0x00CC

  float Machine_SensorGearRatio;        //0x00D0
  float Machine_SpoolDiameter;          //0x00D4
  float Machine_MaxWeight;              //0x00D8
  float Machine_CableMaxLength;         //0x00DC
  float Machine_Scale_Weight2Current;   //0x00E0
  float Machine_SoftWindingHeight;      //0x00E4

  float Machine_DefaultWeight;          //0x00E8
  float Machine_FrictionWeight;         //0x00EC
  float Machine_FrictionSpeedPlus;      //0x00F0
  float Machine_FrictionSpeedMinus;     //0x00F4

  uint32_t check;   //FLASH_VALID_CODE  //0x00F8
} Data_Form_RAM;

typedef struct {
  uint8_t model[2];                     //0x0000
  uint8_t VerMajer;
  uint8_t VerMiner;

  uint16_t VerYear;                     //0x0004
  uint8_t VerMonth;
  uint8_t VerDate;

  uint8_t Motor_Para_Pole;              //0x0008
  uint8_t VerSub;                       ///somebp 2024.02.07
  uint16_t Motor_Ang_EncPulse;

  float Motor_Para_Ld;                  //0x000C
  float Motor_Para_Lq;                  //0x0010
  float Motor_Para_Rs;                  //0x0014
  float Motor_Para_Phaif;               //0x0018

  float Motor_GainCurD_Kp;              //0x001C
  float Motor_GainCurD_Ki;              //0x0020
  float Motor_GainCurD_Kaw;             //0x0024
  float Motor_GainCurQ_Kp;              //0x0028
  float Motor_GainCurQ_Ki;              //0x002C
  float Motor_GainCurQ_Kaw;             //0x0030

  float Motor_GainSpd_Kp;               //0x0034
  float Motor_GainSpd_Ki;               //0x0038
  float Motor_Gainspd_Kaw;              //0x003C

  float Motor_GainFweak_Kp;             //0x0040
  float Motor_GainFweak_Ki;             //0x0044

  float Motor_Ang_AngleScale;           //0x0048
  float Motor_Ang_SpeedScale;           //0x004C
  float Motor1_Ang_AngleElecOffset;     //0x0050
  float Motor2_Ang_AngleElecOffset;     //0x0054

  uint16_t Motor_Ang_MR_Max_Sin;        //0x0058
  uint16_t Motor_Ang_MR_Max_Cos;
  uint16_t Motor_Ang_MR_Min_Sin;        //0x005C
  uint16_t Motor_Ang_MR_Min_Cos;
  uint16_t Motor_Ang_MR_Mid_Sin;        //0x0060
  uint16_t Motor_Ang_MR_Mid_Cos;
  float Motor_Ang_MR_Gain_Sin;          //0x0064
  float Motor_Ang_MR_Gain_Cos;          //0x0068

  float Inv_Para_HwAdcScale;            //0x006C
  float Inv_Para_HwVdcScale;            //0x0070
  float Inv_Para_HwiScale;              //0x0074

  float Inv_Para_Tsamp;                 //0x0078

  float Inv_Para_PWM_Max;               //0x007C
  float Inv_Para_PWM_Mid;               //0x0080
  float Inv_Para_VdcMargin;             //0x0084

  float LPFVdc_fc;                      //0x0088
  float LPFVdc_fs;                      //0x008C

  float LPFCur_fc;                      //0x0090
  float LPFCur_fs;                      //0x0094

  float LPFSpd_fc;                      //0x0098
  float LPFSpd_fs;                      //0x009C

  float ErrRef_IsensorOpen;             //0x00A0
  float ErrRef_IsensorShort;            //0x00A4
  float ErrRef_OverCurrent;             //0x00A8
  float ErrRef_OverSpeed;               //0x00AC
  float ErrRef_OverVoltage;             //0x00B0
  float ErrRef_UnderVoltage;            //0x00B4
  float ErrRef_IsensorOffsetMax;        //0x00B8
  float ErrRef_IsensorOffsetMin;        //0x00BC

  float Inv_Ctrl_VdcLimFweak;           //0x00C0
  float Inv_Ctrl_IlimFweak;             //0x00C4

  float Motor_Ang_RpmLim;               //0x00C8
  float Motor_Ang_SpdCtrlOutLim;        //0x00CC

  float Machine_SensorGearRatio;        //0x00D0
  float Machine_SpoolDiameter;          //0x00D4
  float Machine_MaxWeight;              //0x00D8
  float Machine_CableMaxLength;         //0x00DC
  float Machine_Scale_Weight2Current;   //0x00E0
  float Machine_SoftWindingHeight;      //0x00E4

  float Machine_DefaultWeight;          //0x00E8
  float Machine_FrictionWeight;         //0x00EC
  float Machine_FrictionSpeedPlus;      //0x00F0
  float Machine_FrictionSpeedMinus;     //0x00F4

  uint32_t check;   //FLASH_VALID_CODE  //0x00F8

  uint8_t   unused[SECTOR_SIZE-sizeof(Data_Form_RAM)];
} Data_Form;

////////////////    Public Variables    ///////////////////

extern  EEPROM  Data_Form           Origin_Data;      //EEPROM Area in Flash(1st Sector : 0x08008000)
extern  BACKUP  Data_Form           Backup_Data;      //BACKUP Area in Flash(2nd Sector : 0x0800C000)
extern  const   Data_Form_RAM       Defualt_RAM_Data; //Constants   in Flash(Program Code)
extern          Data_Form_RAM       RAM_Data;         //Buffer Area in RAM  for Protocol

///////////////     Public Functions    //////////////////

#define   EEPROM_Save()   Flash_Write(FLASH_ORIGIN_SECTOR)

void Flash_Init(void);                          //Backup or Restore on Startup
HAL_StatusTypeDef Flash_Write(uint8_t sector);  //Save Flash

#ifdef __cplusplus
}
#endif

#endif /* __FLASH_H_ */
