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