#include "drv_iic_front.h"
#include "nrf_delay.h"

#define delayTime	1

static void IIC_FRONT_Start(void)
{
	IIC_FRONT_SDA_SET;
	IIC_FRONT_SCL_SET;
	nrf_delay_us(5);
	IIC_FRONT_SDA_CLR;
	nrf_delay_us(5);
	IIC_FRONT_SCL_CLR;
}

static void IIC_FRONT_Stop(void)
{
	IIC_FRONT_SCL_CLR;
	IIC_FRONT_SDA_CLR;
	nrf_delay_us(5);
	IIC_FRONT_SCL_SET;
	IIC_FRONT_SDA_SET;
	nrf_delay_us(5);
}

static void IIC_FRONT_ACK(void)
{
	IIC_FRONT_SCL_CLR;
	nrf_delay_us(1);
	IIC_FRONT_SDA_CLR;
	nrf_delay_us(1);
	IIC_FRONT_SCL_SET;
	nrf_delay_us(1);
	IIC_FRONT_SCL_CLR;
}

static void IIC_FRONT_NoACK(void)
{
	IIC_FRONT_SCL_CLR;
	IIC_FRONT_SDA_SET;
	nrf_delay_us(1);
	IIC_FRONT_SCL_SET;
	nrf_delay_us(1);
	IIC_FRONT_SCL_CLR;    
}

static bool IIC_FRONT_WaitACK(void)
{
	uint8_t tim = 0;
//	IIC_FRONT_SCL_CLR;
	IIC_FRONT_SDA_SET;
	nrf_delay_us(1);
	IIC_FRONT_SCL_SET;
//	nrf_delay_us(1);
	while(IIC_FRONT_SDA_READ){
		if(++tim>=50){
			IIC_FRONT_Stop();
			return false;
		}
		nrf_delay_us(1);
	}
	IIC_FRONT_SCL_CLR;
	return true;
}

static void IIC_FRONT_SendByte(uint8_t _byte)
{
	uint8_t i = 0;
	for (i=0; i<8; i++){
		IIC_FRONT_SCL_CLR;
//		nrf_delay_us(1);
		if (_byte&0x80)	IIC_FRONT_SDA_SET;
		else IIC_FRONT_SDA_CLR;
		_byte <<= 1;
		IIC_FRONT_SCL_SET;
	}
	IIC_FRONT_SCL_CLR;
}

static uint8_t IIC_FRONT_RecByte(void)
{
	uint8_t i = 0;
	uint8_t rec_byte;
   
	IIC_FRONT_SDA_SET;
	for (i=0; i<8; i++){
		rec_byte <<= 1;
		IIC_FRONT_SCL_CLR;
		IIC_FRONT_SCL_CLR;
		IIC_FRONT_SCL_CLR;
		IIC_FRONT_SCL_CLR;
//		nrf_delay_us(1);
		IIC_FRONT_SCL_SET;
//		nrf_delay_us(1);
		if (IIC_FRONT_SDA_READ) rec_byte |= 0x01;
	} 
	IIC_FRONT_SCL_CLR;
	return rec_byte;
}

/********************************************/
bool IIC_FRONT_WriteBytes(uint8_t add,uint8_t reg,uint8_t* p,uint8_t len)
{
	uint8_t i = 0;
	IIC_FRONT_Start();
	IIC_FRONT_SendByte(add);
	if(!IIC_FRONT_WaitACK()) return false;
	IIC_FRONT_SendByte(reg);
	if(!IIC_FRONT_WaitACK()) return false;
	for(i=0;i<len;i++){
		IIC_FRONT_SendByte(p[i]);
		if(!IIC_FRONT_WaitACK()) return false;
	}
	IIC_FRONT_Stop();
	return true;
}

bool IIC_FRONT_ReadBytes(uint8_t add,uint8_t reg,uint8_t* p,uint8_t len)
{
	uint8_t i = 0;
	IIC_FRONT_Start();
	IIC_FRONT_SendByte(add);
	if(!IIC_FRONT_WaitACK()) return false;
	IIC_FRONT_SendByte(reg);
	if(!IIC_FRONT_WaitACK()) return false;
	IIC_FRONT_Start();
	IIC_FRONT_SendByte(add+1);
	if(!IIC_FRONT_WaitACK()) return false;
	for(i=0;i<len-1;i++){
		p[i] = IIC_FRONT_RecByte(); IIC_FRONT_ACK();
	}
	p[i] = IIC_FRONT_RecByte(); IIC_FRONT_NoACK();
	IIC_FRONT_Stop();
	return true;
}


void IIC_FRONT_Init(void)
{
	nrf_gpio_cfg(
        PIN_QMC_LSM_FRONT_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_QMC_LSM_FRONT_SCL);
	nrf_gpio_pin_set(PIN_QMC_LSM_FRONT_SCL);
	
	nrf_gpio_cfg(
        PIN_QMC_LSM_FRONT_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_QMC_LSM_FRONT_SDA);
	nrf_gpio_pin_set(PIN_QMC_LSM_FRONT_SDA);
}

