/** * @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; // }