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