/**
 * Write Data in REPEATED START mode to LTC2943 Sensor
 *
 * @param: command to write,

 *
 * @return: ENDO_SUCCESS if the data is successfully copy to IIC TX FIFO
 * 			ENDO_FAILURE: fails when IIC device is not properly initialized
 * 								or LTC2943 state is not WaitForCommand
 * Author: Phuong Pham
 * Created: 1/12/2016
******************************************************************************/
int16_t LTC2943_RepeatedStartWrite(u8 command)
{
	/*Check if the IIC device is properly initialized*/
	if(iic_ptr == NULL)
		return ENDO_FAILURE;

	/*Check for valid data length,
	 * LTC2943 has only 23 register*/
	//if((len == 0) && (len > 23))
	//	return ENDO_FAILURE;

	/*Check if the state of LTC2943 is LTC2943_WaitForCommand
	 * If not return right away*/
	if(s_ltc2943_state != LTC2943_WaitForCommand)
		return ENDO_FAILURE;

	int16_t status = EndoIicOpen(BATT_LTC2943);

	if((status != ENDO_SUCCESS) && (status !=(int16_t)IIC_ALREADY_USING))
		return status;

	/*Set the status to transferring*/
	s_iic_status = LTC2943_TRANSFERRING;
	/*Update the state to WriteWait*/
	s_ltc2943_state = LTC2943_WriteRepeatedStartWait;

	/*Read Status Register*/
	u32 option = XIic_GetOptions(iic_ptr);
	XIic_SetOptions(iic_ptr, option | XII_REPEATED_START_OPTION);
	/*Send data by copying data to IIC device*/
	(void)XIic_MasterSend(iic_ptr, command, 1);




	return ENDO_SUCCESS;
}
/*
 * *********************************************************
 * IicReadData with address added as an input parameter - Repeated Start
 * *********************************************************
 */
int IicReadData(u8 IicAddr, u8 addr, u8 *BufferPtr, u16 ByteCount)
{
	int Status;
	u8 IicOptions;
	u32 IicTimeoutCounter = 0;
	/*
	 * Set Receive Flag
	 */
	ReceiveComplete = 1;

	IicOptions = XIic_GetOptions(&IicInstance);
	XIic_SetOptions(&IicInstance, IicOptions | XII_REPEATED_START_OPTION);

	/*
	 * Start Iic Device
	 */
	Status = XIic_Start(&IicInstance);
	if (Status != XST_SUCCESS) {
#ifdef IIC_DEBUG
		xil_printf("IicReadData: IIC Start failed with status %x\r\n", Status);
#endif
		return XST_FAILURE;
	}

	/*
	 * Set Iic Address
	 */
	Status = XIic_SetAddress(&IicInstance, XII_ADDR_TO_SEND_TYPE, IicAddr);
	if (Status != XST_SUCCESS) {
#ifdef IIC_DEBUG
		xil_printf("IicReadData: IIC Set Address failed with status %x\r\n", Status);
#endif
		return XST_FAILURE;
	}

	/*
	 * Write addr to the device
	 */
	// Mark the Transmit Flag
	TransmitComplete = 1;
	IicInstance.Stats.TxErrors = 0;

	/*
	 * Send the Data
	 */
	Status = XIic_MasterSend(&IicInstance, &addr, 1);
	if (Status != XST_SUCCESS) {
#ifdef IIC_DEBUG
		xil_printf("IicReadData: IIC Master Send failed with status %x\r\n", Status);
#endif
		return XST_FAILURE;
	}

	/*
	 * Wait till the transmission is completed
	 */
	while((TransmitComplete) && IicTimeoutCounter <= IIC_TIMEOUT) {
		IicTimeoutCounter ++;
	}

	/*
	 * Clear Repeated Start option
	 */
	XIic_SetOptions(&IicInstance, IicOptions);

	/*
	 * Handle Tx Timeout
	 */
	if (IicTimeoutCounter > IIC_TIMEOUT) {
		XIic_Reset(&IicInstance);
		Status = XIic_Stop(&IicInstance);
#ifdef IIC_DEBUG
		xil_printf("IicReadData: IIC Write Timeout!\r\n");
		if (Status != XST_SUCCESS) {
			xil_printf("IicReadData: IIC Stop Failed with status %x\r\n", Status);
		}
#endif
		return XST_FAILURE;
	}

	/*
	 * Receive Data
	 */
	Status = XIic_MasterRecv(&IicInstance, BufferPtr, ByteCount);
	if(Status != XST_SUCCESS) {
		if (Status != XST_SUCCESS) {
#ifdef IIC_DEBUG
			xil_printf("IicReadData: IIC Master Recv Failed with status %x\r\n", Status);
#endif
			return XST_FAILURE;
		}
	}

	/*
	 * Wait until all the data is received
	 */
	IicTimeoutCounter = 0;

	while(((ReceiveComplete) || (XIic_IsIicBusy(&IicInstance)==TRUE)) && IicTimeoutCounter <= IIC_TIMEOUT) {
		IicTimeoutCounter ++;
	}

	/*
	 * Handle Rx Timeout
	 */
	if (IicTimeoutCounter > IIC_TIMEOUT) {
		XIic_Reset(&IicInstance);
		Status = XIic_Stop(&IicInstance);
#ifdef IIC_DEBUG
		xil_printf("IicReadData: IIC Recv Timeout!\r\n");
		if (Status != XST_SUCCESS) {
			xil_printf("IicReadData: IIC Stop Failed with status %x\r\n", Status);
		}
#endif
		return XST_FAILURE;
	}

	/*
	 * Stop Iic
	 */
	Status = XIic_Stop(&IicInstance);
	if (Status != XST_SUCCESS) {
#ifdef IIC_DEBUG
		xil_printf("IicReadData: IIC Stop Failed with status %x\r\n", Status);
#endif
		return XST_FAILURE;
	}

	return XST_SUCCESS;
}
void TaskRun_Batt_LTC2943(void)
{
	int16_t status;
	u32 iic_option;

	/*Wait for IIC data transfer*/
	if(s_iic_status == LTC2943_TRANSFERRING)
		return;

	else if(s_iic_status == LTC2943_TRANSFERRED_DONE)
	{

		switch(s_ltc2943_state)
		{

			/*Done data write operation*/
			case LTC2943_WriteWait:
				 /*Release IIC Resource*/
				 status = EndoIicClose(BATT_LTC2943);
				 /*Set the status to transferring*/
				 s_iic_status = LTC2943_IDLE ;
				 /*Finish a write operation, and wait for next command*/
				 s_ltc2943_state = LTC2943_WaitForCommand;

				break;

			case LTC2943_WriteRepeatedStartWait:
				iic_option = XIic_GetOptions(iic_ptr);
				XIic_SetOptions(iic_ptr, iic_option &= XII_REPEATED_START_OPTION);
				/*Set the status to transferring*/
				s_iic_status = LTC2943_TRANSFERRING;
				/*Read 14 bytes of data from LTC2943_VOLTAGE_MSB_REG
				 * to LTC2943_TEMPERATURE_LSB_REG*/
				//memset(rx_buffer,0, 16);
				(void)XIic_MasterRecv(iic_ptr, rx_buffer, 24);

				/*Update the LTC2943 state*/
				s_ltc2943_state = LTC2943_ReadAdcValueWait;
				break;


			case LTC2943_ReadAdcValueWait:
				/*Finish a repeated START read*/
				status = EndoIicClose(BATT_LTC2943);
				if(status == ENDO_SUCCESS)
				{
					/*Convert raw data to voltage, current, temperature*/
					LTC2943_ConvertData(rx_buffer+8, 14);
				}
				/*Set the status to transferring*/
				s_iic_status = LTC2943_IDLE ;
				/*Finish the write-read operation, and wait for next command*/
				s_ltc2943_state = LTC2943_WaitForCommand;
				break;


			default:
				/*Error happen here*/
				s_iic_status = LTC2943_IDLE ;

				s_ltc2943_state = LTC2943_Error;
					break;
		}



	}
	else /*s_iic_status == LTC2943_IDLE*/
	{
		switch(s_ltc2943_state)
				{
					case LTC2943_Init:
						 status = EndoIicSensorInit(BATT_LTC2943, iic_ptr,
								 	 	 	 	 	 LTC2943_SendHandler,
								 	 	 	 	 	 LTC2943_RecvHandler,
								 	 	 	 	 	 LTC2943_StatusHandler);

						 if(status == ENDO_SUCCESS)
							 s_ltc2943_state = LTC2943_WaitForCommand;

						break;


					case LTC2943_WaitForCommand:
						break;

					case LTC2943_Error:
						s_ltc2943_state = LTC2943_WaitForCommand;
						break;

					default:
						break;
				}
	}


}