#include <stdint.h>
#include <xc.h>
#include "structs.h"
#include <math.h>


#define ADC_RES 4096

#define PWR_EN_TRIS TRISBbits.TRISB4
#define PWR_EN_LAT LATBbits.LATB4
#define SIPO_SER_TRIS TRISBbits.TRISB5
#define SIPO_SER_LAT LATBbits.LATB5
#define SIPO_CLK_TRIS TRISBbits.TRISB6
#define SIPO_CLK_LAT LATBbits.LATB6
#define SIPO_LATCH_TRIS TRISBbits.TRISB7
#define SIPO_LATCH_LAT LATBbits.LATB7
#define SCL_OUT_TRIS TRISBbits.TRISB10
#define SCL_OUT_LAT LATBbits.LATB10
#define SDA_IN_TRIS TRISBbits.TRISB11
#define SDA_IN_LAT LATBbits.LATB11
#define SCS_OUT_TRIS TRISBbits.TRISB12
#define SCS_OUT_LAT LATBbits.LATB12
#define REF_OSC_TRIS TRISBbits.TRISB8
#define REF_OSC_LAT LATBbits.LATB8
#define TX_TRIS TRISBbits.TRISB14
#define TX_LAT LATBbits.LATB14
#define RX_TRIS TRISBbits.TRISB15
#define RX_LAT LATBbits.LATB15
#define INT_TRIS TRISBbits.TRISB9
#define INT_LAT LATBbits.LATB9
#define INT_PORT PORTBbits.RB9
#define CURR_VOLT_SW_TRIS TRISBbits.TRISB13
#define CURR_VOLT_SW_LAT LATBbits.LATB13
#define CURR_VOLT_SW_PORT PORTBbits.RB13


#define V_GAIN(x) ((x == 0) ? 1.0 : ((x == 1) ? 10.0 : 100.0))      //determine gain of voltage amplifier from the index determined by the autocalibration
#define V_CAL(x) ((x == 0) ? cal->cal_u1 : ((x == 1) ? cal->cal_u10 : cal->cal_u100))  //assign calibration coefficient to each gain
#define V_GAIN_VRR(x) ((x == 0) ? 0x0 : ((x == 1) ? 0x2 : 0x6 ))    //determine bits that configure hardware amplifier from the index determined by the autocalibration
#define V_PH_CAL(x) ((x == 0) ? cal->ph_cal_u1 : ((x == 1) ? cal->ph_cal_u10 : cal->ph_cal_u100))  //assign calibration coefficient to each gain

#define I_GAIN(x) ((x == 0) ? -10.0 : ((x == 1) ? -100.0 : ((x == 2) ? -1000.0 : -10000.0 )))   //determine gain of current amplifier from the index determined by the autocalibration (voltage amplifier and current amplifier partially overlap)
#define I_CAL(x) ((x == 0) ? cal->cal_i10 : ((x == 1) ? cal->cal_i100 : ((x == 2) ? cal->cal_i1000 : cal->cal_i10000)))  //assign calibration coefficient to each gain (voltage amplifier and current amplifier partially overlap)
#define I_GAIN_IRR(x) ((x == 0) ? 0x5 : ((x == 1) ? 0x2 : ((x == 2) ? 0x4 : 0x8)))  //determine bits that configure hardware amplifier from the index determined by the autocalibration (voltage amplifier and current amplifier partially overlap)
#define I_PH_CAL(x) ((x == 0) ? cal->ph_cal_i10 : ((x == 1) ? cal->ph_cal_i100 : ((x == 2) ? cal->ph_cal_i1000 : cal->ph_cal_i10000)))  //assign calibration coefficient to each gain (voltage amplifier and current amplifier partially overlap)

#define FREQ_PH_CORR(x) ((x == 0) ? 1 : ((x == 0x1) ? 0.1 : (x == 0x2 ? 0.01 : 0.001)))

#define RANGE_ADJ_FILTER 2

#define PI 3.141592654

void init(struct config_struct *config, struct cal_struct *cal, struct cal_struct *cal_flash_pt);
void config_hardware(struct config_struct *config);
void send_hw_conf(struct config_struct config);
void calibration(struct config_struct *config, struct cal_struct *cal, struct cal_struct *cal_flash_pt);
unsigned int  write_cal(void* address, void* data);
unsigned int  erase_cal(void* address);
unsigned  int  NVMUnlock (unsigned int nvmop);
unsigned int nvm_nop (void* address);
