AT24Cxx驱动(优化)

发布于 2022-10-11  548 次阅读


#include <string.h>
#include <stdlib.h>
#include "stdio.h"

#include "at24cxx.h"




#ifdef PKG_USING_AT24CXX

//#define DRV_DEBUG

#ifdef DRV_DEBUG 
#define LOG_E(...)	lwlog_debug(__VA_ARGS__, "")
#define LOG_D(...)	lwlog_debug(__VA_ARGS__, "")
#else
#define LOG_E(...)
#define LOG_D(...)
#endif

#define AT24CXX_ADDR (0xA0)                      //A0 A1 A2 connect GND


#if (EE_TYPE == AT24C01)
    #define AT24CXX_PAGE_BYTE               8
    #define AT24CXX_MAX_MEM_ADDRESS         128
#elif (EE_TYPE == AT24C02)
    #define AT24CXX_PAGE_BYTE               8
    #define AT24CXX_MAX_MEM_ADDRESS         256
#elif (EE_TYPE == AT24C04)
    #define AT24CXX_PAGE_BYTE               16
    #define AT24CXX_MAX_MEM_ADDRESS         512
#elif (EE_TYPE == AT24C08)
    #define AT24CXX_PAGE_BYTE               16
    #define AT24CXX_MAX_MEM_ADDRESS         1024
#elif (EE_TYPE == AT24C16)
    #define AT24CXX_PAGE_BYTE               16
    #define AT24CXX_MAX_MEM_ADDRESS         2048
#elif (EE_TYPE == AT24C32)
    #define AT24CXX_PAGE_BYTE               32
    #define AT24CXX_MAX_MEM_ADDRESS         4096
#elif (EE_TYPE == AT24C64)
    #define AT24CXX_PAGE_BYTE               32
    #define AT24CXX_MAX_MEM_ADDRESS         8192
#elif (EE_TYPE == AT24C128)
    #define AT24CXX_PAGE_BYTE               64
    #define AT24CXX_MAX_MEM_ADDRESS         16384
#elif (EE_TYPE == AT24C256)
    #define AT24CXX_PAGE_BYTE               64
    #define AT24CXX_MAX_MEM_ADDRESS         32768
#elif (EE_TYPE == AT24C512)
    #define AT24CXX_PAGE_BYTE               128
    #define AT24CXX_MAX_MEM_ADDRESS         65536
#endif


/** 函数名:
  * 功能	:
  * 输入	:
	* 输出	:
	* 编写人:XMW
  */
const static char *EE_Type_Str[] = 
{
	"AT24C01",  
	"AT24C02",  
	"AT24C04",  
	"AT24C08",  
	"AT24C16",  
	"AT24C32",  
	"AT24C64",  
	"AT24C128", 
	"AT24C256", 
	"AT24C512", 
	"AT24CTYPE"
};

/** 函数名:rt_hw_ms_delay
  * 功能	:
  * 输入	:
	* 输出	:
	* 编写人:XMW
  */
void rt_hw_ms_delay(uint32_t ms)
{
	osDelay(ms);
}

/** 函数名:read_regs
  * 功能	:读取寄存器
  * 输入	:
	* 输出	:
	* 编写人:XMW
  */
static uint8_t read_regs(at24cxx_device_t dev, uint8_t len, uint8_t *buf)
{
    if (HAL_I2C_Master_Receive(dev->i2c,AT24CXX_ADDR,buf,len,10) == HAL_OK)
    {
        return AT_EOK;
    }
    else
    {
        return AT_ERROR;
    }
}

/** 函数名:at24cxx_read_one_byte
  * 功能	:
  * 输入	:
	* 输出	:
	* 编写人:XMW
  */
uint8_t at24cxx_read_one_byte(at24cxx_device_t dev, uint16_t readAddr)
{
    uint8_t buf[2];
    uint8_t temp;
		if(dev->DevType.eeType > AT24C16)
		{
			buf[0] = (uint8_t)(readAddr>>8);	
			buf[1] = (uint8_t)readAddr;
			if (HAL_I2C_Master_Transmit(dev->i2c, AT24CXX_ADDR, buf, 2 ,10) != 0)
			{
				return AT_ERROR;
			}					
		}
		else
		{
			buf[0] = readAddr;
			if (HAL_I2C_Master_Transmit(dev->i2c, AT24CXX_ADDR|(readAddr>>7), buf, 1,10) != 0)
			{
				return AT_ERROR;
			}
		}
//#if	(EE_TYPE > AT24C16)  
//    buf[0] = (uint8_t)(readAddr>>8);	
//    buf[1] = (uint8_t)readAddr;
//    if (HAL_I2C_Master_Transmit(dev->i2c, AT24CXX_ADDR, buf, 2 ,10) != 0) 
//#else
//    buf[0] = readAddr;
//    if (HAL_I2C_Master_Transmit(dev->i2c, AT24CXX_ADDR|(readAddr>>7), buf, 1,10) != 0)
//#endif        
//    {
//        return AT_ERROR;
//    }
    read_regs(dev, 1, &temp);
    return temp;
}

/** 函数名:at24cxx_write_one_byte
  * 功能	:
  * 输入	:
	* 输出	:
	* 编写人:XMW
  */
uint8_t at24cxx_write_one_byte(at24cxx_device_t dev, uint16_t writeAddr, uint8_t dataToWrite)
{
    uint8_t buf[3];
		if(dev->DevType.eeType > AT24C16)
		{
			buf[0] = (uint8_t)(writeAddr>>8);	
			buf[1] = (uint8_t)writeAddr;
			buf[2] = dataToWrite;
			if (HAL_I2C_Master_Transmit(dev->i2c, AT24CXX_ADDR, buf, 3,10) == 0)  
			{
				return AT_EOK;
			}					
		}
		else
		{
			buf[0] = writeAddr; //cmd
			buf[1] = dataToWrite;
			if (HAL_I2C_Master_Transmit(dev->i2c, AT24CXX_ADDR|(writeAddr>>7), buf, 2 , 10)  == 0)
			{
				return AT_EOK;
			}
		}
		return AT_ERROR;
//#if	(EE_TYPE > AT24C16)      
//    buf[0] = (uint8_t)(writeAddr>>8);	
//    buf[1] = (uint8_t)writeAddr;
//    buf[2] = dataToWrite;
//    if (HAL_I2C_Master_Transmit(dev->i2c, AT24CXX_ADDR, buf, 3,10) == 0)    
//#else    
//    buf[0] = writeAddr; //cmd
//    buf[1] = dataToWrite;
//    if (HAL_I2C_Master_Transmit(dev->i2c, AT24CXX_ADDR|(writeAddr>>7), buf, 2 , 10)  == 0)
//#endif        
//        return AT_EOK;
//    else
//        return AT_ERROR;
}

/** 函数名:at24cxx_read_page
  * 功能	:
  * 输入	:
	* 输出	:
	* 编写人:XMW
  */
uint8_t at24cxx_read_page(at24cxx_device_t dev, uint32_t readAddr, uint8_t *pBuffer, uint16_t numToRead)
{
	HAL_StatusTypeDef status;
	
	if (HAL_I2C_IsDeviceReady(dev->i2c, dev->AddrInput, 2, 0x1000) != HAL_OK)
  {
		HAL_I2C_DeInit(dev->i2c);
		HAL_I2C_Init(dev->i2c);
  }
	if(dev->DevType.eeType > AT24C16)
	{
		status = HAL_I2C_Mem_Read(dev->i2c,dev->AddrInput,readAddr,I2C_MEMADD_SIZE_16BIT,pBuffer,numToRead,20);
	}
	else
	{
		status = HAL_I2C_Mem_Read(dev->i2c,dev->AddrInput|(readAddr>>7),readAddr,I2C_MEMADD_SIZE_8BIT,pBuffer,numToRead,20);
	}
//#if	(EE_TYPE > AT24C16) 
//		status = HAL_I2C_Mem_Read(dev->i2c,dev->AddrInput,readAddr,I2C_MEMADD_SIZE_16BIT,pBuffer,numToRead,20);
//#else
//    status = HAL_I2C_Mem_Read(dev->i2c,dev->AddrInput|(readAddr>>7),readAddr,I2C_MEMADD_SIZE_8BIT,pBuffer,numToRead,20);
//#endif
	if(status == HAL_OK)	
	{
		return AT_EOK;
	}
	else
	{
		HAL_I2C_DeInit(dev->i2c);
		HAL_I2C_Init(dev->i2c);	
		if(dev->DevType.eeType > AT24C16)
		{
			status = HAL_I2C_Mem_Read(dev->i2c,dev->AddrInput,readAddr,I2C_MEMADD_SIZE_16BIT,pBuffer,numToRead,20);
		}
		else
		{
			status = HAL_I2C_Mem_Read(dev->i2c,dev->AddrInput|(readAddr>>7),readAddr,I2C_MEMADD_SIZE_8BIT,pBuffer,numToRead,20);
		}
//		#if	(EE_TYPE > AT24C16) 
//		status = HAL_I2C_Mem_Read(dev->i2c,dev->AddrInput,readAddr,I2C_MEMADD_SIZE_16BIT,pBuffer,numToRead,20);
//		#else
//    status = HAL_I2C_Mem_Read(dev->i2c,dev->AddrInput|(readAddr>>7),readAddr,I2C_MEMADD_SIZE_8BIT,pBuffer,numToRead,20);
//		#endif		
		return AT_ERROR;
	}
	
//	while (HAL_I2C_IsDeviceReady(dev->i2c, dev->AddrInput, 2, 0x1000) != HAL_OK){};
}

uint8_t at24cxx_write_page(at24cxx_device_t dev, uint32_t wirteAddr, uint8_t *pBuffer, uint16_t numToWrite)
{
		HAL_StatusTypeDef status;
	if (HAL_I2C_IsDeviceReady(dev->i2c, dev->AddrInput, 2, 0x1000) != HAL_OK)
  {
		HAL_I2C_DeInit(dev->i2c);
		HAL_I2C_Init(dev->i2c);
  }
	if(dev->DevType.eeType > AT24C16)
	{
		status = HAL_I2C_Mem_Write(dev->i2c,dev->AddrInput,wirteAddr,I2C_MEMADD_SIZE_16BIT,pBuffer,numToWrite,20);
	}
	else
	{
		status = HAL_I2C_Mem_Write(dev->i2c,dev->AddrInput|(wirteAddr>>7),wirteAddr,I2C_MEMADD_SIZE_8BIT,pBuffer,numToWrite,20);
	}
//#if	(EE_TYPE > AT24C16) 
//		status = HAL_I2C_Mem_Write(dev->i2c,dev->AddrInput,wirteAddr,I2C_MEMADD_SIZE_16BIT,pBuffer,numToWrite,20);
//#else
//    status = HAL_I2C_Mem_Write(dev->i2c,dev->AddrInput|(wirteAddr>>7),wirteAddr,I2C_MEMADD_SIZE_8BIT,pBuffer,numToWrite,20);
//#endif    
		if(status != HAL_OK)  
		{
			HAL_I2C_DeInit(dev->i2c);
			HAL_I2C_Init(dev->i2c);
			if(dev->DevType.eeType > AT24C16)
			{
				status = HAL_I2C_Mem_Write(dev->i2c,dev->AddrInput,wirteAddr,I2C_MEMADD_SIZE_16BIT,pBuffer,numToWrite,20);
			}
			else
			{
				status = HAL_I2C_Mem_Write(dev->i2c,dev->AddrInput|(wirteAddr>>7),wirteAddr,I2C_MEMADD_SIZE_8BIT,pBuffer,numToWrite,20);
			}
//			#if	(EE_TYPE > AT24C16) 
//			status = HAL_I2C_Mem_Write(dev->i2c,dev->AddrInput,wirteAddr,I2C_MEMADD_SIZE_16BIT,pBuffer,numToWrite,20);
//			#else
//			status = HAL_I2C_Mem_Write(dev->i2c,dev->AddrInput|(wirteAddr>>7),wirteAddr,I2C_MEMADD_SIZE_8BIT,pBuffer,numToWrite,20);
//			#endif
			return AT_ERROR;	
		}
		else 
		{
			return AT_EOK;
		}
//		while (HAL_I2C_IsDeviceReady(dev->i2c, dev->AddrInput, 2, 0x1000) != HAL_OK){};
}

static uint8_t at24cxx_check_page(at24cxx_device_t dev, uint32_t maxAdress)
{
//	for(uint32_t i=8;i>0;i--)
//	{
//		if(at24cxx_check_device(dev, uint32_t maxAdress))
//	
//	}
}


static uint8_t at24cxx_check_device(at24cxx_device_t dev, uint32_t maxAdress)
{
    volatile uint8_t temp = 0x0 ,old_data, oldtemp;
		if(dev == NULL)  
			return AT_ERROR;
		rt_hw_ms_delay(EE_TWR);
		for(uint8_t i=1;i<=8;i++)
		{
			old_data = at24cxx_read_one_byte(dev, maxAdress - i);
			rt_hw_ms_delay(EE_TWR);
			oldtemp = i;
			at24cxx_write_one_byte(dev, maxAdress - i, oldtemp);
			rt_hw_ms_delay(EE_TWR);
			temp = at24cxx_read_one_byte(dev, maxAdress - i);
			rt_hw_ms_delay(EE_TWR);
			at24cxx_write_one_byte(dev, maxAdress - i, old_data);
			if (temp != oldtemp) 
			{
				return AT_ERROR;	
			}
			rt_hw_ms_delay(EE_TWR);
		}
    return AT_EOK;
}


uint32_t at24cxx_check_poll(at24cxx_device_t dev)
{
	uint32_t addrMax = 0;
	int8_t eeTypeId = AT24CTYPE;
#ifdef EEPROM_AUTO_CHECK
	for(int8_t i=AT24CTYPE-1;i>=0;i--)
	{
		addrMax = pow(2,i)*128;
		dev->DevType.eeType = i;
		if(at24cxx_check_device(dev, addrMax)==AT_EOK)
		{
			eeTypeId = i;
			break;
		}
	}
#endif	
	if(eeTypeId >= AT24CTYPE)
	{
		dev->DevType.eeType = EE_TYPE;
		dev->DevType.memSize = AT24CXX_MAX_MEM_ADDRESS;
		dev->DevType.pageSize = AT24CXX_PAGE_BYTE;
	}
	else
	{
		dev->DevType.memSize = addrMax;
		if(dev->DevType.eeType <= AT24C02)
			dev->DevType.pageSize = 8;
		else if(dev->DevType.eeType <= AT24C16)
			dev->DevType.pageSize = 16;
		else if(dev->DevType.eeType <= AT24C64)
			dev->DevType.pageSize = 32;
		else if(dev->DevType.eeType <= AT24C256)
			dev->DevType.pageSize = 64;
		else
			dev->DevType.pageSize = 128;
	}
	lwlog_debug("at24cxx:%s, %d,%d.",EE_Type_Str[eeTypeId],dev->DevType.pageSize, dev->DevType.memSize);
//	dev->eeType = EE_TYPE;
}

uint8_t at24cxx_check(at24cxx_device_t dev)
{
    volatile uint8_t temp = 0x0 ,old_data;
		if(dev == NULL)  
			return AT_ERROR;
		rt_hw_ms_delay(EE_TWR);
		
		at24cxx_check_poll(dev);
		rt_hw_ms_delay(EE_TWR);
    old_data = at24cxx_read_one_byte(dev, dev->DevType.memSize - 1);
		rt_hw_ms_delay(EE_TWR);
		at24cxx_write_one_byte(dev, dev->DevType.memSize - 1, 0x55);
		rt_hw_ms_delay(EE_TWR);
		temp = at24cxx_read_one_byte(dev, dev->DevType.memSize - 1);
		if (temp == 0x55) 
		{
			at24cxx_write_one_byte(dev, dev->DevType.memSize - 1, old_data);
			rt_hw_ms_delay(EE_TWR);
			return AT_EOK;	
		}
    return AT_ERROR;
}


/**
 * This function read the specific numbers of data to the specific position
 *
 * @param bus the name of at24cxx device
 * @param ReadAddr the start position to read
 * @param pBuffer  the read data store position
 * @param NumToRead
 * @return AT_EOK  write ok.
 */
uint8_t at24cxx_read(at24cxx_device_t dev, uint32_t ReadAddr, uint8_t *pBuffer, uint16_t NumToRead)
{
    uint8_t result = AT_EOK;
		if(dev == NULL)  
			result = AT_ERROR;
	
    if(ReadAddr + NumToRead > AT24CXX_MAX_MEM_ADDRESS)
    {
        result = AT_ERROR;
    }
    osMutexAcquire(dev->lock,osWaitForever);

    if (result == AT_EOK)
    {
        while (NumToRead)
        {
            *pBuffer++ = at24cxx_read_one_byte(dev, ReadAddr++);
            NumToRead--;
        }
    }
    else
    {
        LOG_E("The at24cxx could not respond  at this time. Please try again");
    }
		osMutexRelease(dev->lock);

    return result;
}

/**
 * This function read the specific numbers of data to the specific position
 *
 * @param bus the name of at24cxx device
 * @param ReadAddr the start position to read
 * @param pBuffer  the read data store position
 * @param NumToRead 
 * @return AT_EOK  write ok.
 */
uint8_t at24cxx_page_read(at24cxx_device_t dev, uint32_t ReadAddr, uint8_t *pBuffer, uint16_t NumToRead)
{
    uint8_t result = AT_EOK;
    uint16_t pageReadSize = dev->DevType.pageSize - ReadAddr % dev->DevType.pageSize;
	  
    if(ReadAddr + NumToRead > dev->DevType.memSize)
    {
        return AT_ERROR;
    }
		osMutexAcquire(dev->lock,osWaitForever);
    if(result == AT_EOK)
    {
        while (NumToRead)
        {
            if(NumToRead > pageReadSize)
            {
                if(at24cxx_read_page(dev, ReadAddr, pBuffer, pageReadSize))
                {
                    result = AT_ERROR;
                }
//								rt_hw_ms_delay(EE_TWR);
                ReadAddr += pageReadSize;
                pBuffer += pageReadSize;
                NumToRead -= pageReadSize;
                pageReadSize = dev->DevType.pageSize;
            }
            else
            {
                if(at24cxx_read_page(dev, ReadAddr, pBuffer, NumToRead))
                {
                    result = AT_ERROR;
                }
//								rt_hw_ms_delay(EE_TWR);
                NumToRead = 0;
            }
        }
    }
    else
    {
        LOG_E("The at24cxx could not respond  at this time. Please try again");
    }
		osMutexRelease(dev->lock);
    return result;
}

/**
 * This function write the specific numbers of data to the specific position
 *
 * @param bus the name of at24cxx device
 * @param WriteAddr the start position to write
 * @param pBuffer  the data need to write
 * @param NumToWrite
 * @return AT_EOK  write ok.at24cxx_device_t dev
 */
uint8_t at24cxx_write(at24cxx_device_t dev, uint32_t WriteAddr, uint8_t *pBuffer, uint16_t NumToWrite)
{
    uint16_t i = 0;
    uint8_t result= AT_EOK;
    if(dev == NULL)  
			result= AT_ERROR;
    if(WriteAddr + NumToWrite > AT24CXX_MAX_MEM_ADDRESS)
    {
        result= AT_ERROR;
    }
    osMutexAcquire(dev->lock,osWaitForever);
    if (result == AT_EOK)
    {
        while (1) //NumToWrite--
        {
            if (at24cxx_write_one_byte(dev, WriteAddr, pBuffer[i]) != AT_EOK)
            {
                rt_hw_ms_delay(EE_TWR);
            }
            else
            {
                WriteAddr++;
                i++;
            }
            if (i == NumToWrite)
            {
                break;
            }

        }
    }
    else
    {
        LOG_E("The at24cxx could not respond  at this time. Please try again");
    }
		osMutexRelease(dev->lock);

    return result;
}

/**
 * This function write the specific numbers of data to the specific position
 *
 * @param bus the name of at24cxx device
 * @param WriteAddr the start position to write
 * @param pBuffer  the data need to write
 * @param NumToWrite
 * @return AT_EOK  write ok.at24cxx_device_t dev
 */
uint8_t at24cxx_page_write(at24cxx_device_t dev, uint32_t WriteAddr, uint8_t *pBuffer, uint16_t NumToWrite)
{
    uint8_t result = AT_EOK;
    uint16_t pageWriteSize = dev->DevType.pageSize - WriteAddr % dev->DevType.pageSize;
    if(WriteAddr + NumToWrite > dev->DevType.memSize)
    {
        return AT_ERROR;
    }
		osMutexAcquire(dev->lock,osWaitForever);
    if(result == AT_EOK)
    {
        while (NumToWrite)
        {
            if(NumToWrite > pageWriteSize)
            {
                if(at24cxx_write_page(dev, WriteAddr, pBuffer, pageWriteSize))
                {
                    result = AT_ERROR;
                }
                rt_hw_ms_delay(EE_TWR);    // wait 5ms befor next operation

                WriteAddr += pageWriteSize;
                pBuffer += pageWriteSize;
                NumToWrite -= pageWriteSize;
                pageWriteSize = dev->DevType.pageSize;
            }
            else
            {
                if(at24cxx_write_page(dev, WriteAddr, pBuffer, NumToWrite))
                {
                    result = AT_ERROR;
                }
                rt_hw_ms_delay(EE_TWR);   // wait 5ms befor next operation

                NumToWrite = 0;
            }
        }
    }
    else
    {
        LOG_E("The at24cxx could not respond  at this time. Please try again");
    }
		osMutexRelease(dev->lock);
    return result;
}

uint8_t pageErase[128];
/**
 * This function write the specific numbers of data to the specific position
 *
 * @param bus the name of at24cxx device
 * @param WriteAddr the start position to write
 * @param pBuffer  the data need to write
 * @param NumToWrite
 * @return AT_EOK  write ok.at24cxx_device_t dev
 */
uint8_t at24cxx_page_erase(at24cxx_device_t dev, uint32_t WriteAddr, uint16_t NumToWrite)
{
    uint8_t result = AT_EOK;
    uint16_t pageWriteSize = AT24CXX_PAGE_BYTE - WriteAddr % AT24CXX_PAGE_BYTE;
    if(WriteAddr + NumToWrite > AT24CXX_MAX_MEM_ADDRESS)
    {
        return AT_ERROR;
    }
		osMutexAcquire(dev->lock,osWaitForever);
    if(result == AT_EOK)
    {
        while (NumToWrite)
        {
            if(NumToWrite > pageWriteSize)
            {
                if(at24cxx_write_page(dev, WriteAddr, pageErase, pageWriteSize))
                {
                    result = AT_ERROR;
                }
                rt_hw_ms_delay(EE_TWR);    // wait 5ms befor next operation

                WriteAddr += pageWriteSize;
//                pBuffer += pageWriteSize;
                NumToWrite -= pageWriteSize;
                pageWriteSize = AT24CXX_PAGE_BYTE;
            }
            else
            {
                if(at24cxx_write_page(dev, WriteAddr, pageErase, NumToWrite))
                {
                    result = AT_ERROR;
                }
                rt_hw_ms_delay(EE_TWR);   // wait 5ms befor next operation

                NumToWrite = 0;
            }
        }
    }
    else
    {
        LOG_E("The at24cxx could not respond  at this time. Please try again");
    }
		osMutexRelease(dev->lock);
    return result;
}

/**
 * This function initializes at24cxx registered device driver
 *
 * @param dev the name of at24cxx device
 *
 * @return the at24cxx device.
 */
static struct at24cxx_device atxdevice;
at24cxx_device_t at24cxx_init(I2C_HandleTypeDef *hi2c, uint8_t AddrInput)
{
	at24cxx_device_t dev;
	dev = &atxdevice;
	dev->i2c = hi2c;
	dev->lock = osMutexNew(NULL);
	dev->AddrInput = AT24CXX_ADDR;
	dev->DevType.eeType = EE_TYPE;
	if (at24cxx_check(dev) != AT_EOK)
	{
		if(dev->lock != NULL)
			osMutexDelete(dev->lock);
		dev = NULL;
	}
  return dev;
}

/**
 * This function releases memory and deletes mutex lock
 *
 * @param dev the pointer of device driver structure
 */
void at24cxx_deinit(at24cxx_device_t dev)
{
	if(dev->lock != NULL)
			osMutexDelete(dev->lock);
	dev = NULL;
}

#endif
/*
 * Copyright (c) 2006-2018, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2019-04-13     XiaojieFan   the first version
 * 2019-12-04     RenMing      Use PAGE WRITE instead of BYTE WRITE and input address can be selected 
 */

#ifndef __AT24CXX_H__
#define __AT24CXX_H__

#include "main.h"

#define AT24C01     0
#define AT24C02     1
#define AT24C04     2
#define AT24C08     3
#define AT24C16     4
#define AT24C32     5
#define AT24C64     6
#define AT24C128    7
#define AT24C256    8
#define AT24C512    9
#define AT24CTYPE   10   // Number of supported types

#define EE_TWR      5

#ifndef EE_TYPE
#define EE_TYPE     AT24C128
#endif


typedef enum
{
	AT_EOK = 1,
	AT_ERROR = 2
}at24cxx_s;

typedef struct
{
	uint8_t eeType;
	uint8_t pageSize;
	uint32_t memSize;
}at24cxxType_t;

struct at24cxx_device
{
    I2C_HandleTypeDef *i2c;
    osMutexId_t lock;
    uint8_t AddrInput;
		at24cxxType_t DevType;
};
typedef struct at24cxx_device *at24cxx_device_t;

void at24cxx_deinit(at24cxx_device_t dev);
at24cxx_device_t at24cxx_init(I2C_HandleTypeDef *hi2c, uint8_t AddrInput);
uint8_t at24cxx_read(at24cxx_device_t dev, uint32_t ReadAddr, uint8_t *pBuffer, uint16_t NumToRead);
uint8_t at24cxx_write(at24cxx_device_t dev, uint32_t WriteAddr, uint8_t *pBuffer, uint16_t NumToWrite);
uint8_t at24cxx_page_read(at24cxx_device_t dev, uint32_t ReadAddr, uint8_t *pBuffer, uint16_t NumToRead);
uint8_t at24cxx_page_write(at24cxx_device_t dev, uint32_t WriteAddr, uint8_t *pBuffer, uint16_t NumToWrite);
uint8_t at24cxx_page_erase(at24cxx_device_t dev, uint32_t WriteAddr, uint16_t NumToWrite);
#endif

一沙一世界,一花一天堂。君掌盛无边,刹那成永恒。