/*****************************************************************************
* File Name          : BC45_Board_Category.c
* Author             : Ohmmarin Sathusen
* Version            : V1.5.0.0
* Date               : 18/09/2012
* Description        : Add on from V1.4.0.0
*                         - ON_MAGNETIC_BUZZER_ms
******************************************************************************/   

#include "Common_Utility_Category.h"
#include "BC45_Chip_Function.h"
#include "BC45_Board_Category.h"
#include "BC45_Board_ASIC_Category.h"
#include <stdint.h>




static tPRIOR_Resp_Package      PRIOR_Resp_Package ;
static uint8_t  FLAG_RETURN_RF_DATA_FAIL ;

tPRIOR_Resp_Package* get_PRIOR_Resp_Package(void)
{
	return (&PRIOR_Resp_Package);
}

uint8_t get_FLAG_RETURN_RF_DATA_FAIL(void)
{
	return FLAG_RETURN_RF_DATA_FAIL;
}

/*******************************************************************************
* Function Name : BC45_Board_Command
* Description   : Perform 
*					- setting and getting BC45 Board
*			
* Input         : 	- Command : Commands associated to BC45_Board as shown in source below 
*					- Param	: Parameters associated to command as shown in source below (after CMD_TYPE)
*					- LenParam : Length of input parameters
* Output        : 
*					- Data_Resp	: Reponse from operation the command
*					- LenData_Resp : Length of output response
* Return        : 
*				   - Response : Result from operating the function
*				 	 	- _SUCCESS_ 
*******************************************************************************/
uint8_t BC45_Board_Command( uint8_t Command, uint8_t *Param, uint16_t LenParam, uint8_t *Data_Resp, uint16_t *LenData_Resp )
{
	uint8_t   Resp ;
	uint8_t   Mode ;
	uint8_t   NEW_DEVICE_ID ;
	uint8_t   Timeout_Val_H, Timeout_Val_L ;
	uint16_t  Timeout_Val ;

	switch(Command)
	{
		case Get_Device_ID :
								// SOP + LEN_H + LEN_L + SEQ_NUM + DEV_ID + CMD_TYPE + CMD + LRC
								// SOP + LEN_H + LEN_L + SEQ_NUM + DEV_ID + CMD_TYPE + FBP_CMD + RESP + Device_ID + LRC									
								Resp = BC45_Board_Get_Device_ID( Data_Resp, LenData_Resp ) ;
		break ;

		case Write_Device_ID :
								// SOP + LEN_H + LEN_L + SEQ_NUM + DEV_ID + CMD_TYPE + CMD + New_Device_ID + LRC
								// SOP + LEN_H + LEN_L + SEQ_NUM + DEV_ID + CMD_TYPE + FBP_CMD + RESP + LRC									
								if ( LenParam >= 1 )
								{ 
									NEW_DEVICE_ID = *(Param) ;
									if ( NEW_DEVICE_ID <= MAX_DEVICE_ID )
									{
										Resp = BC45_Board_Write_Device_ID( NEW_DEVICE_ID ) ;
									}
									else
									{
										Resp = PARAMETER_NOT_CORRECT ;
									}
								}
								else
								{
									Resp = PARAMETER_NOT_CORRECT ;
								}
								*( LenData_Resp ) = 0 ; 
		break ;

		case Get_Last_Response :
								// SOP + LEN_H + LEN_L + SEQ_NUM + DEV_ID + CMD_TYPE + CMD + LRC
								// SOP + LEN_H + LEN_L + SEQ_NUM + DEV_ID + CMD_TYPE + FBP_CMD + RESP + DATA[0] + ... + DATA[N-1] + LRC									
								Resp = BC45_Board_GetLastResponse( Data_Resp, LenData_Resp ) ;
		break ;

		case Test_Communication :
								// SOP + LEN_H + LEN_L + SEQ_NUM + DEV_ID + CMD_TYPE + CMD + DATA[0] + ... + DATA[N-1] + LRC
								// SOP + LEN_H + LEN_L + SEQ_NUM + DEV_ID + CMD_TYPE + FBP_CMD + RESP + DATA[0] + ... + DATA[N-1] + LRC									
								Resp = BC45_Board_TestCommunication( Param, LenParam, Data_Resp, LenData_Resp ) ;	
		break ;

		case Get_Version :
								// SOP + LEN_H + LEN_L + SEQ_NUM + DEV_ID + CMD_TYPE + CMD + LRC
								// SOP + LEN_H + LEN_L + SEQ_NUM + DEV_ID + CMD_TYPE + FBP_CMD + RESP + Version(0)+ ... + Version(3) + LRC									
								Resp = BC45_Board_GetVersion( Data_Resp, LenData_Resp ) ;
		break ;

		case Handle_RFData_Fail :
								// SOP + LEN_H + LEN_L + SEQ_NUM + DEV_ID + CMD_TYPE + CMD + Handle + LRC
								// SOP + LEN_H + LEN_L + SEQ_NUM + DEV_ID + CMD_TYPE + FBP_CMD + RESP + LRC									
								if ( LenParam >= 1 )
								{ 
									Mode = *( Param ) ;
									Resp = BC45_Board_Handle_RFDataFail( Mode ) ;	
								}
								else
								{
									Resp = PARAMETER_NOT_CORRECT ;
								}
								*( LenData_Resp ) = 0 ; 
		break ;

		case Get_Driver_Config :
								// SOP + LEN_H + LEN_L + SEQ_NUM + DEV_ID + CMD_TYPE + CMD + LRC
								// SOP + LEN_H + LEN_L + SEQ_NUM + DEV_ID + CMD_TYPE + FBP_CMD + RESP + Driver_Config + LRC									
								Resp = BC45_Board_Get_Driver_Config( Data_Resp, LenData_Resp ) ;
		break ;

		case Write_Driver_Config :
								// SOP + LEN_H + LEN_L + SEQ_NUM + DEV_ID + CMD_TYPE + CMD + Driver_Config + LRC
								// SOP + LEN_H + LEN_L + SEQ_NUM + DEV_ID + CMD_TYPE + FBP_CMD + RESP + LRC									
								if ( LenParam >= 1 )
								{ 
									Resp = BC45_Board_Write_Driver_Config( *(Param) ) ;
								}
								else
								{
									Resp = PARAMETER_NOT_CORRECT ;
								}
								*( LenData_Resp ) = 0 ; 
		break ;

		case Get_Last_Response_All :
								// SOP + LEN_H + LEN_L + SEQ_NUM + DEV_ID + CMD_TYPE + CMD + LRC
								// SOP + LEN_H + LEN_L + SEQ_NUM + DEV_ID + CMD_TYPE + FBP_CMD + RESP + DATA[0] + ... + DATA[N-1] + LRC									
								Resp = BC45_Board_GetLastResponse_All( Data_Resp, LenData_Resp ) ;
		break ;

		case Get_Handle_RFData_Fail :
								// SOP + LEN_H + LEN_L + SEQ_NUM + DEV_ID + CMD_TYPE + CMD + LRC
								// SOP + LEN_H + LEN_L + SEQ_NUM + DEV_ID + CMD_TYPE + FBP_CMD + RESP + DATA[0] + LRC									
								Resp = BC45_Board_GetHandle_RFDataFail( Data_Resp, LenData_Resp ) ;	

		break ;

		case Get_ASIC_Exe_Timeout_Val :
								// SOP + LEN_H + LEN_L + SEQ_NUM + DEV_ID + CMD_TYPE + CMD + LRC
								// SOP + LEN_H + LEN_L + SEQ_NUM + DEV_ID + CMD_TYPE + FBP_CMD + RESP + ASIC_Exe_Timeout_Value + LRC									
								Resp = BC45_Board_Get_ASIC_Exe_Timeout_Val( Data_Resp, LenData_Resp ) ;
		break ;

		case Write_ASIC_Exe_Timeout_Val :
								// SOP + LEN_H + LEN_L + SEQ_NUM + DEV_ID + CMD_TYPE + CMD + ASIC_Exe_Timeout_Value + LRC
								// SOP + LEN_H + LEN_L + SEQ_NUM + DEV_ID + CMD_TYPE + FBP_CMD + RESP + LRC									
								if ( LenParam >= 2 )
								{ 
									Timeout_Val_H = *( Param ) ;
									Timeout_Val_L = *( Param + 1 ) ;
									Timeout_Val   = (uint16_t)( ((uint16_t)Timeout_Val_H << 8) | Timeout_Val_L ) ;
									Resp = BC45_Board_Write_ASIC_Exe_Timeout_Val( Timeout_Val ) ;
								}
								else
								{
									Resp = PARAMETER_NOT_CORRECT ;
								}
								*( LenData_Resp ) = 0 ; 
		break ;

		case Enable_Continuous_Run :
								// SOP + LEN_H + LEN_L + SEQ_NUM + DEV_ID + CMD_TYPE + CMD + LRC
								// SOP + LEN_H + LEN_L + SEQ_NUM + DEV_ID + CMD_TYPE + FBP_CMD + RESP + LRC									
								Resp = BC45_Board_Enable_Continuous_Run( ) ;
								*( LenData_Resp ) = 0 ; 
		break ;

		case Disable_Continuous_Run :
								// SOP + LEN_H + LEN_L + SEQ_NUM + DEV_ID + CMD_TYPE + CMD + LRC
								// SOP + LEN_H + LEN_L + SEQ_NUM + DEV_ID + CMD_TYPE + FBP_CMD + RESP + LRC									
								Resp = BC45_Board_Disable_Continuous_Run( ) ;
								*( LenData_Resp ) = 0 ; 
		break ;

		case Set_Delay_Time_ms :
								// SOP + LEN_H + LEN_L + SEQ_NUM + DEV_ID + CMD_TYPE + CMD + Delay_Time_H + Delay_Time_L + LRC
								// SOP + LEN_H + LEN_L + SEQ_NUM + DEV_ID + CMD_TYPE + FBP_CMD + RESP + LRC									
								if ( LenParam >= 2 )
								{ 
									Resp = BC45_Board_Set_Delay_Time_ms( Param ) ;
								}
								else
								{
									Resp = PARAMETER_NOT_CORRECT ;
								}
								*( LenData_Resp ) = 0 ; 
		break ;

		case Get_Delay_Time_ms :
								// SOP + LEN_H + LEN_L + SEQ_NUM + DEV_ID + CMD_TYPE + CMD + LRC
								// SOP + LEN_H + LEN_L + SEQ_NUM + DEV_ID + CMD_TYPE + FBP_CMD + RESP + Delay_Time_H + Delay_Time_L + LRC									
								Resp = BC45_Board_Get_Delay_Time_ms( Data_Resp, LenData_Resp ) ;
		break ;

          	case Get_Board_Description :
								// SOP + LEN_H + LEN_L + SEQ_NUM + DEV_ID + CMD_TYPE + CMD + LRC
								// SOP + LEN_H + LEN_L + SEQ_NUM + DEV_ID + CMD_TYPE + FBP_CMD + RESP + Board_Type + Board_Detail[1] + ... + Board_Detail[3] + Version[4] + .. Version[0]  + LRC									
								Resp = BC45_Board_Get_Board_Description( Data_Resp, LenData_Resp ) ;
		break ;
                
                //case On_Magnetic_Buzzer :
                                                                // SOP + LEN_H + LEN_L + SEQ_NUM + DEV_ID + CMD_TYPE + CMD + FREQ_In + LRC
								// SOP + LEN_H + LEN_L + SEQ_NUM + DEV_ID + CMD_TYPE + FBP_CMD + RESP + Board_Type + Board_Detail[1] + ... + Board_Detail[3] + Version[4] + .. Version[0]  + LRC									
								//if ( LenParam >= 1 )
								//{ 
								//	ON_MAGNETIC_BUZZER_ms  ( (*Param) , 200 ) ;
                                                                //        Resp = _SUCCESS_ ;
								//}
								//else
								//{
								//	Resp = PARAMETER_NOT_CORRECT ;
								//}
                                                                
                  					        
								
								//*( LenData_Resp ) = 0 ; 
                                                                
								
                //break;
          

		default :
								Resp = UNKNOWN_CMD ;
								*( LenData_Resp ) = 0 ; 
		break ;
	} ;
	
	return Resp ;
}

/*******************************************************************************
* Function Name : BC45_Board_Get_Device_ID
* Description   : Get Device ID from BC45_BOARD_PROPERTY.Device_ID
* Input         : None
* Output        : 
*				  - Device_ID
*				  - LenDevice_ID
* Return        : 
*				  - Response
*						- _SUCCESS_				  
*******************************************************************************/
uint8_t BC45_Board_Get_Device_ID( uint8_t *Device_ID, uint16_t *LenDevice_ID )
{	 
	*( Device_ID )    = BC45_BOARD_PROPERTY.Device_ID ;
	*( LenDevice_ID ) = 1 ;

	return _SUCCESS_ ;	
}

/*******************************************************************************
* Function Name : BC45_Board_Get_Driver_Config
* Description   : Get current state of Driver Configuration (variable)
* Input         : None
* Output        : 
*				  - Driver_Config_Type : 
*						- DRIVER_CONFIG_X_CC     : Diffential Close Coupling Network with internal envelope
*						- DRIVER_CONFIG_X_CCXENV : Diffential Close Coupling Network with external envelope
*						- DRIVER_CONFIG_X_S50OUT : Single-ended Drive with external envelope
*						- DRIVER_CONFIG_X_E50OUT : 50 ohm output from Class-E driver with external envelope 
*				  - LenDriver_Config
* Return        : 
*				  - Response
*						- _SUCCESS_				  
*******************************************************************************/
uint8_t BC45_Board_Get_Driver_Config( uint8_t *Driver_Config, uint16_t *LenDriver_Config )
{	 
	*( Driver_Config )    = BC45_BOARD_PROPERTY.Driver_Config_Type ;
	*( LenDriver_Config ) = 1 ;

	return _SUCCESS_ ;	
}

/*******************************************************************************
* Function Name : BC45_Board_Get_ASIC_Exe_Timeout_Val
* Description   : Get ASIC Execution Timeout Value
*				  This Timeout is for MCU in case of no response from ASIC.
* Input         : None
* Output        : 
*				  - Timeout_Val	(mS) Ex. If Timeout_Value = 1000, timeout = 1 sec.
*				  - LenTimeout_Val	 (2)
* Return        : 
*				  - Response
*						- _SUCCESS_				  
*******************************************************************************/
uint8_t BC45_Board_Get_ASIC_Exe_Timeout_Val( uint8_t *Timeout_Val, uint16_t *LenTimeout_Val )
{	 
	uint16_t  temp_Timeout_Val ;
	
	temp_Timeout_Val 	 = BC45_BOARD_PROPERTY.ASIC_Exe_Timeout_Val ;
	*( Timeout_Val )     = (uint8_t)( temp_Timeout_Val >> 8 ) ;
	*( Timeout_Val + 1 ) = (uint8_t)( temp_Timeout_Val ) ;
	*( LenTimeout_Val )  = 2 ;

	return _SUCCESS_ ;	
}

/*******************************************************************************
* Function Name : BC45_Board_GetLastResponse
* Description   : Get Last Host-interface Response 
* Input         : None
* Output        : 
*				  - Data_Resp
*				  - LenData_Resp
* Return        : 
*				  - Response
*						- _SUCCESS_				  
*******************************************************************************/
uint8_t BC45_Board_GetLastResponse( uint8_t *Data_Resp, uint16_t *LenData_Resp )
{
	uint16_t  i ;
	uint16_t  LenData ;
	
	LenData = PRIOR_Resp_Package.LenData_Resp ;
	if ( (PRIOR_Resp_Package.Cmd_Type != BC45_BOARD_CMD_TYPE) || ( (PRIOR_Resp_Package.Cmd != Get_Last_Response) && (PRIOR_Resp_Package.Cmd != Get_Last_Response_All) ) )
	{
		for ( i = 0 ; i < LenData ; i++ )
		{	
			// Shift Data to right 3 byte
			*( (Data_Resp + LenData - 1 + 3) - i ) = *( (Data_Resp + LenData - 1) - i ) ;
		}

		*(Data_Resp)     = PRIOR_Resp_Package.Cmd_Type ;
		*(Data_Resp + 1) = PRIOR_Resp_Package.Cmd ;
		*(Data_Resp + 2) = PRIOR_Resp_Package.Resp ;
	} 

	*(LenData_Resp)	 = LenData + 3 ; // LenData_Resp add ( CMD_TYPE , CMD , RESP )

	return _SUCCESS_ ;	
}

/*******************************************************************************
* Function Name : BC45_Board_GetLastResponse_All
* Description   : Get Last Host-interface Response ncluding data if RF communication fails
* Input         : None
* Output        : 
*				  - Data_Resp
*				  - LenData_Resp
* Return        : 
*				  - Response
*						- _SUCCESS_				  
*******************************************************************************/
uint8_t BC45_Board_GetLastResponse_All( uint8_t *Data_Resp, uint16_t *LenData_Resp )
{
	uint16_t i ;
	uint16_t LenData ;
	
	LenData = PRIOR_Resp_Package.LenData_Resp_All ;
	if ( (PRIOR_Resp_Package.Cmd_Type != BC45_BOARD_CMD_TYPE) || ( (PRIOR_Resp_Package.Cmd != Get_Last_Response) && (PRIOR_Resp_Package.Cmd != Get_Last_Response_All) ) )
	{
		for ( i = 0 ; i < LenData ; i++ )
		{	
			// Shift Data to right 3 byte
			*( (Data_Resp + LenData - 1 + 3) - i ) = *( (Data_Resp + LenData - 1) - i ) ;
		}

		*(Data_Resp)     = PRIOR_Resp_Package.Cmd_Type ;
		*(Data_Resp + 1) = PRIOR_Resp_Package.Cmd ;
		*(Data_Resp + 2) = PRIOR_Resp_Package.Resp ;
	} 

	*(LenData_Resp)	 = LenData + 3 ; // LenData_Resp add ( CMD_TYPE , CMD , RESP )

	return _SUCCESS_ ;	
}

/*******************************************************************************
* Function Name : BC45_Board_TestCommunication
* Description   : Echo received data back to host
* Input         : 
*				  - Data_LoopBack
*				  - LenData_LoopBack
* Output        : 
*				  - Data_Resp
*				  - LenData_Resp
* Return        : 
*				  - Response
*						- _SUCCESS_				  
*******************************************************************************/
uint8_t BC45_Board_TestCommunication( uint8_t *Data_LoopBack, uint16_t LenData_LoopBack, uint8_t *Data_Resp, uint16_t *LenData_Resp )
{
	uint16_t i ;

	*(LenData_Resp) = LenData_LoopBack ; 
	for ( i = 0 ; i < LenData_LoopBack ; i++ )
	{
		*( Data_Resp + i ) = *(Data_LoopBack + i) ;		
	} 	

	return _SUCCESS_ ;	
}

/*******************************************************************************
* Function Name : BC45_Board_Handle_RFDataFail
* Description   : Define "Failed Response Format", the host response format (USB/RS232) if RF Data fails 
* Input         : 
*				  - Mode
*						- 0x00h : Not return RF Data(Data FIFO in BC45) when RF Communication Err Occurs
*						- 0x01h : Always return RF Data(Data FIFO in BC45) when RF Communication Err Occurs
*						- other : Always return RF Data(Data FIFO in BC45) when RF Communication Err Occurs
* Output        : None
* Return        : 
*				  - Response
*						- _SUCCESS_				  
*******************************************************************************/
uint8_t BC45_Board_Handle_RFDataFail( uint8_t Mode )
{
	// Mode = 0  --> Not return RF Data(Data FIFO in BC45) when RF Communication Err Occur
	// Mode = 1  --> Always return RF Data(Data FIFO in BC45) when RF Communication Err Occur
	if ( Mode > 0 )
	{ 
		FLAG_RETURN_RF_DATA_FAIL = 1 ;	
	}
	else
	{
		FLAG_RETURN_RF_DATA_FAIL = 0 ;	
	}
	return _SUCCESS_ ;	
}

/*******************************************************************************
* Function Name : BC45_Board_GetHandle_RFDataFail
* Description   : Get state "Failed Response Format" 
* Input         : None
* Output        : 
*				  - Mode
*						- 0x00h : Not return RF Data(Data FIFO in BC45) when RF Communication Err Occurs
*						- 0x01h : Always return RF Data(Data FIFO in BC45) when RF Communication Err Occurs
*						- other : Always return RF Data(Data FIFO in BC45) when RF Communication Err Occurs
*				  - LenMode
* Return        : 
*				  - Response
*						- _SUCCESS_				  
*******************************************************************************/
uint8_t BC45_Board_GetHandle_RFDataFail( uint8_t *Mode , uint16_t *LenMode )
{
	// Mode = 0  --> Not return RF Data(Data FIFO in BC45) when RF Communication Err Occur
	// Mode = 1  --> Alway return RF Data(Data FIFO in BC45) when RF Communication Err Occur
	*( Mode ) = FLAG_RETURN_RF_DATA_FAIL ;	
	*( LenMode ) = 1 ;

	return _SUCCESS_ ;	
}

/*******************************************************************************
* Function Name : BC45_Board_GetVersion
* Description   : Get version of BC45 Board
* Input         : None
* Output        : 
*				  - Version
*				  - LenVersion
* Return        : 
*				  - Response
*						- _SUCCESS_				  
*******************************************************************************/
uint8_t BC45_Board_GetVersion( uint8_t *Version , uint16_t *LenVersion )
{
	*( Version ) = VERSION ;	
	*( Version + 1 ) = SUB_VERSION_1 ;	
	*( Version + 2 ) = SUB_VERSION_2 ;	
	*( Version + 3 ) = SUB_VERSION_3 ;	
	*( LenVersion ) = 4 ;

	return _SUCCESS_ ;	
}

uint8_t BC45_Board_Enable_Continuous_Run( void )
{	
	BC45_BOARD_PROPERTY.Continuous_Run = 1 ;
	return _SUCCESS_ ;	
}

uint8_t BC45_Board_Disable_Continuous_Run( void )
{	
	BC45_BOARD_PROPERTY.Continuous_Run = 0 ;
	return _SUCCESS_ ;	
}

uint8_t BC45_Board_Set_Delay_Time_ms( uint8_t *Delay_Time_ms )
{
	BC45_BOARD_PROPERTY.Delay_Run_ms =  (uint16_t)( ((uint16_t)(*( Delay_Time_ms )) << 8) | (uint16_t)(*( Delay_Time_ms + 1 )) ) ;
	return _SUCCESS_ ;	
}

uint8_t BC45_Board_Get_Delay_Time_ms( uint8_t *Delay_Time_ms, uint16_t *Len_Delay_Time_ms )
{
	uint16_t  temp_Delay_Time ;
	
	temp_Delay_Time 	 = BC45_BOARD_PROPERTY.Delay_Run_ms ;
	*( Delay_Time_ms )     = (uint8_t)( temp_Delay_Time >> 8 ) ;
	*( Delay_Time_ms + 1 ) = (uint8_t)( temp_Delay_Time ) ;
	*( Len_Delay_Time_ms )  = 2 ;

	return _SUCCESS_ ;	
}

uint8_t BC45_Board_Get_Board_Description( uint8_t *Board_Description, uint16_t *Len_Board_Description )
{
	// Board Detail
	*( Board_Description ) = Board_Type ;	
	*( Board_Description + 1 ) = FW_DETAIL ;	

	// Version of Board
	*( Board_Description + 2 ) = VERSION ;	
	*( Board_Description + 3 ) = SUB_VERSION_1 ;	
	*( Board_Description + 4 ) = SUB_VERSION_2 ;	
	*( Board_Description + 5 ) = SUB_VERSION_3 ;	
	*( Len_Board_Description ) = 6 ;

	return _SUCCESS_ ;	
}

/*
void ON_MAGNETIC_BUZZER_ms  ( uint8_t Freq_in , uint16_t ON_Time_ms )
{
      uint16_t    i;
      uint8_t     j, toggle_count; 
      long int    half_period ;
      
      switch (Freq_in)
      {
        case 0x01 :
            half_period = 250;
            toggle_count = 2 ;
        break;
        
        case 0x02 :
            half_period = 166;
            toggle_count = 3 ;
        break;
        
        case 0x03 :
            half_period = 125;
            toggle_count = 4 ;
        break;
        
        case 0x04 :
            half_period = 100;
            toggle_count = 5 ;
        break;
        
        default :
            half_period = 500;
            toggle_count = 1 ;
        break;
     }
     
      for ( i = 0 ; i < (ON_Time_ms) ; i++) 
      {
  	  for (j = 0 ; j < toggle_count ; j++)
          {
            BUZZER_ON  ();
	    Delay_us( half_period ) ;
            BUZZER_OFF ();
            Delay_us( half_period ) ;
          }
      }		
}
*/

