/* ************************************************************************** */
/** Descriptive File Name

  @Company
    Company Name

  @File Name
    Inductor_Tester.h

  @Summary
    Main inductor tester state machine.

  @Description
    Describe the purpose of this file.
 */
/* ************************************************************************** */

#ifndef _EXAMPLE_FILE_NAME_H    /* Guard against multiple inclusion */
#define _EXAMPLE_FILE_NAME_H


/* ************************************************************************** */
/* ************************************************************************** */
/* Section: Included Files                                                    */
/* ************************************************************************** */
/* ************************************************************************** */

/* This lists the other files that are included in this file.
 */

/* TODO:  Include other files here if needed. */


/* Provide C++ Compatibility */
#ifdef __cplusplus
extern "C" {
#endif

#include <stdbool.h>
    
#define Splash_String_0  (unsigned char *)"  Silicon Chip  "
#define Splash_String_1  (unsigned char *)"                "
#define Version_String   (unsigned char *)"Ver 1.2 2024-12 "
#define Blank            (const char *)"                "

#define Use_String_0  (unsigned char *)"Up/Dn for Mode  "
#define Use_String_1  (unsigned char *)"Enter to select "   
    
#define HeartbeatCountInit 10000  /* a biggish number but nmot massive */
    
#define Splash_Time_ms 1500
#define Splash_Version_Time_ms 500

/* Interface Related Defines */
#define Up !Up_Get()                                /* pora B bit 1 */
#define Down !DOWN_Get()                            /* pora B bit 6 */
#define Enter_Key_Pressed !START_Get()              /* pora A bit 8 */
#define Exit_Key_Pressed !SPARE_GPIO_Get()          /* pora C bit 13 */

#define Let_Up_Dn_Settle CORETIMER_DelayMs(400);   /* Let buttons settle */
#define Let_Bounce_Settle CORETIMER_DelayMs(200);   /* Let buttons settle */
#define CAL_Message_Time CORETIMER_DelayMs(2500);   /* Let buttons settle */
#define CAL_Settle_Time CORETIMER_DelayMs(150);     /* Delay after current set */
#define CAL_1A_Ontime 30                            /* tenths of s second */
#define CAL_1A_Offtime 60                           /* tenths of s second */
    
    
#define Bad_News_Time                    3000 //Make user look at the bad news for 3 seconds
#define Stored_Data_Read_Error_0         (const char *)"Data read error "
#define Stored_Data_Read_Error_1         (const char *)"Using defaults  "
#define SPI_Error_1                      (const char *)"TGM Says: Oops  "
#define SPI_Error_2                      (const char *)"SPI Read Error  "
    
//SPI EEPROM Stuff
#define CselEEPROM DelayUs(1); SPI_SS2_Clear(); DelayUs(1);
#define CselClearEEPROM DelayUs(1); SPI_SS2_Set(); DelayUs(1);
#define EEPROM_INIT_DELAY 10
#define EEPROM_Sel_Delay 2

//DAC Stuff
//SPI EEPROM Stuff
#define CselDAC DelayUs(1); SPI_SS1_Clear(); DelayUs(1);
#define CselClearDAC DelayUs(1); SPI_SS1_Set(); DelayUs(1);
#define DAC_LDAC_Assert DelayUs(1); LDAC_L_Clear(); DelayUs(1);
#define DAC_LDAC_lear DelayUs(1); LDAC_L_Set(); DelayUs(1);   
    
//ADC Stuff
/* Each ADC result takes 2 bytes. Reserve space for Buffer A and Buffer B. */
#define Buffer_Size 128
#define Half_Buffer_Size 128
#define ADC_Sample_Offfset (Buffer_Size * 2)   // offset of channel 1 from base of DMA
    
#define DMA_BUFA_FULL  (0x00000002) // this is specific to the PIC32MK - ASDCDSTAT bit 2
#define DMA_BUFB_FULL  (0x00020000)  // this is specific to the PIC32MK  - ASDCDSTAT bit 17    
#define DMA_BUFA_FULL_INT_EN  (0x00000200) // this is specific to the PIC32MK  - ASDCDSTAT bit 9
#define DMA_BUFB_FULL_INT_EN  (0x02000000)  // this is specific to the PIC32MK  - ASDCDSTAT bit 25
#define DMA_INT_EN  (DMA_BUFA_FULL_INT_EN  |  DMA_BUFB_FULL_INT_EN)   
    
#define  ADC_MAX_COUNT 4095
#define ADC_Buffer_Timeout_ms 100  /* this is for ever...*/
#define VSense_Divider_Top  10000.0
#define VSense_Divider_Bottom 4700.0
#define ERROR_Volts 666.666    
#define INA281_Gain 20.0   
#define Num_DMA_Buffers 100
#define Num_DMA_Buffers_LTest ((Num_DMA_Buffers)/2)
#define Meas_Buffer_Size (Buffer_Size * Num_DMA_Buffers) // 12800 samples
#define Half_Meas_Buffer_Size ((Buffer_Size * Num_DMA_Buffers)/2) // 12800 samples
#define Precharge_Counter_Overflow 3750000 // this seems reasonable
    
    
/* capacitance Meas_Stuff */
#define Cap_Meas_Max_Voltage     2.5         //This is "big enough" but well within the 3.3v range
#define Cap_Meas_Voltage_ADC_Val (int)((Cap_Meas_Max_Voltage * ADC_MAX_COUNT)/LTestData.ADC_Full_Scale_V)        // hard code this to be SURE it is optimised in compile
                                             // Which is 4095*2/3.3
#define Cap_Meas_Min_Voltage     0.3         //This is 300mV
#define Cap_Meas_Min_Threshold   (int)((Cap_Meas_Min_Voltage*ADC_MAX_COUNT)/LTestData.ADC_Full_Scale_V)         //This is 300mV
#define Cap_Meas_Min_Samples    20          // Minimum number of samples for cap measurement
#define Cap_Meas_Lower_Limit 50E-9          // 50nF is too low to be accurate    
/* resistance Meas_Stuff */
    
/* Inductance Meas_Stuff */
/* the ConstI threshold is looking only at the constant current source */
/* being saturated or not - remember that a constantr current source   */
/* will drive an "infinite" coltage across an inductor until the current */
/* thruogh the inductor reaches the porgrammed current, at which time  */
/* the voltage will fall to the I*R value                              */    
#define Inductance_Measurement_ConstI_Start_Threshold 2.5  
#define Inductance_Measurement_ConstI_End_Threshold 2.5
#define Inductance_Measurement_ConstI_Saturated     3.0
#define Inductance_Test_Nominal_Voltage 8.0    
#define Inductance_Measurement_ConstI_Buffer_Start_Ratio 0.25 // Use the forst 90% of the biffer   
#define Inductance_Measurement_ConstI_Buffer_End_Ratio 0.75  // Use the forst 90% of the biffer   
#define TIP121_Sat_At_1A   0.7
#define Inductance_Measurement_Max_Resistance 6    // set 3 ohms as max resistance    
#define Inductance_Measurement_Rail_Meas_Settle 50 //milliseconds
#define Inductance_Meas_Lower_Limit 50E-6          // 50uH is too low to be accurate  
    
/* Saturation Point Measurement Stuff */
#define Time_To_Check_If_Cap 100 // number of mS to run current for     
#define Wait_To_Check_If_Cap CORETIMER_DelayMs (Time_To_Check_If_Cap)    
#define T1_Ms 100 // number of mS to run current for     
#define Wait_T1 CORETIMER_DelayMs (T1_Ms)    
#define T2_Ms 100 // number of mS to run current for     
#define Wait_T2 CORETIMER_DelayMs (T1_Ms)    
#define Power_Diss_In_CapTest 0.1 // this si watts which will be dissipated for 100ms
#define T1_Voltage_Threshold_For_Cap  0.1  
#define Peak_Test_Current_of_V_R 0.5  //ratio n of V/I current fopr peak in test    
#define Max_Test_Current    30.0 //Amps    
#define Capture_Buffer_Oversize 1.5 // add extra time for initial buffer to capture slow Irise     
#define Cutoff_Current_Stabilise CORETIMER_DelayUs(50);
#define Initial_Current_Sense_Ratio_Low_Inductance 0.05 // 20% of max current
#define Initial_Current_Sense_Ratio_High_Inductance 0.05 // 10% of max current
#define Saturation_Current_Test_Low_Inductance_Threshold 0.00015
#define Final_Current_Sense_Ratio 0.9 // 90% of max current
#define ADC_To_Amps_Sat (LTestData.ADC_Full_Scale_V /(ADC_MAX_COUNT*INA281_Gain * Current_Sense_Resistance))    
#define Const_Current_Source_Bias_Current 0.075 // set this to 75mA - this generates 0.075*0.005*20 = 7.5mV offset on the current sense IC and gets it into its linear region
#define Time_For_PSU_To_Settle CORETIMER_DelayMs(100);
#define Num_Sat_Samples 10 
#define High_Gain_Current_Scale 0.9403  //voltage divider comprised of 470R series with 4k7+2k7 voltage divider
// *****************************************************************************
// *****************************************************************************
// Application states
//  Summary:
//  The first set are Application states enumeration
//  Description:
//    This enumeration defines the valid application states.  These states
//    determine the behavior of the application at various times.
//
// *****************************************************************************
// *****************************************************************************
typedef enum
{
	/* Application's state machine's initial state. */
	Inductor_Tester_STATE_INIT=0,
	Inductor_Tester_STATE_LCDINIT,
	Inductor_Tester_STATE_CAL_SEL,
	Inductor_Tester_STATE_CAL,
    Inductor_Tester_STATE_IDLE,
    Inductor_Tester_STATE_MEASURE_CAP,
    Inductor_Tester_STATE_MEASURE_RES,
    Inductor_Tester_STATE_MEASURE_IND,
    Inductor_Tester_STATE_MEASURE_IND_SAT,
    Inductor_Tester_STATE_CHECK_DUT,
    Inductor_Tester_STATE_ERROR

} Inductor_Tester_STATES;

// *****************************************************************************
// *****************************************************************************
// Measurement Actions
//  Summary:
//  Description:
//    This enumeration defines the valid measurements that can be
//    made from the idle state.
//
// *****************************************************************************
// *****************************************************************************
typedef enum
{
	/* Application's measurement actions. */
	Measurement_Idle=0,
    Measurement_Resistance,
    Measurement_Capacitance,
    Measurement_Inductance_I,
    Measurement_Inductance_Sat,
    Measurement_ERROR
} Measurement_Action;



/* User Interface Actions*/
typedef enum
{
	/* Application's state machine's initial state. */
	UIAction_NULL = 0,
	UIAction_Up,            
	UIAction_Down,
   	UIAction_Enter,
   	UIAction_Exit
} UI_ACTIONS;


// *****************************************************************************
/* Application Data

  Summary:
    Holds Digital_Preamp application data

  Remarks:
    Application strings and buffers are defined outside this structure.
 */
// *****************************************************************************
// *****************************************************************************

typedef struct
{
    /* The application's current state */
    Inductor_Tester_STATES      state;                  /* UI driver timer handle. */
    Measurement_Action          Meas_Action;            /* Measurement to make... */
    int                         heartbeatToggle;        /* Flag for heartbeat */
    int                         heartbeatCount;         /* Counter for heartbeat */
    int                         Revert_To_Idle_Counter; /* used as flag for reverting state to idle */
    int                         UI_Update_Display;      /* UI needs update */
    int                         UI_Keypressed;          /* UI action */
    int                         Up_Key;                 /* Up key value */
    int                         Down_Key;               /* Down key value */
    int                         Spare_GPIO_Key;         /* Spare key value */
    int                         Start_Key;              /* Start key value */
    int                         UI_Slow_Count;          /* ui counter */
    int                         TEMP_DATA;              /* scratch */
    int                         TEMP_DATA1;              /* scratch */
    int                         MemoryBankSelected;     /* Will have several memory Banks available when you finish this ;) */
    float                       Test_Current_Resistor;  /* This is the value used for the test current resistance - nominally 1Ohm*/
    float                       Current_Meas_Resistor;  /* Current shunt resistance - Nominally 0.005 Ohms */
    float                       ISet_CAL_10mA;          /* ISet Cal at 10mA */
    float                       ISet_CAL_100mA;         /* ISet Cal at 10mA */
    float                       ISet_CAL_1A;            /* ISet Cal at 1A */
    float                       Cap_Cal_Low_Range;      /* Null zero capacitance */
    float                       ADC_Full_Scale_V;       /* ADC Reference Voltage - 3.3 analogue voltage V */
    float                       DAC_Full_Scale_V;       /* DAC Reference Voltage - 2.048 analogue voltage V */
    float                       ADC_Ch0[Buffer_Size];
    float                       ADC_Ch1[Buffer_Size];
    float                       V_Meas_1us;             /* Voltage at 1us */
    float                       V_Meas_10us;            /* Voltage at 10us */
    float                       V_Meas_100us;           /* Voltage at 100us */
    float                       V_Meas_1ms;             /* Voltage at 1ms */
    float                       V_Meas_10ms;            /* Voltage at 10ms */
    float                       V_Meas_100ms;           /* Voltage at 100ms */
    float                       V_Meas_1000ms;          /* Voltage at 1000ms */
    uint16_t                    Meas_Buffer[Meas_Buffer_Size];     /* buffer for measured data */
    bool                        DUT_Is_Resistor;
    bool                        DUT_Is_Capacitor;
    bool                        DUT_Is_Inductor;
    bool                        Valid_DC_Resistance;    /* We have a valid resistance */
    float                       Measured_DC_Resistance; /* exactly that */
    bool                        Valid_Capacitance;      /* we have a valid measured Cap */
    float                       Measured_10pc_Sat_I;    /* current at which inductance has fallen 10% */
    float                       Measured_20pc_Sat_I;    /* current at which inductance has fallen 20% */
    bool                        Valid_Sat_I;            /* we have a valid sdaturation current */
    float                       Measured_Const_I_Cap;   /* capacitance measured using constant current */
    bool                        Valid_Const_I_Ind;      /* we have a valid inductance */
    float                       Measured_Const_I_Ind;   /* Inductance measured using constant current */
    bool                        Valid_Const_V_Ind;      /* we have a valid inductance */
    float                       Measured_Const_V_Ind;   /* Inductance measured using constant voltage */
    float                       Measured_Current_for_Reduced_Ind;   /* Inductance measured using constant voltage */
    float                       Measured_Sat_Current_Results[2][Num_Sat_Samples];   /* Inductance measured using constant voltage */
    bool                        Next_Range;             /* meas next range */ 
    float                       Scratch;                /* convenient scratch data */
    float                       Test_Rail_V_Meas;       /* MEasured test rail voltage */
    int                         Inductance_Sat_Step;    /* step over measurement range for inductance */
    float                       Inductance_At_Step;     /* inductance at the step we are looking at */

} Inductor_Tester_DATA;

/* This is where all the data is stored... */
extern Inductor_Tester_DATA LTestData;
extern __attribute__((coherent)) uint16_t adcResultBuffer[2][2][Buffer_Size];
extern __attribute__((coherent)) uint8_t adcSampleCntBuffer[2][2];    
extern volatile int bufferA_Full;
extern volatile int bufferB_Full;
extern uint16_t *Meas_Ptr;
extern uint16_t *Meas_Ptr_Rst; 
extern int Meas_Buffer_Full;

/***************************************************/
/* Storage related in the hardware implementation  */
/* Stuff to allow memory bank in use to be tracked */
/***************************************************/
#define Mem_Banks_Do_Not_Erase      3
#define Mem_Banks_Erase             4
#define Max_Mem_Banks_With_Erase    4
#define Max_Mem_Banks               2
#define Default_Mem_Bank            0
#define Clear_Buffers_SPI_Time      3

/* How big is each set of data in ROM?*/
#define ParmSet_Array_Size          0x0800
/* Approx EEPROM write delay in mS */
#define EEPROM_WR_Delay             10   
/* Approx EEPROM write delay in mS */
#define DAC_RESET_Delay             50   

/* These offsets are within each band block */
#define Test_Resistor_Offset        0X0000
#define Meas_Resistor_Offset        0X0004
#define DAC_ISet_Zero_OP_Offset     0X0008
#define DAC_ISet_CAL_10mA_Offset    0X000C
#define DAC_ISet_CAL_1A_Offset      0X0010
#define DAC_ICutoff_Zero_Offset     0X0014
#define DAC_ICutoff_1900mV_Offset   0X0018
#define Temp_Data_Offset            0X001C
#define ADC_Full_Scale_V_Offset     0X0020
#define DAC_Full_Scale_V_Offset     0X0024
#define DAC_ISet_CAL_100mA_Offset   0X0028
#define Cap_Cal_Low_Range_Offset    0X0032

/* Measurement Stuff */
#define Test_Resistor_Default 1.0           /* Ohms */
#define Test_Resistor_Min 0.8               /* minimum Ohms */
#define Test_Resistor_Max 1.2               /* maximjm Ohms */
#define Measurement_Resistor_Default 0.005  /* Ohms */
#define Measurement_Resistor_Min 0.004      /* maximum Ohms */
#define Measurement_Resistor_Max 0.006      /* maximum Ohms */
#define DAC_ISet_10mA_Cal           0.010   /* 10mA (boost this)*/
#define DAC_ISet_10mA_Cal_Step      0.0001  /* this is fairly small */
#define DAC_ISet_10mA_Cal_Default   0.013   /* will use this at initial boot */
#define DAC_ISet_10mA_Cal_Min   0.007       /* Less than this and we have trouble */
#define DAC_ISet_10mA_Cal_Max   0.016       /* More than this and we have trouble */
#define DAC_ISet_100mA_Cal           0.1    /* 100mA */
#define DAC_ISet_100mA_Cal_Step      0.0001                                                                                                                                                                                                                                                                                                                                                                                                                                                                               /* this is fairly small */
#define DAC_ISet_100mA_Cal_Default   0.1    /* Will use this at initial boot */
#define DAC_ISet_100mA_Cal_Min   0.08       /* Less than this and we have trouble */
#define DAC_ISet_100mA_Cal_Max   0.12       /* more than this and we have trouble */
#define DAC_ISet_1A_Cal         1.0         /* 1A */
#define DAC_ISet_1A_Cal_Step    0.001        /* this is fairly small */
#define DAC_ISet_1A_Cal_Default 1.0         /* Will use this at initial boot */
#define DAC_ISet_1A_Cal_Min     0.8         /* Less than this and we have trouble */
#define DAC_ISet_1A_Cal_Max     1.2         /* More than this and we have trouble */
#define Cap_Low_Range_Cal_Default 0.000000042 /* This was seen on the proto */
#define Cap_Low_Range_Cal_Min     0.0000000001  /* Need something... */
#define Cap_Low_Range_Cal_Max     0.000000080   /* Need something */
#define Cap_Low_Range_Cal_Step    0.000000001  /* inF steps */
#define DAC_ICutoff_Zero_Step   0.0001      /* V */
#define DAC_ICutoff_Zero_Default 0.0        /* V */
#define DAC_ICutoff_Zero_Min 0.0            /* V */
#define DAC_ICutoff_Zero_Max 0.015          /* V */
#define DAC_ICutoff_1900mV_Step 0.001       /* V */
#define DAC_ICutoff_1900mV_Default 1.900    /* V */
#define DAC_ICutoff_1900mV_Min 1.800        /* V */
#define DAC_ICutoff_1900mV_Max 2.000        /* V */
#define ADC_Full_Scale_V_Step   0.001       /* V */
#define ADC_Full_Scale_V_Min    2.900       /* V */
#define ADC_Full_Scale_V_Max    3.500       /* V */
#define ADC_Full_Scale_V_Default 3.300      /* V */
#define DAC_Full_Scale_V_Min    1.950       /* V */
#define DAC_Full_Scale_V_Max    2.15       /* V */
#define DAC_Full_Scale_V_Default 2.048      /* specced internal reference - update from cal */

/*  Limit Values for Data Structures  */
#define	TEMP_DATA_Min 0             /* Hz */
#define	TEMP_DATA_Max 666           /* Hz */
#define	Fl_Min 10                   /* Hz */
#define Fl_Step 1                   /* Hz */
#define	Fl_Max 20000                /* Hz */
#define	Fu_Min 10                   /* Hz */
#define Fu_Step 1                   /* Hz */
#define	Fu_Max 20000                /* Hz */
#define Sl_Step 1

/* Can't believe I have to define this!!! */
#define Pi (double) 3.141592653590
#define sqrt2 (double) 1.414213562373

/***************************************************/
//  User interface behaviour control
// These define how long before increments on the rotary encoder go from
// "slow increments" to fast increments
// then how lond before "fast" reverts to "slow" again
/***************************************************/
#define debounce_time_us 3000
#define Speed_Init     1
#define Revert_To_Idle 6660000    /* About 10s delay before retuirns to idle */
#define Key_Press_Delay_Us 150
#define Delay_After_Save_Ms    500
//#define	Temp_Normal_Speed   1     /* Seems like a sensible number*/
//#define	Temp_Speed          10     /* Seems like a sensible number*/
#define Disable_Interrupts_During_Proc     GPIO_PinInterruptDisable(GPIO_PIN_RC7); TMR1_InterruptDisable();
#define Re_enable_Interrupts               GPIO_PinInterruptEnable(GPIO_PIN_RC7); TMR1_InterruptEnable();

/* Some defines */
//void UI_InterruptHandler(uint32_t intCause, uintptr_t context);
void LCD_Boot(void);
void LCD_Splash_Screen(void);
void Inductor_Tester_Tasks(void);
void handleState_MEASURE_CAP(void); 
void Idle_Screen();


    /* Provide C++ Compatibility */
#ifdef __cplusplus
}
#endif

#endif /* _EXAMPLE_FILE_NAME_H */

/* *****************************************************************************
 End of File
 */
