/**
* @file AT24CXX_ATY.c
*
* @param Project DEVICE_GENERAL_ATY_LIB
*
* @author ATY
*
* @copyright
* - Copyright 2017 - 2026 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 functions of AT24CXX for C platform
*
* @version
* - 1_01_220602 > ATY
* -# Preliminary version, first Release
* - 1_01_221212 > ATY
* -# Change to general I2C function
* -# Change and remove several functions
* - 1_02_231229 > ATY
* -# add multy addr and channel
********************************************************************************
*/
#ifndef __AT24CXX_ATY_C
#define __AT24CXX_ATY_C
#include "AT24CXX_ATY.h"
/******************************* For user *************************************/
/******************************************************************************/
/**
* @brief Read one byte from assign address
* @param regAddr address to read data
* @param addr chip address
* @param channel chip channel
* @return uint8 data at regAddr
*/
uint8_t AT24CXX_ReadByte(uint16_t regAddr, uint8_t addr, uint8_t channel)
{
uint8_t temp_uint8 = 0, addrG[2] = {regAddr >> 8, regAddr % 256};
if(AT24CXX_TYPE > AT24C16)
I2C_Write_NoStop(addr, addrG, 2, channel);
else // 04/08/16
I2C_Write_NoStop(addr + ((regAddr / 256) << 1), addrG + 1, 1, channel);
I2C_Read(addr, &temp_uint8, 1, channel);
return temp_uint8;
}
/**
* @brief Write one byte to assign address
* @param regAddr address to write data
* @param data_t data to write
* @param addr chip address
* @param channel chip channel
*/
void AT24CXX_WriteByte(uint16_t regAddr, uint8_t data_t, uint8_t addr, uint8_t channel)
{
uint8_t addrG[3] = {regAddr >> 8, regAddr % 256, data_t};
if(AT24CXX_TYPE > AT24C16)
I2C_Write(addr, addrG, 3, channel);
else // 04/08/16
I2C_Write(addr + ((regAddr / 256) << 1), addrG + 1, 2, channel);
DelayMs(AT24CXX_WRITE_DELAY);
}
/**
* @brief Read series data from assign address
* @param regAddr address to start read data
* @param pbuf data group to save read data
* @param len data length to read
* @param addr chip address
* @param channel chip channel
*/
void AT24CXX_Read(uint16_t regAddr, uint8_t* pbuf, uint16_t len, uint8_t addr, uint8_t channel)
{
uint8_t addrG[2] = {regAddr >> 8, regAddr % 256};
if(AT24CXX_TYPE > AT24C16)
I2C_Write_NoStop(addr, addrG, 2, channel);
else // 04/08/16
I2C_Write_NoStop(addr + ((regAddr / 256) << 1), addrG + 1, 1, channel);
I2C_Read(addr, pbuf, len, channel);
}
/**
* @brief Write series data to assign address
* @param regAddr address to start read data
* @param pbuf data group to write
* @param len data length to write
* @param addr chip address
* @param channel chip channel
*/
void AT24CXX_Write(uint16_t regAddr, uint8_t* pbuf, uint16_t len, uint8_t addr, uint8_t channel)
{
uint8_t* addrG = (uint8_t*)malloc(sizeof(uint8_t) * (len + 2));
addrG[0] = regAddr >> 8;
addrG[1] = regAddr % 256;
for(uint16_t i = 0; i < len; i++)
addrG[2 + i] = pbuf[i];
if(AT24CXX_TYPE > AT24C16)
I2C_Write(addr, addrG, len + 2, channel);
else // 04/08/16
I2C_Write(addr + ((regAddr / 256) << 1), addrG + 1, len + 1, channel);
free(addrG);
DelayMs(AT24CXX_WRITE_DELAY);
}
/**
* @brief Write random data to assign address
* @param regAddr address to start read data
* @param pbuf data group to save read data
* @param len data length to write
* @param addr chip address
* @param channel chip channel
*/
void AT24CXX_WriteRandom(uint16_t regAddr, uint8_t* pbuf, uint16_t len, uint8_t addr, uint8_t channel)
{
uint16_t fullPageCount = 0; // whole page count
uint16_t lastPageSize = 0;
uint16_t firstPageSize = 0;
if(regAddr + len > AT24CXX_TYPE)
len = AT24CXX_TYPE - regAddr;
if(regAddr % AT24CXX_PAGE_SIZE == 0) // regAddr is the page start
firstPageSize = 0;
else
{
firstPageSize = AT24CXX_PAGE_SIZE - (regAddr % AT24CXX_PAGE_SIZE);
AT24CXX_Write(regAddr, pbuf, firstPageSize, addr, channel);
}
if((regAddr + len) % AT24CXX_PAGE_SIZE == 0) // location regAddr will be wrote too
lastPageSize = 0;
else
{
lastPageSize = (regAddr + len) % AT24CXX_PAGE_SIZE;
AT24CXX_Write(regAddr + len - lastPageSize, pbuf + len - lastPageSize, lastPageSize, addr, channel);
}
fullPageCount = (len - firstPageSize - lastPageSize) / AT24CXX_PAGE_SIZE;
for(uint8_t i = 0; i < fullPageCount; i++)
AT24CXX_Write(regAddr + firstPageSize + i * AT24CXX_PAGE_SIZE,
pbuf + firstPageSize + i * AT24CXX_PAGE_SIZE, AT24CXX_PAGE_SIZE, addr, channel);
DelayMs(AT24CXX_WRITE_DELAY);
}
/**
* @brief Check device state
* @param addr chip address
* @param channel chip channel
* @return errCode, 0: device good, !0: device has problem
*/
uint8_t AT24CXX_Check(uint8_t addr, uint8_t channel)
{
uint8_t temp_uint8;
// avoid writing every boot up
temp_uint8 = AT24CXX_ReadByte(0xFF, addr, channel);
if(temp_uint8 == 0X68)
return 0;
else
{
// may be the first init
AT24CXX_WriteByte(0xFF, 0x68, addr, channel);
temp_uint8 = AT24CXX_ReadByte(0xFF, addr, channel);
if(temp_uint8 == 0x68)
return 0;
}
return 1;
}
/**
* @brief Init device
* @param addr chip address
* @param channel chip channel
* @note not useful if i2c functions good
*/
void AT24CXX_Init(uint8_t addr, uint8_t channel)
{
}
#ifdef __DEBUG_AT24CXX_ATY
/**
* @brief Test funtion(can be instead by Check function)
* @param addr chip address
* @param channel chip channel
* @return errCode, 0: success, !0: err
*/
uint8_t AT24CXX_Test(uint8_t addr, uint8_t channel)
{
// AT24CXX_Init(addr, channel);
// W/R one byte
uint8_t startupCounte = 0;
startupCounte = AT24CXX_ReadByte(0xFF, addr, channel);
AT24CXX_WriteByte(0xFF, startupCounte + 1, addr, channel);
AT24CXX_ReadByte(0xFF, addr, channel);
// 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, addr, channel);
AT24CXX_Read(0xFA, tempTestR_uint8, 0x100 - 0xFA, addr, channel);
AT24CXX_Write(0xFA, tempTestW_uint8, 0xFF - 0xFA, addr, channel);
AT24CXX_Read(0xFA, tempTestR_uint8, 0x100 - 0xFA, addr, channel);
// W/R random
uint8_t tempBuf[50];
const char* str = "abcdefghijklmnopqrstuvwxyz0123456789";
AT24CXX_WriteRandom(100, (uint8_t*)str, strlen(str), addr, channel);
AT24CXX_Read(100, tempBuf, strlen(str), addr, channel);
printf("\r\nAT24CXX read data from regAddr %d at num %d: %s\r\n",
100, startupCounte, (char*)tempBuf);
if(memcmp(str, tempBuf, strlen(str)) == 0)
return 0;
return 1;
}
// AT24CXX_Test(AT24CXX_ADDRESS, AT4CXX_I2C);
#endif /* __DEBUG_AT24CXX_ATY */
#endif /* __AT24CXX_ATY_C */
/******************************** End Of File *********************************/