/** \brief This function sends a I2C packet enclosed by
 *         a I2C start and stop to the device.
 *
This function combines a I2C packet send sequence that
is common to all packet types. Only if word_address is
#I2C_PACKET_FUNCTION_NORMAL, count and buffer parameters are
expected to be non-zero.
 * @param[in] word_address packet function code listed in #i2c_word_address
 * @param[in] count number of bytes in data buffer
 * @param[in] buffer pointer to data buffer
 * @return status of the operation
 */
static uint8_t ecc108p_i2c_send(uint8_t word_address, uint8_t count, uint8_t *buffer)
{
	uint8_t i2c_status = ecc108p_send_slave_address(I2C_WRITE);
	if (i2c_status != I2C_FUNCTION_RETCODE_SUCCESS)
		return ECC108_COMM_FAIL;

	i2c_status = i2c_send_bytes(1, &word_address);
	if (i2c_status != I2C_FUNCTION_RETCODE_SUCCESS)
		return ECC108_COMM_FAIL;

	if (count == 0) {
		// We are done for packets that are not commands (Sleep, Idle, Reset).
		(void) i2c_send_stop();
		return ECC108_SUCCESS;
	}

	i2c_status = i2c_send_bytes(count, buffer);

	(void) i2c_send_stop();

	if (i2c_status != I2C_FUNCTION_RETCODE_SUCCESS)
		return ECC108_COMM_FAIL;
	else
		return ECC108_SUCCESS;
}
/** \brief This function resynchronizes communication.
 *
 * Parameters are not used for I2C.\n
 * Re-synchronizing communication is done in a maximum of three steps
 * listed below. This function implements the first step. Since
 * steps 2 and 3 (sending a Wake-up token and reading the response)
 * are the same for I2C and SWI, they are
 * implemented in the communication layer (#ecc108c_resync).
  <ol>
     <li>
       To ensure an IO channel reset, the system should send
       the standard I2C software reset sequence, as follows:
       <ul>
         <li>a Start condition</li>
         <li>nine cycles of SCL, with SDA held high</li>
         <li>another Start condition</li>
         <li>a Stop condition</li>
       </ul>
       It should then be possible to send a read sequence and
       if synchronization has completed properly the ATECC108 will
       acknowledge the device address. The chip may return data or
       may leave the bus floating (which the system will interpret
       as a data value of 0xFF) during the data periods.\n
       If the chip does acknowledge the device address, the system
       should reset the internal address counter to force the
       ATECC108 to ignore any partial input command that may have
       been sent. This can be accomplished by sending a write
       sequence to word address 0x00 (Reset), followed by a
       Stop condition.
     </li>
     <li>
       If the chip does NOT respond to the device address with an ACK,
       then it may be asleep. In this case, the system should send a
       complete Wake token and wait t_whi after the rising edge. The
       system may then send another read sequence and if synchronization
       has completed the chip will acknowledge the device address.
     </li>
     <li>
       If the chip still does not respond to the device address with
       an acknowledge, then it may be busy executing a command. The
       system should wait the longest TEXEC and then send the
       read sequence, which will be acknowledged by the chip.
     </li>
  </ol>
 * \param[in] size size of rx buffer
 * \param[out] response pointer to response buffer
 * \return status of the operation
 */
uint8_t ecc108p_resync(uint8_t size, uint8_t *response)
{
	uint8_t nine_clocks = 0xFF;
	uint8_t ret_code = i2c_send_start();

	// Do not evaluate the return code that most likely indicates error,
	// since nine_clocks is unlikely to be acknowledged.
	(void) i2c_send_bytes(1, &nine_clocks);

	// Send another Start. The function sends also one byte,
	// the I2C address of the device, because I2C specification
	// does not allow sending a Stop right after a Start condition.
	ret_code = ecc108p_send_slave_address(I2C_READ);

	// Send only a Stop if the above call succeeded.
	// Otherwise the above function has sent it already.
	if (ret_code == I2C_FUNCTION_RETCODE_SUCCESS)
		ret_code = i2c_send_stop();

	// Return error status if we failed to re-sync.
	if (ret_code != I2C_FUNCTION_RETCODE_SUCCESS)
		return ECC108_COMM_FAIL;

	// Try to send a Reset IO command if re-sync succeeded.
	return ecc108p_reset_io();
}
void I2CWrite(ch_uint32 addr, ch_uint32 value)
{
	//Realize this according to your system...
        unsigned char   out_buf[2];
        out_buf[0] = addr;
        out_buf[1] = value;
        i2c_send_bytes(out_buf, 2);

}
//IIC function: read/write CH7033
ch_uint32 I2CRead(ch_uint32 addr)
{
	//Realize this according to your system...
        unsigned char buf[2];
        buf[0] = addr;
        i2c_send_bytes(buf, 1); //S+DEVICE+W A RegAddr A        
        i2c_rcv_bytes(buf, 1);  //S+ DEVICE + R Data Byte High A Data Byte Low          
        return buf[0];

}
/** \brief This function creates a Start condition and sends the
 * I2C address.
 * \param[in] read #I2C_READ for reading, #I2C_WRITE for writing
 * \return status of the I2C operation
 */
static uint8_t ecc108p_send_slave_address(uint8_t read)
{
	uint8_t sla = device_address | read;
	uint8_t ret_code = i2c_send_start();
	if (ret_code != I2C_FUNCTION_RETCODE_SUCCESS)
		return ret_code;

	ret_code = i2c_send_bytes(1, &sla);

	if (ret_code != I2C_FUNCTION_RETCODE_SUCCESS)
		(void) i2c_send_stop();

	return ret_code;
}
/** \brief This I2C function generates a Wake-up pulse and delays.
 * \return status of the operation
 */
uint8_t ecc108p_wakeup(void)
{
#if !defined(ECC108_GPIO_WAKEUP) && !defined(ECC108_I2C_BITBANG)

	// Generate wakeup pulse by writing a 0 on the I2C bus.
	uint8_t dummy_byte = 0;
	uint8_t i2c_status = i2c_send_start();
	if (i2c_status != I2C_FUNCTION_RETCODE_SUCCESS)
		return ECC108_COMM_FAIL;

	// To send eight zero bits it takes 10E6 / I2C clock * 8 us.
	delay_10us(ECC108_WAKEUP_PULSE_WIDTH - (uint8_t) (1000000.0 / 10.0 / I2C_CLOCK * 8.0));

	// We have to send at least one byte between an I2C Start and an I2C Stop.
	(void) i2c_send_bytes(1, &dummy_byte);
	i2c_status = i2c_send_stop();
	if (i2c_status != I2C_FUNCTION_RETCODE_SUCCESS)
		return ECC108_COMM_FAIL;
#else
#  if defined(ECC108_I2C_BITBANG)
	// Generate wakeup pulse using the GPIO pin that is connected to SDA.
	I2C_DATA_LOW();
	delay_10us(ECC108_WAKEUP_PULSE_WIDTH);
	I2C_DATA_HIGH();
#  else
	// Generate wakeup pulse by disabling the I2C peripheral and
	// pulling SDA low. The I2C peripheral gets automatically
	// re-enabled when calling i2c_send_start().
	// PORTD is used on the Microbase. You might have to use another
	// port for a different target.
	TWCR = 0;           // Disable I2C.
	//DDRD |= _BV(PD1);   // Set SDA as output.
	//PORTD &= ~_BV(PD1); // Set SDA low.
        pinMode(SDA, OUTPUT);
        digitalWrite(SDA, LOW);
	delay_10us(ECC108_WAKEUP_PULSE_WIDTH);
	//PORTD |= _BV(PD1);  // Set SDA high.
        digitalWrite(SDA, HIGH);
#   endif
#endif

	delay_10us(ECC108_WAKEUP_DELAY);

	return ECC108_SUCCESS;
}
/******************************************************************
* i2c_send_byte
******************************************************************/
int i2c_send_byte(int bus, uint8_t data) {
    return i2c_send_bytes(bus,1,&data);
}