#include "i2c.h"

uint16_t delay = 0x2fff;
//--------------------------------------------
//
//--------------------------------------------
void I2C_MyInit(void)
{
	GPIO_InitTypeDef 	GPIO_Init_I2C;
	I2C_InitTypeDef 	I2C1_Init;

		//SCL, SDA
		RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
		RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);

		GPIO_Init_I2C.GPIO_Pin 	    = GPIO_Pin_6|GPIO_Pin_7;
		GPIO_Init_I2C.GPIO_Mode 	= GPIO_Mode_AF;
		GPIO_Init_I2C.GPIO_Speed 	= GPIO_Speed_100MHz;
        GPIO_Init_I2C.GPIO_OType 	= GPIO_OType_OD;//т.к. 5В
		GPIO_Init_I2C.GPIO_PuPd 	= GPIO_PuPd_UP;

		GPIO_Init(GPIOB, &GPIO_Init_I2C);

		GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_I2C1);
		GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_I2C1);

		/*I2C1_Init.I2C_Timing 			    = 0x10420F13;//(0x3 << I2C_OFFSET_TIMINGR_PRESC)|(0xE  << I2C_OFFSET_TIMINGR_SCLDEL)|(0x3  << I2C_OFFSET_TIMINGR_SDADEL)|(0x2e  << I2C_OFFSET_TIMINGR_SCLH)|(0x37 << I2C_OFFSET_TIMINGR_SCLL);
		I2C1_Init.I2C_AnalogFilter 			= I2C_AnalogFilter_Enable;
		I2C1_Init.I2C_DigitalFilter 		= 0x00;
		I2C1_Init.I2C_Mode                  = I2C_Mode_I2C;
		I2C1_Init.I2C_OwnAddress1 			= 0x00;
		I2C1_Init.I2C_Ack 					= I2C_Ack_Enable;
		I2C1_Init.I2C_AcknowledgedAddress 	= I2C_AcknowledgedAddress_7bit;*/
        I2C1_Init.I2C_ClockSpeed            = 100000;
        I2C1_Init.I2C_Mode                  = I2C_Mode_I2C;
        I2C1_Init.I2C_DutyCycle             = I2C_DutyCycle_2;
        I2C1_Init.I2C_OwnAddress1           = 0x00;
        I2C1_Init.I2C_Ack                   = I2C_Ack_Enable;
        I2C1_Init.I2C_AcknowledgedAddress   = I2C_AcknowledgedAddress_7bit;

		I2C_Init(I2C1, &I2C1_Init);
        
        I2C_Cmd(I2C1, ENABLE);
}
//--------------------------------------------
//
//--------------------------------------------
RESULT_I2C I2C_StartTransmission(I2C_TypeDef* I2Cx, uint8_t transmissionDirection,  uint8_t slaveAddress)
{
    // На всякий слуыай ждем, пока шина осовободится
    while(I2C_GetFlagStatus(I2Cx, I2C_FLAG_BUSY)) {
        static uint16_t c;
        c++;
        if(c == delay) { c = 0; return RESULT_I2C_FLAG_BUSY; }
    }
 
    // Генерируем старт - тут все понятно )
    I2C_GenerateSTART(I2Cx, ENABLE);
 
    // Ждем пока взлетит нужный флаг
    while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_MODE_SELECT)) {
        static uint16_t c;
        c++;
        if(c == delay) { c = 0; return RESULT_I2C_EVENT_MASTER_MODE_SELECT; }
    }
 
    // Посылаем адрес подчиненному
    I2C_Send7bitAddress(I2Cx, slaveAddress, transmissionDirection);
 
    // А теперь у нас два варианта развития событий - в зависимости от выбранного направления обмена данными
    if(transmissionDirection== I2C_Direction_Transmitter)
    {
    	while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)) {
            static uint16_t c;
            c++;
            if(c == delay) { c = 0; return RESULT_I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED; }
        }
    }
 
    if(transmissionDirection== I2C_Direction_Receiver)
    {
        while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)) {
            static uint16_t c;
            c++;
            if(c == delay) { c = 0; return RESULT_I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED; }
        }
    }
    return RESULT_OK;
}
//--------------------------------------------
//
//--------------------------------------------
RESULT_I2C I2C_WriteData(I2C_TypeDef* I2Cx, uint8_t data)
{
    // Просто вызываем готоваую функцию из SPL и ждем, пока данные улетят
    I2C_SendData(I2Cx, data);
    while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED)) {
        static uint16_t c;
        c++;
        if(c == delay) { c = 0; return RESULT_I2C_EVENT_MASTER_BYTE_TRANSMITTED; }
    }
    return RESULT_OK;
}
//--------------------------------------------
//
//--------------------------------------------
uint8_t I2C_ReadData(I2C_TypeDef* I2Cx)
{
    uint8_t data;
    // Тут картина похожа, как только данные пришли быстренько считываем их и возвращаем
    while( !I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_RECEIVED) ) {
        static uint16_t c;
        c++;
        if(c == delay) { c = 0; break; }
    }
    data = I2C_ReceiveData(I2Cx);
    return data;
}
//--------------------------------------------
//
//--------------------------------------------
void I2C_MyStop(I2C_TypeDef* I2Cx)
{
    I2C_GenerateSTOP(I2Cx, ENABLE);
}
