#include   <string.h>
#include "Speaker.h"

/***************************************************************
copyright from private LiuXiao
if you have any question,you can contact me by email 461445092@qq.com
2022-10-05 17:56:24.020233
***************************************************************/
speaker_queue_str  speaker_queue;
Speaker_main_e_typ speaker_main_state_str;
STATE_UINT16       speaker_cycle_u16;
speaker_ctrl_Str   speaker_ctrl_buf_str;
static uint8_t DAC_Initialize_status = 0;
static uint8_t DAC_Initialize_RetryCnt = 3;
/************************************
Get Sw Fifo empty condition
************************************/

uint8_t speaker_queue_is_empty(void)
{
	uint8_t fl_temp_U8;
	__disable_irq();
	if(speaker_queue.queue_in == speaker_queue.queue_out)
	{
		fl_temp_U8 = TRUE;
	}
	else
	{
		fl_temp_U8 = FALSE;
	}
	__enable_irq();
	return fl_temp_U8;
}

/************************************
Get Sw Fifo Full condition
************************************/

uint8_t speaker_queue_is_full(void)
{
	uint8_t fl_temp_U8;
	__disable_irq();
	fl_temp_U8 = (speaker_queue.queue_in + 1) % (sizeof(speaker_queue.queue)/sizeof(speaker_queue.queue[0]));
	if(fl_temp_U8 == speaker_queue.queue_out)
	{
		fl_temp_U8 = TRUE;
	}
	else
	{
		fl_temp_U8 = FALSE;
	}
	__enable_irq();
	return fl_temp_U8;
}


/************************************
Push a element data to queue
************************************/

uint8_t speaker_queue_push_e(speaker_ctrl_Str fl_str_e)
{
	uint8_t fl_temp_U8;
	
	if(TRUE == speaker_queue_is_full())
	{
		return FALSE;
	}
	else
	{
	
		__disable_irq();
		fl_temp_U8 = (speaker_queue.queue_in + 1) % (sizeof(speaker_queue.queue)/sizeof(speaker_queue.queue[0]));
		speaker_queue.queue_in = fl_temp_U8;
		speaker_queue.queue[fl_temp_U8]  = fl_str_e;
		__enable_irq();
		return TRUE;
	}
}


/************************************
Get  Data from Rx Sw Fifo
return: TRUE->OK    FALSE->Fail
************************************/

uint8_t speaker_queue_pull_e(speaker_ctrl_Str *fl_str_e)
{
	uint8_t fl_temp_U8;

	if(TRUE == speaker_queue_is_empty())
	{
		return FALSE;
	}
	else
	{
	    __disable_irq();
		fl_temp_U8 = (speaker_queue.queue_out + 1) % (sizeof(speaker_queue.queue)/sizeof(speaker_queue.queue[0]));
		speaker_queue.queue_out = fl_temp_U8;
		fl_str_e[0] = 	speaker_queue.queue[fl_temp_U8];
	
		__enable_irq();

		return TRUE;
	}
}

/************************************
uart init
************************************/

void speaker_Init(void)
{
	SA51024_Init();
	memset(&speaker_queue,0,sizeof(speaker_queue));	
	speaker_main_state_str = SPEAKER_INIT;
	DAC_Initialize_RetryCnt = 0x03;
	DAC_Initialize_status = 0;
}

/*
para level 0~3,other value force set to 3
return void
*/
/*level  ->0  ------ 1 ----------2 ---------3*/
/*gain0/1->00 ------ 10----------01---------11*/

void speaker_set_strenght(FA51024_ctrl_e_typ level)
{
	
	//PORT_PinWrite(PORT_PIN_PA13,1);/*SHUTDOWN = 1，turn on chip*/

	if(level == SA51024_STRENGTH_LEVEL0)
	{
		PORT_PinWrite(PORT_PIN_PB14,0);/*GAIN1*/
		PORT_PinWrite(PORT_PIN_PB15,0);/*GAIN0*/
	}
	else if(level == SA51024_STRENGTH_LEVEL1)
	{
		PORT_PinWrite(PORT_PIN_PB14,0);/*GAIN1*/
		PORT_PinWrite(PORT_PIN_PB15,1);/*GAIN0*/
	}
	else if(level == SA51024_STRENGTH_LEVEL2)
	{
		PORT_PinWrite(PORT_PIN_PB14,1);/*GAIN1*/
		PORT_PinWrite(PORT_PIN_PB15,0);/*GAIN0*/
	}
	else
	{
		PORT_PinWrite(PORT_PIN_PB14,1);/*GAIN1*/
		PORT_PinWrite(PORT_PIN_PB15,1);/*GAIN0*/
	}
}

/*
speaker main control state task
*/
void  speaker_MainTask(void)
{
	speaker_ctrl_Str fl_str_e;
	

	switch(speaker_main_state_str)
	{
		case SPEAKER_INIT:
				//SA51024_Set_State(SA51024_STOP,speaker_ctrl_buf_str.strenght);
				PORT_PinWrite(PORT_PIN_PA13,0);/*SHUTDOWN = 1，turn on chip*/
                PORT_PinWrite(PORT_PIN_PA25,0);
				speaker_set_strenght(SA51024_STRENGTH_LEVEL0);
				speaker_main_state_str = SPEAKER_INIT_CYCLE;
				speaker_cycle_u16 = 0;
		break;
		case SPEAKER_INIT_CYCLE:
		    if(speaker_cycle_u16++ >= 10)//20ms
			{
				DAC_Initialize_status = 0x01;
			}

			if(speaker_cycle_u16++ >= ((SPEAKER_INTERVAL_CYCLE_TIMES)/(SPEAKER_TASK_PERIOD)))
			{
				DAC_REGS->DAC_CTRLA &= ~DAC_CTRLA_ENABLE_Msk;
               PORT_PinGPIOConfig(PORT_PIN_PA02);
                speaker_main_state_str = SPEAKER_IDLE;
			}
		break;
		case SPEAKER_IDLE:
            //SA51024_TRIG_ADC(2047);
            PORT_PinWrite(PORT_PIN_PA25,0);
			if(TRUE == speaker_queue_pull_e(&fl_str_e))
			{
				speaker_ctrl_buf_str = fl_str_e;
				speaker_main_state_str = SPEAKER_SET_STRENGHT;
			}
		break;

		case SPEAKER_SET_STRENGHT:
			{
				speaker_set_strenght(speaker_ctrl_buf_str.strenght);
				PORT_PinWrite(PORT_PIN_PA13,1);
				speaker_main_state_str = SPEAKER_INTERVAL;
				speaker_cycle_u16 = 0;
			}
		break;
		
		case SPEAKER_INTERVAL:
			if(speaker_cycle_u16++ >= ((SPEAKER_INTERVAL_CYCLE_TIMES)/(SPEAKER_TASK_PERIOD)))
			{
				speaker_main_state_str = SPEAKER_START;
			}
		break;
			
		case SPEAKER_START:
			{
               PORT_PinPeripheralFunctionConfig(PORT_PIN_PA02,PERIPHERAL_FUNCTION_B);
               PORT_PinWrite(PORT_PIN_PA25,0);
                DAC_REGS->DAC_CTRLA |= DAC_CTRLA_ENABLE_Msk;
				SA51024_Set_State(SA51024_WORKING,speaker_ctrl_buf_str.strenght);
				speaker_cycle_u16 = 0;
				speaker_main_state_str = SPEAKER_UPDATE_CYCLE;
			}
		break;
		
		case SPEAKER_UPDATE_CYCLE:
			// if(speaker_cycle_u16++ >= speaker_ctrl_buf_str.cycle)
			if(speaker_cycle_u16 >= SA51024_WAVE_MAX_NUM)
			{
				speaker_main_state_str = SPEAKER_STOP;
			}
		break;
			
		default:
		case SPEAKER_STOP:
			{
				SA51024_Set_State(SA51024_STOP,SA51024_STRENGTH_LEVEL0);
                speaker_set_strenght(SA51024_STRENGTH_LEVEL0);
                PORT_PinWrite(PORT_PIN_PA25,0);
				PORT_PinWrite(PORT_PIN_PA13,0);/*SHUTDOWN = 0，turn off chip*/
				speaker_main_state_str = SPEAKER_IDLE;
				speaker_cycle_u16 = 0;
                
                  /* Disable DAC */
              // DAC_REGS->DAC_CTRLA &= ~DAC_CTRLA_ENABLE_Msk;
               PORT_PinGPIOConfig(PORT_PIN_PA02);
			}
		break;


	}


}

/*
para1 cycle time unit ms
para2 level 0~3,other value force set to 3
return FALSE tigger fail,TRUE tigger sucess
*/
STATE_UINT8  speeker_Tig_Once(uint16_t cycle_time,FA51024_ctrl_e_typ level)
{
	speaker_ctrl_Str fl_str_e;
	STATE_UINT8 ret = FALSE;

	if(cycle_time <= (SPEAKER_MAX_CYCLE_TIMES))
	{
		if(level <= SA51024_STRENGTH_LEVEL3)
		{
			fl_str_e.cycle = cycle_time/SPEAKER_TASK_PERIOD;
			fl_str_e.strenght = level;
			if(TRUE == speaker_queue_push_e(fl_str_e))
			{
				ret = TRUE;
			}
		}
	}

	return ret;
}


Speaker_main_e_typ Get_Speaker_Main_State(void)
{
	return speaker_main_state_str;
}



