/* 
* classTwi.h
*
* Created: 21/05/2018 15:32:09
* Author: Ledo
*/


#ifndef __CLASSTWI_H__
#define __CLASSTWI_H__

#include <sam.h>

#define CPU_FREQ            96000000
/** Time-out value (number of attempts). */
#define TWI_TIMEOUT              30000

/**
 * \brief Return codes for TWI APIs.
 * @{
 */
#define TWI_SUCCESS              0
#define TWI_INVALID_ARGUMENT     1
#define TWI_ARBITRATION_LOST     2
#define TWI_NO_CHIP_FOUND        3
#define TWI_RECEIVE_OVERRUN      4
#define TWI_RECEIVE_NACK         5
#define TWI_SEND_OVERRUN         6
#define TWI_SEND_NACK            7
#define TWI_BUSY                 8
#define TWI_ERROR_TIMEOUT        9
/**
 * @}
 */

/* Low level time limit of I2C Fast Mode. */
#define LOW_LEVEL_TIME_LIMIT 384000
#define I2C_FAST_MODE_SPEED  400000
#define TWI_CLK_DIVIDER      2

#define TWI_CLK_CALC_ARGU    4
#define TWI_CLK_DIV_MAX      0xFF
#define TWI_CLK_DIV_MIN      7

#define TWI_WP_KEY_VALUE (0x545749u << 8) 
#define PASS      0
#define FAIL      1

#define TWI_WPMR_WPEN (0x1u << 0) /**< \brief (TWI_WPMR) Write Protection Enable */

 
/**
 * \brief Input parameters when initializing the TWI module mode.
 */
typedef struct twi_options {
	//! MCK for TWI.
	uint32_t master_clk;
	//! The baud rate of the TWI bus.
	uint32_t speed;
	//! The desired address.
	uint8_t chip;
	//! SMBUS mode (set 1 to use SMBUS quick command, otherwise don't).
	uint8_t smbus;
} twi_options_t;

/**
 * \brief Information concerning the data transmission.
 */
typedef struct twi_packet {
	//! TWI address/commands to issue to the other chip (node).
	uint8_t addr[3];
	//! Length of the TWI data address segment (1-3 bytes).
	uint32_t addr_length;
	//! Where to find the data to be transferred.
	uint8_t *buffer;
	//! How many bytes do we want to transfer.
	uint32_t length;
	//! TWI chip address to communicate with.
	uint8_t chip;
} twi_packet_t;



class classTwi
{
//variables
public:
protected:
private:

//functions
public:
	classTwi();
	~classTwi();
	void twi_enable_master_mode(Twi *p_twi);
	void twi_disable_master_mode(Twi *p_twi);
	uint32_t twi_master_init(Twi *p_twi, const twi_options_t *p_opt);
	uint32_t twi_set_speed(Twi *p_twi, uint32_t ul_speed, uint32_t ul_mck);
	uint32_t twi_probe(Twi *p_twi, uint8_t uc_slave_addr);
	uint32_t twi_master_read(Twi *p_twi, twi_packet_t *p_packet);
	uint32_t twi_master_write(Twi *p_twi, twi_packet_t *p_packet);
	void twi_enable_interrupt(Twi *p_twi, uint32_t ul_sources);
	void twi_disable_interrupt(Twi *p_twi, uint32_t ul_sources);
	uint32_t twi_get_interrupt_status(Twi *p_twi);
	uint32_t twi_get_interrupt_mask(Twi *p_twi);
	uint8_t twi_read_byte(Twi *p_twi);
	void twi_write_byte(Twi *p_twi, uint8_t uc_byte);
	void twi_enable_slave_mode(Twi *p_twi);
	void twi_disable_slave_mode(Twi *p_twi);
	void twi_slave_init(Twi *p_twi, uint32_t ul_device_addr);
	void twi_set_slave_addr(Twi *p_twi, uint32_t ul_device_addr);
	uint32_t twi_slave_read(Twi *p_twi, uint8_t *p_data);
	uint32_t twi_slave_write(Twi *p_twi, uint8_t *p_data);
	void twi_reset(Twi *p_twi);
	uint32_t twi_mk_addr(const uint8_t *addr, int len);
	Pdc *twi_get_pdc_base(Twi *p_twi);
	void twi_set_write_protection(Twi *p_twi, bool flag);
	void twi_read_write_protection_status(Twi *p_twi, uint32_t *p_status);
protected:
private:
	classTwi( const classTwi &c );
	classTwi& operator=( const classTwi &c );

}; //classTwi

#endif //__CLASSTWI_H__
