/**
 * @file eeprom.c
 * @author Chen Jihang (embedded@eseaoptics.com)
 * @brief EEPROM驱动
 * @version 1.0
 * @date 2023-01-04
 *
 * @copyright ESEA (c) 2020
 *
 */
#include "eeprom.h"

osThreadId_t eepromTaskHandle;
const osThreadAttr_t eepromTask_attributes = {
  .name = "eepromTask",
  .stack_size = 256 * 4,
  .priority = (osPriority_t) osPriorityNormal,
};

uint8_t  eeprom_read_buf[1024] ={0};

#define pEepromI2C &hi2c1

I2C_HELPER_TypeDef *eeprom_helper;

// EEPROM_TypeDef *eeprom;


My_EEPROM_TypeDef my_eeprom=
{
    Eeprom_Init,  Eeprom_Port,  Eeprom_Test,
 
    AT24C02,
    EEPROM_MEM_ADDR_TYPE_Bit8,
    0xA0,   // 7+1 bit or 10 + 1 bit, EEPROM 8bit , write A0 , read  A1
    0,
    8,
    0,NULL,
    0,
};

void Eeprom_Init()
{

    eeprom_helper = I2C_HELPER_Init( );
    I2C_HELPER_Set_Hi2c( eeprom_helper,  pEepromI2C );
    I2C_HELPER_Set_dev_addr( eeprom_helper, EEPROM_WRITE_ADDRESS);
    I2C_HELPER_Set_mem_addr_size( eeprom_helper,  I2C_MEMADD_SIZE_8BIT );  //I2C_MEMADD_SIZE_8BIT
    // I2C_HELPER_Set_mem_addr(ads1115_i2c_helper, uint16_t mem_addr);

    // I2C_HELPER_Setup_Trans_mode( eeprom_helper, I2C_Trans_IT );

    //  设置回调
    I2C_HELPER_Set_Callback( eeprom_helper,  (void *)&my_eeprom, (i2c_callback_fun) Eeprom_callback);

    return 0;
}

 

void Eeprom_Port(  )
{
    eepromTaskHandle = osThreadNew(Eeprom_Task, NULL, &eepromTask_attributes );
}

void Eeprom_Task(  )
{
    uint64_t  ticks;
    int count = 0;
    int st;
    for (;;)
    {
        switch (my_eeprom.state)
        {
        case EEPROM_WORK_STATE_WAITING:
            log_d( " eeporm waiting  ********** "  );
            osDelay(20);
            break;
        case EEPROM_WORK_STATE_READY:
            // log_d( " eeporm ready  ********** "  );
            osDelay(1);
            break;
        case EEPROM_WORK_STATE_Writing:
            log_d( " eeporm writing  ********** %d" ,count );
            if (my_eeprom.size == 0 )
            {
                my_eeprom.state = EEPROM_WORK_STATE_STOP;
            }
            I2C_HELPER_Set_mem_addr( eeprom_helper, count );
            st = I2C_HELPER_Trans( eeprom_helper, my_eeprom.buf, 1 );
            ticks =  osKernelGetTickCount();
            my_eeprom.state = EEPROM_WORK_STATE_WRITE_Waiting;
            break;   
        case EEPROM_WORK_STATE_WRITE_Waiting:
            if (osKernelGetTickCount()-ticks >my_eeprom.write_delay_ms){
                count++;
                my_eeprom.size--;
                my_eeprom.buf++;
            }
            if (my_eeprom.size> 0 )
            {
                my_eeprom.state = EEPROM_WORK_STATE_Writing;
                continue;
            }
            my_eeprom.state = EEPROM_WORK_STATE_STOP;
            count = 0;
            break;
        case EEPROM_WORK_STATE_Reading:
            I2C_HELPER_Set_mem_addr(eeprom_helper, 0);
            while( I2C_HELPER_Start_Rcv( eeprom_helper, eeprom_read_buf, 24 ) != HAL_OK )
            {
                osDelay(1);
            }
            // log_d( "  eeprom_read_buf **********  %02X   %02X " ,eeprom_read_buf[0],eeprom_read_buf[23] );
            // 或等到 I2C 状态为 ready
            // while(i2c_get_state(&i2c_buf)!=0){
            //     if(time_clock_get_time_offset_ms(&time)>1000){
            //         return -1;
            //     }
            // }
            my_eeprom.state = EEPROM_WORK_STATE_STOP;
            break; 
        case EEPROM_WORK_STATE_ERROR:
            log_w( " ADS1115 error ..... "  );
            // my_ads1115.state  = ADS1115_WORK_STATE_WAITING ;
            osDelay(10);
            continue;    
        case EEPROM_WORK_STATE_STOP:
            log_w( " ADS1115 stop..... "  );
            // my_ads1115.state  = ADS1115_WORK_STATE_WAITING ;
            osDelay(10);
            continue;  
        default:
            break;
        }
        // /* 判断size, size 大于零才开始工作*/
        // if (eeprom->size == 0) 
        // {
        //     eeprom->send_buf = NULL;
        //     eeprom->is_busy == 0;
        //     // log_i("eeprom port func...");
        //     osDelay(100);
        // };

        // /* size> 0, 写入一个数据 */
        // if ( eeprom->size > 0 && eeprom->writeCplt == 0 && eeprom->is_busy == 0 )
        // {
        //     eeprom->time_base   = osKernelGetTickCount( );
        //     eeprom->is_busy     = 1;
        //     // log_i("eeporm  write ... "); 
        //     st = HAL_I2C_Mem_Write(eeprom->hi2c, eeprom->dev_addr, AT24C02, eeprom->mem_addr_type, eeprom->send_buf, 1, eeprom->write_delay_ms);
        //     if (st != HAL_OK) {
        //         log_e(" Eeprom Write error");
        //         eeprom->size        = 0;
        //         eeprom->send_buf    = NULL;
        //         eeprom->is_busy     = 0;        
        //         break;        
        //     }
        //     // I2CHelper_Write( eeprom->i2chelper, eeprom->send_buf, 1 );
        //     continue;
        // };

        // /*  等待 eeprom->write_delay_ms ，写入数据*/
        // if ( eeprom->size > 0 && eeprom->writeCplt == 0 && eeprom->is_busy == 1 )
        // {
        //     if( (osKernelGetTickCount( ) - eeprom->time_base)  > eeprom->write_delay_ms)
        //     {
        //         // log_i("eeporm  write ... 5ms "); 
        //         eeprom->writeCplt = 1 ;
        //     }
        //     continue;
        // };

        // /* 写完成，处理数据等待进入下一组 */
        // if ( eeprom->size > 0 && eeprom->writeCplt == 1 )
        // {
        //     eeprom->send_buf++;
        //     eeprom->mem_addr++;
        //     eeprom->size--;
        //     eeprom->is_busy = 0; 
        //     eeprom->writeCplt = 0;
        //     continue;
        // };
        osDelay( 10);
    }
}

int Eeprom_Test(  )
{
    uint8_t test_send[1] = { 0xFF  };  // 不同model,地址不同  方法也不同
    uint8_t test_rcv  = 0;
    int st;
    //  write
    I2C_HELPER_Set_mem_addr( eeprom_helper, AT24C02 );
    st = I2C_HELPER_Trans( eeprom_helper, test_send, 1 );

    HAL_Delay(my_eeprom.write_delay_ms);

    // // Read
    I2C_HELPER_Set_mem_addr(eeprom_helper, AT24C02);
    st = I2C_HELPER_Start_Rcv(eeprom_helper, (uint8_t *)&test_rcv , 2);  

    if ( test_rcv == 255 ){
        return 0;
    }
 
    return -1;
}

int Eeprom_callback(My_EEPROM_TypeDef *pEeprom, uint8_t *buf, uint16_t size)
{
    // switch (my_eeprom.state)
    // {
    //     // case ADS1115_WORK_STATE_TESTING :
    //     //     my_ads1115.state++;
    //     //     break;
    //     // case ADS1115_WORK_STATE_GET_DATA_SET_REG01_Wait :
    //     //     my_ads1115.state++;
    //     //     break;
    //     // case ADS1115_WORK_STATE_GET_DATA_RCV_Wait :
    //     //     // TODO Check data?
    //     //     my_ads1115.state++;
    //     //     break;        
    //     default:
    //         break;
    // }
 
} 

int Eeprom_SET_Device_Model(EEPROM_MODEL_TypeDef model)
{
    my_eeprom.model = model;
    if (my_eeprom.model < AT24C04 )
    {
        I2C_HELPER_Set_mem_addr_size( eeprom_helper,  I2C_MEMADD_SIZE_8BIT );
    }else{
        I2C_HELPER_Set_mem_addr_size( eeprom_helper,  I2C_MEMADD_SIZE_16BIT );
    }
    return 0;
}


int Eeprom_SET_Write_Delay_ms(uint8_t write_delay_ms)
{
    my_eeprom.write_delay_ms = write_delay_ms;
    return 0;
}

// int Eeprom_Transmit(EEPROM_TypeDef *eeprom,  uint8_t * buf, uint16_t size)
// {
//     // HAL_I2C_Master_Transmit_DMA ( eeprom->i2chelper->hi2c, eeprom->dev_addr, buf ,size );
// }

// int Eeprom_Begin_Rcv(EEPROM_TypeDef *eeprom,  uint8_t * buf, uint16_t size)
// {
//     // HAL_I2C_Master_Receive_IT( eeprom->i2chelper->hi2c, eeprom->dev_addr, buf ,size );
//     // I2CHelper_Begin_Rcv(eeprom->i2chelper,   buf, size);

// //  HAL_I2C_Mem_Read(eeprom->i2c, eeprom->dev_addr, mem_addr, eeprom->mem_addr_type, buf, 1,eeprom->write_delay_ms);
// //  HAL_I2C_Mem_Write(eeprom->i2c, eeprom->dev_addr, mem_addr, eeprom->mem_addr_type, buf, 1,eeprom->write_delay_ms);

// }

int Eeprom_Read(  uint8_t * buf, uint16_t size)
{
    int st;
    // st = HAL_I2C_Mem_Read( eeprom->hi2c, eeprom->dev_addr, eeprom->mem_addr, eeprom->mem_addr_type, buf, size, 0xFFFF);
    if ( st != HAL_OK ) {
        return -1;
    }
    return 0;
    // HAL_I2C_Master_Transmit_IT (eeprom->hi2c, eeprom->dev_addr, buf ,size);
}

int Eeprom_Write(  uint8_t * buf, uint16_t size)
{
    my_eeprom.buf    = buf;
    my_eeprom.size        = size;
    int st;
    // st = HAL_I2C_Mem_Read( eeprom->hi2c, eeprom->dev_addr, eeprom->mem_addr, eeprom->mem_addr_type, buf, size, 0xFFFF);
    if ( st != HAL_OK ) {
        return -1;
    }
    return 0;
    // HAL_I2C_Master_Transmit_IT (eeprom->hi2c, eeprom->dev_addr, buf ,size);
}
 

void Eeprom_Set_Sendbuf_Size(   uint8_t * buf, uint16_t size)
{
    my_eeprom.buf    = buf;
    my_eeprom.size        = size;
    return ;
}



// //主机模式发送回调函数
// void HAL_I2C_MasterTxCpltCallback(I2C_HandleTypeDef *I2cHandle)
// {
//     if (I2cHandle == pEepromI2C)
//     {
//         eeprom->writeCplt =1;
//         log_i("send cplt");
//     }
// }
// //主机模式接收回调函数
// void HAL_I2C_MasterRxCpltCallback(I2C_HandleTypeDef *I2cHandle)
// {
//     if (I2cHandle == pEepromI2C)
//     {
//         eeprom->readCplt =1;
//         log_i("rcv cplt");
//     }
// }


// https://blog.csdn.net/qq_35496059/article/details/101279408
// void I2C3_EV_IRQHandler(void)
// {
//   /* USER CODE BEGIN I2C3_EV_IRQn 0 */

//   /* USER CODE END I2C3_EV_IRQn 0 */
// 	loop1:
//   	HAL_I2C_EV_IRQHandler(&hi2c3);
//   /* USER CODE BEGIN I2C3_EV_IRQn 1 */
// 	if((((I2C3->ISR)&0x08)>>3)==1)//判断是addr触发的中断
// 	{
// 		I2C3->ISR|=0x01;//TXE=1
// 		I2C3->ICR|=0x08;//清除addr
// 	}

// //读写处理
// 		{
			
// 			if((((I2C3->ISR)&0x10000)>>16)==1)//dir
// 			{
// 				int i=0;
// 				int j=0;
// 				while(((((I2C3->ISR)&0x32)>>5)==0))//detect stop
// 				{
// 					if(((((I2C3->ISR)&0x10000)>>16)==0)||((((I2C3->ISR)&0x08)>>3)==1))//addr or read
// 				goto loop1;			
// 				if(((((I2C3->ISR)&0x02)>>1)==1))TXIS
// 				{
// 					if(I2C3->RXDR==0x00)
// 					I2C3->TXDR=ppp1[i];
// 					if(I2C3->RXDR==0x12)
// 					{
// 						I2C3->TXDR=ppp2[i];
						
// 					}
					
// 					//[i]=I2C3->RXDR;
// 					i++;
			
// 				}
// 						if(i==21)
// 					{
// 					//21个字节 退出	
// 						ppp2[0]++;
// 						return;
// 					}
			
// 				}
				
// 				//x=HAL_I2C_Slave_Receive(&hi2c3,ppp,2,5);
// 				I2C3->ICR=(I2C3->ICR)|0x32;//clear stop

// 			else//read
// 			{
// 				int i=0;
// 				while(((((I2C3->ISR)&0x32)>>5)==0))//detect stop
// 				{
// 					if(((((I2C3->ISR)&0x10000)>>16)==1)||((((I2C3->ISR)&0x08)>>3)==1))
// 						goto loop1;					
// 					if(((((I2C3->ISR)&0x04)>>2)==1))//RXNE
// 					{
// 						ppp[i]=I2C3->RXDR;
// 						i++;
// 					}
// 					}
// 				//x=HAL_I2C_Slave_Receive(&hi2c3,ppp,2,5);
// 				I2C3->ICR=(I2C3->ICR)|0x32;
// 			}
	
// 		}

// //	I2C3->CR1|=0x08;

// //  /* USER CODE END I2C3_EV_IRQn 1 */
// }

// 寄存器说明
// ISR:
// |bit23…17|ADDCODE ----|主机地址----------|
// |bit16…|DIR------------------|0读/1写------------|在addr=1时更新
// |bit15…|BUSY---------------| ---------------------|起始信号=1，检测到stop=0
// |bit5…|STOPF---------------|----------------------|检测到stop
// |bit3…|ADDR----------------|----------------------|匹配到地址
// |bit2…|RXNE----------------|----------------------|RXDR不为空
// |bit1…|TXIS------------------|-------------------- -|发送标志
// |bit0…|TXE------------------|-----------------------|TXDR为空
 

















// uint8_t Eeprom_SET_I2C(eeprom_t *eeprom, I2C_HandleTypeDef *i2c)
// {
//     eeprom->i2c = i2c;
//     eeprom->stat = HAL_I2C_STATE_READY;
//     return 0;
// }
// uint8_t Eeprom_SET_Device_Model(eeprom_t *eeprom, uint16_t model)
// {
//     eeprom->model = model;
//     // if (eeprom->model < AT24C16)
//     // {
//     //     eeprom->mem_addr_type = I2C_MEMADD_SIZE_8BIT;
//     // }
//     // else
//     // {
//     //     eeprom->mem_addr_type = I2C_MEMADD_SIZE_16BIT;
//     // }
//     return 0;
// }

// uint8_t Eeprom_SET_Device_Addr(eeprom_t *eeprom, uint8_t dev_addr)
// {
//     eeprom->dev_addr = dev_addr;
//     return 0;
// }

// uint8_t Eeprom_SET_Mem_Addr_Type(eeprom_t *eeprom, uint8_t mem_addr_type)
// {
//     eeprom->mem_addr_type = mem_addr_type;
//     return 0;
// }

// uint8_t Eeprom_SET_Workmode(eeprom_t *eeprom, uint8_t workmode)
// {
//     eeprom->WORKMODE = workmode;
//     return 0;
// }

// uint8_t Eeprom_Read_One_Byte(eeprom_t *eeprom, uint16_t mem_addr, uint8_t *buf)
// {
//     // eeprom->stat = HAL_I2C_Mem_Read_IT(eeprom->i2c, eeprom->dev_addr, mem_addr, eeprom->mem_addr_type, buf, 1);
//     return HAL_I2C_Mem_Read(eeprom->i2c, eeprom->dev_addr, mem_addr, eeprom->mem_addr_type, buf, 1,eeprom->write_delay_ms);
// }

// uint8_t Eeprom_Write_One_Byte(eeprom_t *eeprom, uint16_t mem_addr, uint8_t *buf)
// {
//     return HAL_I2C_Mem_Write(eeprom->i2c, eeprom->dev_addr, mem_addr, eeprom->mem_addr_type, buf, 1,eeprom->write_delay_ms);

// }

// uint8_t Eeprom_Read_One_Byte_IT(eeprom_t *eeprom, uint16_t mem_addr, uint8_t *buf)
// {
//     // eeprom->stat = HAL_I2C_Mem_Read_IT(eeprom->i2c, eeprom->dev_addr, mem_addr, eeprom->mem_addr_type, buf, 1);
//     eeprom->size  = 0;
//     return HAL_I2C_Mem_Read_IT(eeprom->i2c, eeprom->dev_addr, mem_addr, eeprom->mem_addr_type, buf, 1 );
// }

// uint8_t Eeprom_Write_One_Byte_IT(eeprom_t *eeprom, uint16_t mem_addr, uint8_t *buf)
// {
//     eeprom->size  = 0;
//     return HAL_I2C_Mem_Write_IT(eeprom->i2c, eeprom->dev_addr, mem_addr, eeprom->mem_addr_type, buf, 1 );
// }

// uint8_t Eeprom_Read_Multi_Byte(eeprom_t *eeprom, uint16_t mem_addr, uint8_t *buf, uint16_t size, uint32_t timeout )
// {
//     // eeprom->stat = HAL_I2C_Mem_Write_IT(eeprom->i2c, eeprom->dev_addr, mem_addr, eeprom->mem_addr_type, buf, size);
//     return HAL_I2C_Mem_Read(eeprom->i2c, eeprom->dev_addr, mem_addr, eeprom->mem_addr_type, buf, size,timeout);

// }

// uint8_t Eeprom_Write_Multi_Byte(eeprom_t *eeprom, uint16_t mem_addr, uint8_t *buf, uint16_t size, uint32_t timeout )
// {
//     return HAL_I2C_Mem_Write(eeprom->i2c, eeprom->dev_addr, mem_addr, eeprom->mem_addr_type, buf, size,timeout);

// }

// uint8_t Eeprom_Read_Multi_Byte_IT(eeprom_t *eeprom, uint16_t mem_addr, uint8_t *buf, uint16_t size  )
// {
//     // eeprom->stat = HAL_I2C_Mem_Write_IT(eeprom->i2c, eeprom->dev_addr, mem_addr, eeprom->mem_addr_type, buf, size);
//     eeprom->stat =HAL_I2C_Mem_Read_IT(eeprom->i2c, eeprom->dev_addr, mem_addr, eeprom->mem_addr_type, buf, size );
//     // LOG(" readstat %d",eeprom->stat);
//     return eeprom->stat;

// }

// uint8_t Eeprom_Write_Multi_Byte_IT(eeprom_t *eeprom, uint16_t mem_addr, uint8_t *buf, uint16_t size  )
// {
//     // 写入数据前端循环调用  Eeprom_send_callback
//     // return HAL_I2C_Mem_Write_IT(eeprom->i2c, eeprom->dev_addr, mem_addr, eeprom->mem_addr_type, buf, size );
//     eeprom->send_buf = buf;
//     eeprom->size  = size;
//     eeprom->mem_addr = mem_addr;
//     return 0;
 
// }

// /**
//  * @brief EEPROM发送回调,须循环调用单字节写入
//  *
//  * @param eeprom EEPROM描述符
//  * @return int 0
//  */
// uint8_t Eeprom_send(eeprom_t *eeprom)
// {
//     if (eeprom->size == 0)
//     {
//         eeprom->send_buf = NULL;
//     }
//     if (eeprom->send_buf == NULL)
//     {
//         return 0;
//     }
//     if ( HAL_I2C_GetState(eeprom->i2c) == 1 )
//     {
//         return 0;
//     }
//     if ( (osKernelGetTickCount() -eeprom->time_base) < eeprom->write_delay_ms )
//     {
//         return 0;
//     }
//     if ( HAL_I2C_GetState(eeprom->i2c) == 2 )
//     {
//         // __HAL_I2C_CLEAR_FLAG(eeprom->i2c,I2C_FLAG_AF); //  清除非应答状态
//         eeprom->i2c->State = HAL_I2C_STATE_READY;
//         // i2c_clear_state(eeprom->i2c);
//         eeprom->mem_addr--;
//         eeprom->send_buf--;
//         eeprom->size++;
//     }
//     if (eeprom->size == 0)
//     {
//         eeprom->send_buf = NULL;
//         return 0;
//     }

//     // 单个字节写入 ?? 为什么指向的地址内容发送变化了,静态声明
//     // LOG(  " send  buf  : %02x    %d", *eeprom->send_buf, eeprom->send_buf);
//     HAL_I2C_Mem_Write_IT(eeprom->i2c, eeprom->dev_addr, eeprom->mem_addr, eeprom->mem_addr_type, eeprom->send_buf, 1 );
//     // i2c_write_memory(eeprom->i2c,eeprom->dev_addr+eeprom->page_addr,eeprom->mem_addr,eeprom->mem_addr_size,eeprom->send_buf,1);
//     // eeprom->time_base = __get_tick_milliseconds();
//     eeprom->time_base = osKernelGetTickCount();
//     eeprom->mem_addr++;
//     eeprom->send_buf++;
//     eeprom->size--;
//     return 0;
// }

// void Eeprom_send_callback(eeprom_t *eeprom)
// {
//     Eeprom_send(eeprom);
// }

// uint8_t Eeprom_get_state(eeprom_t *eeprom)
// {
//     if (eeprom->send_buf != NULL)
//     {
//         return 1;
//     }
//     if ( HAL_I2C_GetState(eeprom->i2c) == HAL_I2C_STATE_READY )
//     {
//         return 0;
//     };
//     return 2;
// }