#include "drv_iic_middle.h"
#include "nrf_delay.h"

static void IIC_MIDDLE_Start(void)
{
	IIC_MIDDLE_SDA_SET;
	IIC_MIDDLE_SCL_SET;
	nrf_delay_us(5);
	IIC_MIDDLE_SDA_CLR;
	nrf_delay_us(5);
	IIC_MIDDLE_SCL_CLR;
}

static void IIC_MIDDLE_Stop(void)
{
	IIC_MIDDLE_SCL_CLR;
	IIC_MIDDLE_SDA_CLR;
	nrf_delay_us(5);
	IIC_MIDDLE_SCL_SET;
	IIC_MIDDLE_SDA_SET;
	nrf_delay_us(5);
}

static void IIC_MIDDLE_ACK(void)
{
	IIC_MIDDLE_SCL_CLR;
	nrf_delay_us(1);
	IIC_MIDDLE_SDA_CLR;
	nrf_delay_us(1);
	IIC_MIDDLE_SCL_SET;
	nrf_delay_us(1);
	IIC_MIDDLE_SCL_CLR;
}

static void IIC_MIDDLE_NoACK(void)
{
	IIC_MIDDLE_SCL_CLR;
	IIC_MIDDLE_SDA_SET;
	nrf_delay_us(1);
	IIC_MIDDLE_SCL_SET;
	nrf_delay_us(1);
	IIC_MIDDLE_SCL_CLR;    
}

static bool IIC_MIDDLE_WaitACK(void)
{
	uint8_t tim = 0;
//	IIC_MIDDLE_SCL_CLR;
	IIC_MIDDLE_SDA_SET;
	nrf_delay_us(1);
	IIC_MIDDLE_SCL_SET;
//	nrf_delay_us(1);
	while(IIC_MIDDLE_SDA_READ){
		if(++tim>=50){
			IIC_MIDDLE_Stop();
			return false;
		}
		nrf_delay_us(1);
	}
	IIC_MIDDLE_SCL_CLR;
	return true;
}

static void IIC_MIDDLE_SendByte(uint8_t _byte)
{
	uint8_t i = 0;
	for (i=0; i<8; i++){
		IIC_MIDDLE_SCL_CLR;
		nrf_delay_us(5);
		if (_byte&0x80)	IIC_MIDDLE_SDA_SET;
		else IIC_MIDDLE_SDA_CLR;
		_byte <<= 1;
		IIC_MIDDLE_SCL_SET;
		nrf_delay_us(5);
	}
	IIC_MIDDLE_SCL_CLR;
}

static uint8_t IIC_MIDDLE_RecByte(void)
{
	uint8_t i = 0;
	uint8_t rec_byte;
   
	IIC_MIDDLE_SDA_SET;
	for (i=0; i<8; i++){
		rec_byte <<= 1;
		IIC_MIDDLE_SCL_CLR;
		nrf_delay_us(5);
		IIC_MIDDLE_SCL_SET;
		nrf_delay_us(5);
		if (IIC_MIDDLE_SDA_READ) rec_byte |= 0x01;
	} 
	IIC_MIDDLE_SCL_CLR;
	return rec_byte;
}

/********************************************/
bool IIC_MIDDLE_WriteBytes(uint8_t add,uint8_t reg,uint8_t* p,uint8_t len)
{
	uint8_t i = 0;
	IIC_MIDDLE_Start();
	IIC_MIDDLE_SendByte(add);
	if(!IIC_MIDDLE_WaitACK()) return false;
	IIC_MIDDLE_SendByte(reg);
	if(!IIC_MIDDLE_WaitACK()) return false;
	for(i=0;i<len;i++){
		IIC_MIDDLE_SendByte(p[i]);
		if(!IIC_MIDDLE_WaitACK()) return false;
	}
	IIC_MIDDLE_Stop();
	return true;
}

bool IIC_MIDDLE_ReadBytes(uint8_t add,uint8_t reg,uint8_t* p,uint8_t len)
{
	uint8_t i = 0;
	IIC_MIDDLE_Start();
	IIC_MIDDLE_SendByte(add);
	if(!IIC_MIDDLE_WaitACK()) return false;
	IIC_MIDDLE_SendByte(reg);
	if(!IIC_MIDDLE_WaitACK()) return false;
	IIC_MIDDLE_Start();
	IIC_MIDDLE_SendByte(add+1);
	if(!IIC_MIDDLE_WaitACK()) return false;
	for(i=0;i<len-1;i++){
		p[i] = IIC_MIDDLE_RecByte(); IIC_MIDDLE_ACK();
	}
	p[i] = IIC_MIDDLE_RecByte(); IIC_MIDDLE_NoACK();
	IIC_MIDDLE_Stop();
	return true;
}


void IIC_MIDDLE_Init(void)
{
	nrf_gpio_cfg(
        PIN_QMA7981_SCLK,
        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_QMA7981_SCLK);
	nrf_gpio_pin_set(PIN_QMA7981_SCLK);
	
	nrf_gpio_cfg(
        PIN_QMA7981_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_QMA7981_SDA);
	nrf_gpio_pin_set(PIN_QMA7981_SDA);
}

