#include <p18cxxx.h>
#include "my_typedef.h"
//#include "pic18f4550_api.h"

#ifndef _PIC18F4550_I2C_H_
#define _PIC18F4550_I2C_H_

/***** I2C_MASTER ******/
/************** I2C_CONSTANTS ******************/

#define CLOCK_FREQ 20000000L
#define I2C_ACK  0
#define I2C_NAK  1

/** SSPCON1 **/
#define I2C_WCOL    0x80
#define I2C_SSPOV   0x40
#define I2C_ENABLE  0x20
#define I2C_DISABLE 0xDF
#define I2C_MASTER  0x08
/*************/

/** SSPCON2 **/
#define I2C_ACKSTAT 0x40
#define I2C_ACKDT   0x20
#define I2C_ACKEN   0x10
#define I2C_RCEN    0x08
#define I2C_PEN     0x04
#define I2C_RSEN    0x02
#define I2C_SEN     0x01
/*************/

/** SSPSTAT **/
#define I2C_SMP    0x80
#define I2C_STOP   0x10
#define I2C_START  0x08
#define I2C_RNW    0x04
#define I2C_UPADD  0x02
#define I2C_BUFFUL 0x01
/*************/
/***********************************************/

/*********** I2C_ATOMIC_MACROS *****************/

#define Get_I2C_Idle()              while( (SSPCON2 & 0x1F) | (SSPSTAT & I2C_RNW) )

#define Get_I2C_stop()              (SSPSTAT & 0x10) /* STOP_DETECTED */7
#define Get_I2C_start()             (SSPSTAT & 0x08) /* START_DETECTED 7*/
#define Get_I2C_req_addr_update()   (SSPSTAT & 0x02) /* ADDRESS_NEEDS_UPDATE */
#define Get_I2C_buffer_full()       (SSPSTAT & 0x01) /* BUFFER_FULL */
#define Get_I2C_write_collision()   (SSPCON1 & 0x80) /* COLLISION_DETECTED_WHILE_WRITE */
#define Get_I2C_read_overflow()     (SSPCON1 & 0x40) /* RECEIVE_OVERLOW_DETECTED */

#define Set_I2C_ack_sequence_en()   (SSPCON2 |= 0x10) /* SEND_ACKNOLEDGE_DATA_BIT */
#define Set_I2C_ack_sequence_idle() (SSPCON2 &= 0xEF) /* ACKNOLEDGE_SEQUENCE_IDLE */
#define Set_I2C_send_stop_cond()    (SSPCON2 |= 0x04) /* SEND_STOP_CONDITION */
#define Set_I2C_stop_cond_idle()    (SSPCON2 &= 0xFB) /* STOP_CONDITION_IDLE */
#define Set_I2C_send_rep_start()    (SSPCON2 |= 0x02) /* SEND_REPEATED_START */
#define Set_I2C_rep_start_idle()    (SSPCON2 &= 0xFD) /* REPEATED_START_IDLE */
#define Set_I2C_send_start_cond()   (SSPCON2 |= 0x01) /* SEND_START_CONDITION */
#define Set_I2C_start_cond_idle()   (SSPCON2 &= 0xFE) /* START_CONDITION_IDLE */

#define Get_I2C_State()             (SSPSTAT & 0x04) /* MASTER_MODE_TRANSMISSION_STATE */
#define Get_I2C_master_trans_ack()  (SSPCON2 & 0x40) /* MASTER_TRANSMIT_SLAVE_ACKN_STATUS */

/***********************************************/

/************ I2C_FUNCTIONS ********************/

inline void I2C_Init_100(void);
inline void I2C_Idle(void);
inline void I2C_Start(void);
inline void I2C_ReStart(void);
inline void I2C_Stop(void);
inline void I2C_Write( uint8_t tmp );
inline uint8_t I2C_Read( uint8_t acknoledge );

void I2C_Write_Byte(uint8_t addr, uint8_t data);
void I2C_Write_Byte2(uint8_t addr, uint8_t data1, uint8_t data2);
void I2C_Write_ByteN(uint8_t addr, uint8_t cmd, uint8_t *data, uint8_t length);
uint8_t I2C_Read_Byte(uint8_t addr, uint8_t cmd);
uint16_t I2C_Read_Word(uint8_t addr, uint8_t cmd);
void I2C_Read_Byte2(uint8_t addr, uint8_t cmd, uint8_t* data1, uint8_t* data2);
void I2C_Read_ByteN(uint8_t addr, uint8_t cmd, uint8_t* data, uint8_t length);

/***********************************************/

#endif