#include "drv_iic_back.h"
#include "nrf_delay.h"

static void IIC_BACK_Start(void)
{
	IIC_BACK_SDA_SET;
	IIC_BACK_SCL_SET;
	nrf_delay_us(5);
	IIC_BACK_SDA_CLR;
	nrf_delay_us(5);
	IIC_BACK_SCL_CLR;
}

static void IIC_BACK_Stop(void)
{
	IIC_BACK_SCL_CLR;
	IIC_BACK_SDA_CLR;
	nrf_delay_us(5);
	IIC_BACK_SCL_SET;
	IIC_BACK_SDA_SET;
	nrf_delay_us(5);
}

static void IIC_BACK_ACK(void)
{
	IIC_BACK_SCL_CLR;
	nrf_delay_us(1);
	IIC_BACK_SDA_CLR;
	nrf_delay_us(1);
	IIC_BACK_SCL_SET;
	nrf_delay_us(1);
	IIC_BACK_SCL_CLR;
}

static void IIC_BACK_NoACK(void)
{
	IIC_BACK_SCL_CLR;
	IIC_BACK_SDA_SET;
	nrf_delay_us(1);
	IIC_BACK_SCL_SET;
	nrf_delay_us(1);
	IIC_BACK_SCL_CLR;    
}

static bool IIC_BACK_WaitACK(void)
{
	uint8_t tim = 0;
//	IIC_BACK_SCL_CLR;
	IIC_BACK_SDA_SET;
	nrf_delay_us(1);
	IIC_BACK_SCL_SET;
//	nrf_delay_us(1);
	while(IIC_BACK_SDA_READ){
		if(++tim>=50){
			IIC_BACK_Stop();
			return false;
		}
		nrf_delay_us(1);
	}
	IIC_BACK_SCL_CLR;
	return true;
}

static void IIC_BACK_SendByte(uint8_t _byte)
{
	uint8_t i = 0;
	for (i=0; i<8; i++){
		IIC_BACK_SCL_CLR;
		nrf_delay_us(5);
		if (_byte&0x80)	IIC_BACK_SDA_SET;
		else IIC_BACK_SDA_CLR;
		_byte <<= 1;
		IIC_BACK_SCL_SET;
		nrf_delay_us(5);
	}
	IIC_BACK_SCL_CLR;
}

static uint8_t IIC_BACK_RecByte(void)
{
	uint8_t i = 0;
	uint8_t rec_byte;
   
	IIC_BACK_SDA_SET;
	for (i=0; i<8; i++){
		rec_byte <<= 1;
		IIC_BACK_SCL_CLR;
		nrf_delay_us(5);
		IIC_BACK_SCL_SET;
		nrf_delay_us(5);
		if (IIC_BACK_SDA_READ) rec_byte |= 0x01;
	} 
	IIC_BACK_SCL_CLR;
	return rec_byte;
}

/********************************************/
bool IIC_BACK_WriteBytes(uint8_t add,uint8_t reg,uint8_t* p,uint8_t len)
{
	uint8_t i = 0;
	IIC_BACK_Start();
	IIC_BACK_SendByte(add);
	if(!IIC_BACK_WaitACK()) return false;
	IIC_BACK_SendByte(reg);
	if(!IIC_BACK_WaitACK()) return false;
	for(i=0;i<len;i++){
		IIC_BACK_SendByte(p[i]);
		if(!IIC_BACK_WaitACK()) return false;
	}
	IIC_BACK_Stop();
	return true;
}

bool IIC_BACK_ReadBytes(uint8_t add,uint8_t reg,uint8_t* p,uint8_t len)
{
	uint8_t i = 0;
	IIC_BACK_Start();
	IIC_BACK_SendByte(add);
	if(!IIC_BACK_WaitACK()) return false;
	IIC_BACK_SendByte(reg);
	if(!IIC_BACK_WaitACK()) return false;
	IIC_BACK_Start();
	IIC_BACK_SendByte(add+1);
	if(!IIC_BACK_WaitACK()) return false;
	for(i=0;i<len-1;i++){
		p[i] = IIC_BACK_RecByte(); IIC_BACK_ACK();
	}
	p[i] = IIC_BACK_RecByte(); IIC_BACK_NoACK();
	IIC_BACK_Stop();
	return true;
}


void IIC_BACK_Init(void)
{
	nrf_gpio_cfg(
        PIN_BACK_SCL,
        NRF_GPIO_PIN_DIR_OUTPUT,
        NRF_GPIO_PIN_INPUT_DISCONNECT,
        NRF_GPIO_PIN_NOPULL,
        NRF_GPIO_PIN_S0S1,
        NRF_GPIO_PIN_NOSENSE);
	
	nrf_gpio_cfg_watcher(PIN_BACK_SCL);
	nrf_gpio_pin_set(PIN_BACK_SCL);
	
	nrf_gpio_cfg(
        PIN_BACK_SDA,
        NRF_GPIO_PIN_DIR_OUTPUT,
        NRF_GPIO_PIN_INPUT_DISCONNECT,
        NRF_GPIO_PIN_NOPULL,
        NRF_GPIO_PIN_S0S1,
        NRF_GPIO_PIN_NOSENSE);
	
	nrf_gpio_cfg_watcher(PIN_BACK_SDA);
	nrf_gpio_pin_set(PIN_BACK_SDA);
}

