/**
* @file AT24CXX_ATY.c
*
* @param Project DEVICE_GENERAL_ATY_LIB
*
* @author ATY
*
* @copyright
* - Copyright 2017 - 2023 MZ-ATY
* - This code follows:
* - MZ-ATY Various Contents Joint Statement -
*
* https://mengze.top/MZ-ATY_VCJS
* - CC 4.0 BY-NC-SA -
*
* https://creativecommons.org/licenses/by-nc-sa/4.0/
* - Your use will be deemed to have accepted the terms of this statement.
*
* @brief Familiar functions of AT24CXX for all embedded device
*
* @version
* - 1_01_220602 > ATY
* -# Preliminary version, first Release
* - 1_01_221212 > ATY
* -# Change to general I2C function
* -# Change and remove several functions
********************************************************************************
*/
#ifndef __AT24CXX_ATY_C
#define __AT24CXX_ATY_C
#include "AT24CXX_ATY.h"
/******************************* For user *************************************/
/******************************************************************************/
/**
* @brief Read one byte from assign address
* @param addr address to read data
* @return uint8 data at addr
*/
uint8_t AT24CXX_ReadByte(uint16_t addr)
{
uint8_t temp_uint8 = 0, addrG[2] = {addr >> 8, addr % 256};
if(AT24CXX_TYPE > AT24C16)
I2C_Write_NoStop(AT24CXX_ADDRESS, addrG, 2);
else // 04/08/16
I2C_Write_NoStop(AT24CXX_ADDRESS + ((addr / 256) << 1), addrG + 1, 1);
I2C_Read(AT24CXX_ADDRESS, &temp_uint8, 1);
return temp_uint8;
}
/**
* @brief Write one byte to assign address
* @param addr address to write data
* @param data_t data to write
*/
void AT24CXX_WriteByte(uint16_t addr, uint8_t data_t)
{
uint8_t addrG[3] = {addr >> 8, addr % 256, data_t};
if(AT24CXX_TYPE > AT24C16)
I2C_Write(AT24CXX_ADDRESS, addrG, 3);
else // 04/08/16
I2C_Write(AT24CXX_ADDRESS + ((addr / 256) << 1), addrG + 1, 2);
DelayMs(AT24CXX_WRITE_DELAY);
}
/**
* @brief Read series data from assign address
* @param addr address to start read data
* @param pbuf data group to save read data
* @param len data length to read
*/
void AT24CXX_Read(uint16_t addr, uint8_t* pbuf, uint16_t len)
{
uint8_t addrG[2] = {addr >> 8, addr % 256};
if(AT24CXX_TYPE > AT24C16)
I2C_Write_NoStop(AT24CXX_ADDRESS, addrG, 2);
else // 04/08/16
I2C_Write_NoStop(AT24CXX_ADDRESS + ((addr / 256) << 1), addrG + 1, 1);
I2C_Read(AT24CXX_ADDRESS, pbuf, len);
}
/**
* @brief Write series data to assign address
* @param addr address to start read data
* @param pbuf data group to write
* @param len data length to write
*/
void AT24CXX_Write(uint16_t addr, uint8_t* pbuf, uint16_t len)
{
uint8_t* addrG = (uint8_t*)malloc(sizeof(uint8_t) * (len + 2));
addrG[0] = addr >> 8;
addrG[1] = addr % 256;
for(uint16_t i = 0; i < len; i++)
addrG[2 + i] = pbuf[i];
if(AT24CXX_TYPE > AT24C16)
I2C_Write(AT24CXX_ADDRESS, addrG, len + 2);
else // 04/08/16
I2C_Write(AT24CXX_ADDRESS + ((addr / 256) << 1), addrG + 1, len + 1);
free(addrG);
DelayMs(AT24CXX_WRITE_DELAY);
}
/**
* @brief Write random data to assign address
* @param addr address to start read data
* @param pbuf data group to save read data
* @param len data length to write
*/
void AT24CXX_WriteRandom(uint16_t addr, uint8_t* pbuf, uint16_t len)
{
uint16_t fullPageCount = 0; // whole page count
uint16_t lastPageSize = 0;
uint16_t firstPageSize = 0;
if(addr + len > AT24CXX_TYPE)
len = AT24CXX_TYPE - addr;
if(addr % AT24CXX_PAGE_SIZE == 0) // addr is the page start
firstPageSize = 0;
else
{
firstPageSize = AT24CXX_PAGE_SIZE - (addr % AT24CXX_PAGE_SIZE);
AT24CXX_Write(addr, pbuf, firstPageSize);
}
if((addr + len) % AT24CXX_PAGE_SIZE == 0) // location addr will be wrote too
lastPageSize = 0;
else
{
lastPageSize = (addr + len) % AT24CXX_PAGE_SIZE;
AT24CXX_Write(addr + len - lastPageSize, pbuf + len - lastPageSize, lastPageSize);
}
fullPageCount = (len - firstPageSize - lastPageSize) / AT24CXX_PAGE_SIZE;
for(uint8_t i = 0; i < fullPageCount; i++)
AT24CXX_Write(addr + firstPageSize + i * AT24CXX_PAGE_SIZE,
pbuf + firstPageSize + i * AT24CXX_PAGE_SIZE, AT24CXX_PAGE_SIZE);
DelayMs(AT24CXX_WRITE_DELAY);
}
/**
* @brief Check device state
* @return errCode, 0: device good, !0: device has problem
*/
uint8_t AT24CXX_Check(void)
{
uint8_t temp_uint8;
// avoid writing every boot up
temp_uint8 = AT24CXX_ReadByte(0xFF);
if(temp_uint8 == 0X68)
return 0;
else
{
// may be the first init
AT24CXX_WriteByte(0xFF, 0x68);
temp_uint8 = AT24CXX_ReadByte(0xFF);
if(temp_uint8 == 0x68)
return 0;
}
return 1;
}
/**
* @brief Init device
* @note not useful if i2c functions good
*/
void AT24CXX_Init(void)
{
}
#ifdef __DEBUG_AT24CXX_ATY
/**
* @brief Test funtion(can be instead by Check function)
* @return errCode, 0: success, !0: err
*/
uint8_t AT24CXX_Test(void)
{
// AT24CXX_Init();
// W/R one byte
uint8_t startupCounte = 0;
startupCounte = AT24CXX_ReadByte(0xFF);
AT24CXX_WriteByte(0xFF, startupCounte + 1);
AT24CXX_ReadByte(0xFF);
// W/R bytes
uint8_t tempTestR_uint8[6] = {0, 0, 0, 0, 0, 0};
uint8_t tempTestW_uint8[5] = {1, 2, 3, 4, 5};
AT24CXX_Write(0xFA, tempTestR_uint8, 0xFF - 0xFA);
AT24CXX_Read(0xFA, tempTestR_uint8, 0x100 - 0xFA);
AT24CXX_Write(0xFA, tempTestW_uint8, 0xFF - 0xFA);
AT24CXX_Read(0xFA, tempTestR_uint8, 0x100 - 0xFA);
// W/R random
uint8_t tempBuf[50];
const char* str = "abcdefghijklmnopqrstuvwxyz0123456789";
AT24CXX_WriteRandom(100, (uint8_t*)str, strlen(str));
AT24CXX_Read(100, tempBuf, strlen(str));
printf("\r\nAT24CXX read data from addr %d at num %d: %s\r\n",
100, startupCounte, (char*)tempBuf);
if(memcmp(str, tempBuf, strlen(str)) == 0)
return 0;
return 1;
}
#endif /* __DEBUG_AT24CXX_ATY */
#endif /* __AT24CXX_ATY_C */
/******************************** End Of File *********************************/