/* * @Author: mypx * @Email: mypx_coder@163.com * @Date: 2025-06-19 15:35:35 * @LastEditors: mypx mypx_coder@163.com * @Description: */ #include #include #include "at24cx.h" // Log tag static const char *TAG = "at24c"; // Debug macro for logging messages #define AT24_DBG(fmt, ...) \ if (device && device->log) \ { \ device->log(TAG, fmt, ##__VA_ARGS__); \ } // Define the chip information table static const at24cx_chip_info_t chip_info_table[] = { {0x0000, 0x007F, 8}, // AT24C01 {0x0000, 0x00FF, 8}, // AT24C02 {0x0000, 0x01FF, 9}, // AT24C04 {0x0000, 0x03FF, 10}, // AT24C08 {0x0000, 0x3FFF, 16} // AT24C128 }; // Check if the address is within the valid range static int check_address_range(at24cx_dev_t *device, uint16_t addr, uint16_t num) { const at24cx_chip_info_t *info = &chip_info_table[device->chip_model]; if (addr < info->min_addr || addr + num - 1 > info->max_addr) { AT24_DBG("Address out of range: min = %04X, max = %04X, requested = %04X - %04X", info->min_addr, info->max_addr, addr, addr + num - 1); return -1; } return 0; } // Write a single byte to the specified address int at24cx_write_byte(at24cx_dev_t *device, uint16_t addr, uint8_t data) { if (check_address_range(device, addr, 1) != 0) { return -1; } if (device != NULL && device->write_bytes) { return device->write_bytes((uint16_t)device->dev_addr, addr, &data, 1); } return -1; } // Write multiple bytes to the device, supporting cross-page writing int at24cx_write(at24cx_dev_t *device, uint16_t start_addr, uint8_t *data_buf, uint16_t write_num) { if (check_address_range(device, start_addr, write_num) != 0) { return -1; } uint16_t bytes_written = 0; uint16_t current_addr = start_addr; uint8_t *current_data = data_buf; // Loop until all data is written while (bytes_written < write_num) { // Calculate the number of bytes that can be written to the current page uint16_t bytes_to_write = AT24_MAX_PAGE_SIZE - (current_addr % AT24_MAX_PAGE_SIZE); if (bytes_to_write > write_num - bytes_written) { bytes_to_write = write_num - bytes_written; } if (device != NULL && device->write_bytes) { int ret = device->write_bytes(device->dev_addr, current_addr, current_data, bytes_to_write); if (ret != 0) { AT24_DBG("Failed to write %d bytes at address %04X", bytes_to_write, current_addr); return -1; } } else { return -1; } // Update the number of written bytes, current address, and data pointer bytes_written += bytes_to_write; current_addr += bytes_to_write; current_data += bytes_to_write; } return 0; } // Read a single byte from the specified register int at24cx_read_byte(at24cx_dev_t *device, uint16_t reg, uint8_t *data) { if (check_address_range(device, reg, 1) != 0) { return -1; } if (device != NULL && device->read_bytes) { int ret = device->read_bytes(device->dev_addr, reg, data, 1); if (ret == 0) { return 0; } AT24_DBG("Failed to read byte at register %02X", reg); } return -1; } // Read multiple bytes from the device int at24cx_read(at24cx_dev_t *device, uint16_t start_addr, uint8_t *data_buf, uint16_t read_num) { if (check_address_range(device, start_addr, read_num) != 0) { return -1; } if (device != NULL && device->read_bytes) { int ret = device->read_bytes(device->dev_addr, start_addr, data_buf, read_num); if (ret == 0) { return 0; } AT24_DBG("Failed to read %d bytes from register %02X", read_num, start_addr); } return -1; }