/*
 * configuration.h
 *
 * Created: 02/08/2021 21:15:49
 *  Author: Nick-XMG
 */ 


#ifndef CONFIGURATION_H_
#define CONFIGURATION_H_

// ----------------------------------------------------------------------
// Header Files
// ----------------------------------------------------------------------
#include "atmel_start_pins.h"
#include "bldc.h"
#include "interrupts.h"

#define DMAC_CHANNEL_ADC_SEQ 2U
#define DMAC_CHANNEL_ADC_SRAM 3U


// ----------------------------------------------------------------------
// M1_IA=ADC1_AIN[9], M1_IB=ADC1_AIN[8], M2_IA=ADC1_AIN[7], M2_IB=ADC1_AIN[6]
// ----------------------------------------------------------------------
/* Single Ended */
//const uint32_t adc_seq_regs[4]	= {0x1807, 0x1806, 0x1809, 0x1808};
/* Differential */
const uint32_t adc_seq_regs[4]	= {0x0089, 0x0088, 0x0087, 0x0086};

volatile int16_t adc_res[4]	= {0};
struct _dma_resource *adc_sram_dma_resource;
struct _dma_resource *adc_dmac_sequence_resource;

inline static void configure_tcc_pwm(void)
{
	//gpio_set_pin_pull_mode(M1_HALLA, GPIO_PULL_UP);
	//gpio_set_pin_pull_mode(M1_HALLB, GPIO_PULL_UP);
	//gpio_set_pin_pull_mode(M1_HALLC, GPIO_PULL_UP);
	//gpio_set_pin_pull_mode(M2_HALLA, GPIO_PULL_UP);
	//gpio_set_pin_pull_mode(M2_HALLB, GPIO_PULL_UP);
	//gpio_set_pin_pull_mode(M2_HALLC, GPIO_PULL_UP);
	
	/* TCC0 */
	hri_tcc_set_WEXCTRL_OTMX_bf(TCC0, 0x02);
	
	hri_tcc_set_WAVE_POL0_bit(TCC0);
	hri_tcc_set_WAVE_POL1_bit(TCC0);
	hri_tcc_set_WAVE_POL2_bit(TCC0);
	hri_tcc_set_WAVE_POL3_bit(TCC0);
	hri_tcc_set_WAVE_POL4_bit(TCC0);
	hri_tcc_set_WAVE_POL5_bit(TCC0);
	hri_tcc_write_CC_CC_bf(TCC0, 0, 0);
	hri_tcc_write_CC_CC_bf(TCC0, 1, 0);
	hri_tcc_write_CC_CC_bf(TCC0, 2, 0);
	hri_tcc_write_CC_CC_bf(TCC0, 3, 0);
	hri_tcc_write_CC_CC_bf(TCC0, 4, 0);
	hri_tcc_write_CC_CC_bf(TCC0, 5, 0);
	hri_tcc_write_PER_reg(TCC0,1200);
	//hri_tcc_write_CCBUF_CCBUF_bf(TCC0, 0,250);
	hri_tcc_write_CTRLA_ENABLE_bit(TCC0, 1 << TCC_CTRLA_ENABLE_Pos);	
	
	/* TCC1 */
	hri_tcc_set_WEXCTRL_OTMX_bf(TCC1, 0x02);
	hri_tcc_write_CC_CC_bf(TCC1, 0, 0);
	hri_tcc_write_CC_CC_bf(TCC1, 1, 0);
	hri_tcc_write_CC_CC_bf(TCC1, 2, 0);
	hri_tcc_write_CC_CC_bf(TCC1, 3, 0);
	hri_tcc_write_CC_CC_bf(TCC0, 4, 0);
	hri_tcc_write_CC_CC_bf(TCC0, 5, 0);
	//
	////pwm_set_parameters(&TCC_PWM, 1000, 250);
	hri_tcc_set_WAVE_POL0_bit(TCC1);
	hri_tcc_set_WAVE_POL1_bit(TCC1);
	hri_tcc_set_WAVE_POL2_bit(TCC1);
	hri_tcc_set_WAVE_POL3_bit(TCC1);
	hri_tcc_set_WAVE_POL4_bit(TCC1);
	hri_tcc_set_WAVE_POL5_bit(TCC1);
	
	hri_tcc_write_PER_reg(TCC1,1200);
	//hri_tcc_write_CCBUF_CCBUF_bf(TCC1, 0, 250);
	hri_tcc_clear_CTRLA_ENABLE_bit(TCC1);
	hri_tcc_write_CTRLA_MSYNC_bit(TCC1, true);
	//hri_tcc_write_CTRLA_ENABLE_bit(TCC1, 1 << TCC_CTRLA_ENABLE_Pos); /* Enable: enabled */
	
	//pwm_register_callback(&PWM_0, PWM_PERIOD_CB, pwm_cb);
	pwm_enable(&PWM_0);
	pwm_enable(&PWM_1);

}

inline void configure_adc(void)
{
	adc_sync_enable_channel(&ADC_1, 0);
	//adc_sync_enable_channel(&ADC_1, 0);
	//adc_async_register_callback(&ADC_0, 0, ADC_ASYNC_CONVERT_CB, adc_cb);
	//adc_async_register_callback(&ADC_1, 0, ADC_ASYNC_CONVERT_CB, convert_cb_ADC_1);
	//adc_async_start_conversion(&ADC_0);
	//adc_async_start_conversion(&ADC_1);
}

inline static void adc_init_dma(void)
{
	adc_sram_dmac_init();
	adc_dmac_sequence_init();
	hri_adc_set_DSEQCTRL_INPUTCTRL_bit(ADC1);
	hri_adc_set_DSEQCTRL_AUTOSTART_bit(ADC1);
}

inline void adc_dmac_sequence_init()
{
	/* Configure the DMAC source address, destination address,
	 * next descriptor address, data count and Enable the DMAC Channel 
	 */
	_dma_set_source_address(DMAC_CHANNEL_ADC_SEQ, (const void *)adc_seq_regs);
	_dma_set_destination_address(DMAC_CHANNEL_ADC_SEQ, (const void *)&ADC1->DSEQDATA.reg);
	_dma_set_data_amount(DMAC_CHANNEL_ADC_SEQ, 4);
	_dma_set_next_descriptor(DMAC_CHANNEL_ADC_SEQ, DMAC_CHANNEL_ADC_SEQ);
	_dma_enable_transaction(DMAC_CHANNEL_ADC_SEQ, false);
	//_dma_get_channel_resource(&adc_dmac_sequence_resource, DMAC_CHANNEL_ADC_SEQ);
	//adc_dmac_sequence_resource[0].dma_cb.error = dummy2;
	//adc_dmac_sequence_resource[0].dma_cb.suspend = dummy3;
	//adc_dmac_sequence_resource[0].dma_cb.transfer_done = dummy4;
	hri_dmacchannel_set_CHCTRLB_CMD_bf(&DMAC->Channel[DMAC_CHANNEL_ADC_SEQ], 0x01);	//Suspend
}

inline void adc_sram_dmac_init()
{
	/* Configure the DMAC source address, destination address,
	 * next descriptor address, data count and Enable the DMAC Channel */
	_dma_set_source_address(DMAC_CHANNEL_ADC_SRAM, (const void *)&ADC1->RESULT.reg);
	_dma_set_destination_address(DMAC_CHANNEL_ADC_SRAM, (const void *)adc_res);
	_dma_set_data_amount(DMAC_CHANNEL_ADC_SRAM, 4);
	_dma_set_irq_state(DMAC_CHANNEL_ADC_SRAM, DMA_TRANSFER_COMPLETE_CB, true);
	_dma_get_channel_resource(&adc_sram_dma_resource, DMAC_CHANNEL_ADC_SRAM);
	adc_sram_dma_resource[0].dma_cb.transfer_done = adc_sram_dma_callback;
	_dma_set_next_descriptor(DMAC_CHANNEL_ADC_SRAM, DMAC_CHANNEL_ADC_SRAM);
	_dma_enable_transaction(DMAC_CHANNEL_ADC_SRAM, false);
}



#endif /* CONFIGURATION_H_ */