#include "IIC.h"
//frequent 400kHZ
uint32_t T = 0;
//void Delay5us(void)//2.5us
//{
//    nop();nop(); nop();nop(); nop();nop(); nop();nop();
//    nop();nop(); nop();nop(); nop();nop(); nop();nop();
//    //nop();nop(); nop();nop(); nop();nop();
//    nop();nop(); nop();nop(); nop();nop(); nop();nop();
//    nop();nop(); nop();nop(); nop();nop();
//}
void Delay5us(void)//2.5us
{
    nop();nop(); nop();nop(); nop();nop(); nop();nop();
    nop();nop(); nop();nop(); nop();nop(); nop();nop();
    nop();nop(); nop();nop(); nop();nop(); nop();nop();
    nop();nop(); nop();nop(); nop();nop();

}
//i2c pins initial
void HMC5883_InitPin(void)
{
    I2C_GPIO->DDR |= (I2C_SCL_PIN)|(I2C_SDA_PIN);
    I2C_GPIO->CR1 |= ((I2C_SCL_PIN)|(I2C_SDA_PIN));
    I2C_GPIO->CR2 |= (I2C_SCL_PIN)|(I2C_SDA_PIN);
    I2C_GPIO->ODR &= ~((I2C_SCL_PIN)|(I2C_SDA_PIN));
    SCL_L;
    Delay5us();
    asm("NOP;");
}

bool HMC5883_Start(void)
{
	SDA_H;
	SCL_H;
        Delay5us();
	SDA_L;
        Delay5us();
	SCL_L;
        Delay5us();
	return TRUE;
}

void HMC5883_Stop(void)
{
	SDA_L;
        SCL_H;
	Delay5us();
        SDA_H;
        Delay5us();
        SCL_L;
        Delay5us();
}

bool HMC5883_WaitACK(void)
{
        SDA_H;
        SDA_IN;
        Delay5us();
        SCL_H;
        Delay5us();
        if(SDA_read){SCL_L;SDA_OUT;return FALSE;}
        Delay5us();
        SCL_L;
        SDA_OUT;
        return TRUE;
}

/**************************************
发送应答信号
入口参数:ack (0:ACK 1:NAK)
**************************************/
void HMC5883_SendACK(bool ack)
{
	if(ack==TRUE)SDA_H;
	else{SDA_L;}
        Delay5us();
	SCL_H;
        Delay5us();
        SCL_L;
        Delay5us();
}

/*I2C的NoACK函数----------------------------------------*/
void I2C_NoAck(void)
{
	SCL_L;
	Delay5us();
	SDA_H;
	Delay5us();
	SCL_H;
	Delay5us();
	SCL_L;
	Delay5us();
}


bool HMC5883_SendByte(BYTE dat)
{
    BYTE i;

    for (i=0; i<8; i++)         //8位计数器
    {
        if(dat&0x80)SDA_H;
        else
          SDA_L;
        Delay5us();
        SCL_H;
        Delay5us();
        SCL_L;
       // Delay5us();
        dat<<=1;
    }
    asm("NOP");
    if(!HMC5883_WaitACK())return FALSE;
    return TRUE;
}
/**************************************
从IIC总线接收一个字节数据
**************************************/
BYTE HMC5883_RecvByte()
{
    BYTE i;
    BYTE dat = 0;
    SDA_H;
    SDA_IN;
    //使能内部上拉,准备读取数据,
    for (i=0; i<8; i++)         //8位计数器
    {
        dat <<= 1;
        SCL_H;             //拉高时钟线
        Delay5us();             //延时
        if(SDA_read)dat|=0x01;//读数据
        SCL_L;                //拉低时钟线
        Delay5us();             //延时
    }
    SDA_OUT;
    return dat;
}

bool error_id = FALSE;
uint8_t count1 = 0;
//************************写入单字节数据***************************

bool Single_Write_HMC5883(uchar SlaveAddress,uchar REG_Address,uchar REG_data)
{

    uint8_t cnt = 0;
    while(cnt++<5)
    {
          count1++;
          HMC5883_Start();                  //起始信号
          HMC5883_SendByte(SlaveAddress);   //发送设备地址+写信号
          HMC5883_SendByte(REG_Address);    //内部寄存器地址，请参考中文pdf
          error_id=HMC5883_SendByte(REG_data);       //内部寄存器数据，请参考中文pdf
          HMC5883_Stop();
          if(!error_id)break;
    }
    asm("NOP");
    if(cnt>=5)return FALSE;
    else
      return TRUE;
}



//************************读取内部寄存器*************************
uchar Single_Read_HMC5883(uchar SlaveAddress,uchar REG_Address)
{
     uchar REG_data;
     asm("NOP;");
     HMC5883_Start();                          //起始信号
     HMC5883_SendByte(SlaveAddress);           //发送设备地址+写信号
     HMC5883_SendByte(REG_Address);            //发送存储单元地址，从0开始
     HMC5883_Start();                          //起始信号
     HMC5883_SendByte(SlaveAddress+1);         //发送设备地址+读信号
     REG_data=HMC5883_RecvByte();              //读出寄存器数据
            HMC5883_SendACK(TRUE);
            HMC5883_Stop();                           //停止信号
     return REG_data;
}

//************************读取内部寄存器*************************
/*
uchar Single_Read_HMC5883(uchar SlaveAddress,uchar REG_Address)
{
     uchar REG_data;
     HMC5883_Start();                          //起始信号
     HMC5883_SendByte(SlaveAddress);           //发送设备地址+写信号
     HMC5883_SendByte(REG_Address);            //发送存储单元地址，从0开始
     HMC5883_Start();                          //起始信号
     HMC5883_SendByte(SlaveAddress+1);         //发送设备地址+读信号
     REG_data=HMC5883_RecvByte();              //读出寄存器数据
            HMC5883_SendACK(TRUE);
            HMC5883_Stop();                           //停止信号
     return REG_data;
}
*/
void Multiple_Read_HMC5883(uchar SlaveAddress,uchar *BUFF)
{   uchar i;
    HMC5883_Start();                          //起始信号
    HMC5883_SendByte(SlaveAddress);           //发送设备地址+写信号
    HMC5883_SendByte(0x00);                   //发送存储单元地址，从0x3开始
    HMC5883_Start();                          //起始信号
    HMC5883_SendByte(SlaveAddress+1);         //发送设备地址+读信号
    for (i=0; i<6; i++)                      //连续读取6个地址数据，存储中BUF
    {
        BUFF[i] = HMC5883_RecvByte();          //BUF[0]存储数据
        if (i == 5)
        {
           HMC5883_SendACK(TRUE);                //最后一个数据需要回NOACK
        }
        else
        {
          HMC5883_SendACK(FALSE);                //回应ACK
        }
   }
    HMC5883_Stop();                          //停止信号
}

//初始化HMC5883，根据需要请参考pdf进行修改****

uint8_t hhj = 0;
bool Init_HMC5883()
{
     int temp = 0;
     HMC5883_InitPin();
     temp += Single_Write_HMC5883(SLAVE_ADD,0x0a,0x00);
     temp += Single_Write_HMC5883(SLAVE_ADD,0x09,0x11);
     temp += Single_Write_HMC5883(SLAVE_ADD,0x0B,0x01);
     asm("NOP");
     if(temp<3)return FALSE;
     else
       return TRUE;
}



