/*
 * interrup_handlers.h
 *
 * Created: 03/03/2021 08:22:26
 *  Author: Nick-XMG
 */ 


#ifndef INTERRUPT_HANDLERS_H_
#define INTERRUPT_HANDLERS_H_

#include "atmel_start.h"
#include "pins.h"
#include "bldc.h"
#include "statemachine.h"

#define DEBUG_1_PORT PORT_PC01
#define DEBUG_2_PORT PORT_PC03
#define DEBUG_3_PORT PORT_PC02
#define DEBUG_4_PORT PORT_PC30


// ----------------------------------------------------------------------
// 	EtherCAT Cycle Timer - 1kHz
// ----------------------------------------------------------------------
void TC7_Handler(void)
{
	if (TC7->COUNT16.INTFLAG.bit.OVF == 0x01) {
		TC7->COUNT16.INTFLAG.bit.OVF = 0x01;
		//One_ms_cycle_callback();
		//gpio_toggle_pin_level(DEBUG_1);
		One_ms_cycle_callback();

	}
}

// ----------------------------------------------------------------------
// 	EtherCAT Cycle Timer - 1kHz
// ----------------------------------------------------------------------
void TC0_Handler(void)
{
	/* Capture Interrupt */
	if (TC0->COUNT32.INTFLAG.bit.MC0 == 0x01) {
		TC0->COUNT32.INTFLAG.bit.MC0 = 0x01;
		//gpio_toggle_pin_level(DEBUG_2);

	}
	/* Overflow Interrupt */
	if (TC0->COUNT32.INTFLAG.bit.OVF == 0x01) {
		TC0->COUNT32.INTFLAG.bit.OVF = 0x01;
		Motor1.motor_status.calc_rpm = 0;
		//gpio_toggle_pin_level(DEBUG_2);

	}
}

// ----------------------------------------------------------------------
// 	ADC Callback for Motor Phase Current Measurement.  
// Phase A & B Sampled and converted from LSB to Process Unit PU(Amps)
// ----------------------------------------------------------------------
static void adc_cb(const struct adc_async_descriptor *const descr, const uint8_t channel)
{
	tic_port(DEBUG_2_PORT);
	//tic(DEBUG_1);
	// Filter Out low level noise
	inline void filter_convert_to_pu(int16_t *phase, float32_t *phase_filtered_pu)
	{
		/*
		if(*phase <= 20 && *phase >= -20 ) *phase_filtered_pu = 0.0f;
		else(*phase_filtered_pu = (float32_t)(*phase * ADC_LSB_SIZE * ONEON_CURRENT_SENSOR_SENSITIVITY));
		*/
		
		*phase_filtered_pu = (float32_t)(*phase * ADC_LSB_SIZE * ONEON_CURRENT_SENSOR_SENSITIVITY);
	}
	volatile int16_t phase_A_current_raw = hri_adc_read_RESULT_reg(descr->device.hw) - Motor1.Voffset_lsb.A;  //Read ADC 0
	volatile int16_t phase_B_current_raw = (hri_adc_read_RESULT_reg(ADC1) - Motor1.Voffset_lsb.B)*-1;	//Ib is connected backwards //Read ADC 1, synced with ADC0
	
	// Covert from LSB to PU (A) and filter out small readings
	filter_convert_to_pu(&phase_A_current_raw, &Motor1.Iphase_pu.A); 
	filter_convert_to_pu(&phase_B_current_raw, &Motor1.Iphase_pu.B);
	// i_c = -i_a - i_b because i_a + i_b + i_c = 0
	Motor1.Iphase_pu.C = -Motor1.Iphase_pu.A - Motor1.Iphase_pu.B;
	// Select phase based on Hall State
	//select_active_phase(Motor1.hall_state, &Motor1); 
	// Set Current Loop Flag
	Motor1.timerflags.current_loop_tic = true;
	//toc(DEBUG_1);
	toc_port(DEBUG_2_PORT);
}

// ----------------------------------------------------------------------
// 	ADC Callback for Motor Phase Current Measurement.
// Phase A & B Sampled and converted from LSB to Process Unit PU(Amps)
// ----------------------------------------------------------------------
static void pwm_cb(const struct pwm_descriptor *const descr)
{
	Motor1.timerflags.pwm_cycle_tic = true;
}

static void HW_current_limit_detect_callback(void)
{
	//applicationStatus.currentstate = FAULT;
    //applicationStatus.fault = OVERCURRENT;
	
}


#endif /* INTERRUPT_HANDLERS_H_ */