//////////////////////////////////////////////////////////////////
//
// App:			TWI I/O Expander TCA6416
// Author:		Milan Korinek
// Version:		1.0
// Notice:		Driver of I/O Expander TCA6416
//////////////////////////////////////////////////////////////////


#ifndef TWI_IO_EXPANDER_TCA6416_H_
#define TWI_IO_EXPANDER_TCA6416_H_

#include <compiler.h>
#include <status_codes.h>
#include "freertos_twi_master.h"

#if !defined(IOEXP_TWI_BASE)
	# error The TWI_IO_Expander_TCA6416 TWI instance has not been defined.
#endif

#if !defined(IOEXP_TWI_ADDR)
	# error The TWI_IO_Expander_TCA6416 device address has not been defined.
#endif

#if !defined(IOEXP_TWI_CLOCK_HZ)
# warning The TWI_IO_Expander_TCA6416 clock has not been defined. Using default settings (400kHz).
#define IOEXP_TWI_CLOCK_HZ (400000UL)
#endif


#define IOEXP_INPUT_FLAG
#define IOEXP_OUTPUT_FLAG

#define IOEXP_P00_PIN 0
#define IOEXP_P01_PIN 1
#define IOEXP_P02_PIN 2
#define IOEXP_P03_PIN 3
#define IOEXP_P04_PIN 4
#define IOEXP_P05_PIN 5
#define IOEXP_P06_PIN 6
#define IOEXP_P07_PIN 7

#define IOEXP_P10_PIN 8
#define IOEXP_P11_PIN 9
#define IOEXP_P12_PIN 10
#define IOEXP_P13_PIN 11
#define IOEXP_P14_PIN 12
#define IOEXP_P15_PIN 13
#define IOEXP_P16_PIN 14
#define IOEXP_P17_PIN 15

#define ioexp_pin_mask(pin) (1UL << pin)
#define ioexp_get_high_active_mask(pin_mask) ( pin_mask )	
#define ioexp_get_low_active_mask(pin_mask) ( 0UL )							


#define IOEXP_P00_MASK ioexp_pin_mask(IOEXP_P00_PIN)
#define IOEXP_P01_MASK ioexp_pin_mask(IOEXP_P01_PIN)
#define IOEXP_P02_MASK ioexp_pin_mask(IOEXP_P02_PIN)
#define IOEXP_P03_MASK ioexp_pin_mask(IOEXP_P03_PIN)
#define IOEXP_P04_MASK ioexp_pin_mask(IOEXP_P04_PIN)
#define IOEXP_P05_MASK ioexp_pin_mask(IOEXP_P05_PIN)
#define IOEXP_P06_MASK ioexp_pin_mask(IOEXP_P06_PIN)
#define IOEXP_P07_MASK ioexp_pin_mask(IOEXP_P07_PIN)

#define IOEXP_P10_MASK ioexp_pin_mask(IOEXP_P10_PIN)
#define IOEXP_P11_MASK ioexp_pin_mask(IOEXP_P11_PIN)
#define IOEXP_P12_MASK ioexp_pin_mask(IOEXP_P12_PIN)
#define IOEXP_P13_MASK ioexp_pin_mask(IOEXP_P13_PIN)
#define IOEXP_P14_MASK ioexp_pin_mask(IOEXP_P14_PIN)
#define IOEXP_P15_MASK ioexp_pin_mask(IOEXP_P15_PIN)
#define IOEXP_P16_MASK ioexp_pin_mask(IOEXP_P16_PIN)
#define IOEXP_P17_MASK ioexp_pin_mask(IOEXP_P17_PIN)

/* Commands */ 
typedef enum {
	IOEXP_TCA6416_CMD_INPUT_PORT_0				 = 0x00,
	IOEXP_TCA6416_CMD_INPUT_PORT_1				 = 0x01,
	IOEXP_TCA6416_CMD_OUTPUT_PORT_0				 = 0x02,
	IOEXP_TCA6416_CMD_OUTPUT_PORT_1				 = 0x03,
	IOEXP_TCA6416_CMD_POLARITY_INVERSION_PORT_0  = 0x04,
	IOEXP_TCA6416_CMD_POLARITY_INVERSION_PORT_1	 = 0x05,
	IOEXP_TCA6416_CMD_CONFIGURATION_PORT_0		 = 0x06,
	IOEXP_TCA6416_CMD_CONFIGURATION_PORT_1		 = 0x07,
	IOEXP_TCA6416_CMD_END_MARKER				 = 0x08,
} ioexp_tca6416_commands_t;

typedef enum {
	IOEXP_TCA6416_LOW = 0,
	IOEXP_TCA6416_HIGH = 1,	
} ioexp_tca6416_value_t;

typedef enum {
	IOEXP_TCA6416_OUTPUT = 0UL,
	IOEXP_TCA6416_INPUT = 0xFFFFFFFFUL,
} ioexp_io_conf_t;


typedef uint32_t ioexp_tca6416_registers_t[8];

status_code_t freertos_io_expander_tca6416_init(uint32_t interrupt_priority, portTickType max_block_time_ticks);
status_code_t freertos_io_expander_tca6416_write(ioexp_tca6416_commands_t command, uint32_t  data);
status_code_t freertos_io_expander_tca6416_set(ioexp_tca6416_commands_t command, uint32_t data_masks, uint32_t settings_mask);
status_code_t freertos_io_expander_tca6416_read(ioexp_tca6416_commands_t command, uint32_t length, uint8_t read_data[]);
status_code_t freertos_io_expander_tca6416_get(ioexp_tca6416_commands_t command, uint32_t data_masks,  uint32_t * settings_mask);
void check(void);
#endif /* TWI_IO_EXPANDER_TCA6416_H_ */