Обзор Чипа Внешней I2C Памяти AT24Cхх

36997cf524f77fb53c08bbcf22fabfb7.png

В разработке электронных плат часто надо подписывать электронные платы каким-то серийным номером. Это нужно для идентификации платы при серийном производстве.

Внешние чипы памяти особенно важны та как прошивку могут полностью стереть поэтому хранить серийный номер на микроконтроллере внутри on-chip NOR-Flash самого микроконтроллера ненадежно.

В 2012 году у меня в была задача на четырех микросхемах AT24C16 организовать энергонезависимый журнал для хранения наработок на отказ в холодильном оборудовании. Надо было быстро читать и писать блоки по 16 байт каждый. Тогда я записывал блоки в циклический массив на 100kHz-I2C EEPROM. В каждом блоке был 4 байтный timestamp от RTC. Для чтения и поиска я применил метод бинарного поиска для извлечения нужной записи. У меня за 4–6 секунд находился любой блок в памяти общим размером 8kByte.

В этом тексте я написал с какой стороны подходить к чипам внешней EEPROM.

Что надо из доков?

Название дока

Количество страниц

Vendor

1

AT24C02/04/08/16

13

Huaguan

2

AT24C02/04/08/16

14

Huaguan

3

Two-wire Serial EEPROM

27

Atmel

ASIC AT24C02M5/TR это китайский чип EEPROM на 256 байт с доступом по двухпроводному проводному синхронному последовательному интерфейсу I2C от компании Huaguan Semiconductor. Память поддерживает только 1 миллион записей. Это простой чип. Вся его спека — это всего 14 страниц.

Стоит чип AT24C02M5/TR всего 11 рублей.

35924f385f4ba202c1cb50c268205069.png

В нем 256 байт. Получается что 0.042 RUR/Byte= 44 RUR/kByte=45056 RUR/Mbyte=46.1 MRUR/GByte. Да уж. Жесткий диск на чипах EEPROM строить точно нет смысла. Иначе бы он стоил как 2 квартиры в Москве.

Что значит маркировка AT24C02M5/TR?

c07fbff2e356a26c8bb3a3083ef2cffd.png

Аппаратная часть

2dc36fcc202da6d720265581f426f530.png

На I2C шину можно подцепить до 8 ми таких чипов. Чтобы и них били разные I2C адреса придумали пины A[3]. Старший нимбл всегда 0b1010=0xA=10

df4268a0ebc8e71d0e35a19fe70c00d4.png

Получается что на одной I2C шине из этих микросхем можно собрать планку памяти максимум 8×2kByte=16kByte. А если учесть, что у среднего микроконтроллеров обычно три I2C интерфейса, то получается, что на этой элементной базе на одной электронной плате может быть максимум 48kByte EEPROM.

С точки зрения программиста, чип выглядит так.

515e9fa1ac54dab0572ee2d9a72119c7.png

Внутри чипа AT24Cxx можно увидеть поля засаженные транзисторами, генератор высокого напряжения для стирания Flash ячеек, аппаратный I2C трансивер, компаратор выбора I2C и компаратор совпадения адреса на шине. Еще в спеке упомянуто, что внутри есть триггер Шмитта.

ce741b86202899f3409ba39f36f9671f.png

Что надо из оборудования?
Для разработки и отладки драйвера I2C-EEPROM надо следующее оборудование

Оборудование

Назначение

1

Логический анализатор

Для записи электрического сигнала с I2C шины

2

перемычки

для соединения отладочной платы и модуля

3

отладочный модуль с чипом AT24C02

для отладки драйвера

4

отладочная плата с микроконтроллером и I2C интерфейсом

Для исполнения кода Cи-драйвера

5

Зажимы WAGO 3pin

для соединения логического анализатора и проводов шины I2C

6

DMM, 2 щупа, батарейка 9V для DMM

Для измерения напряжения на электронной плате

Программная часть

Биты передаются старшим битом вперед. Чтение из памяти выглядит так. Тут надо сразу отметить что WORD ADDRESS это 2 байта даже вопреки тому что в datasheet показали как 8 бит. Видимо это ошибка в datasheet (е). Иначе не проходят модулные тесты.

чтение

чтение

На практике чтение выглядит так. Тут видно, что из чипа 0×50 по адресу 7 прочиталось число 0×34. Тут видно два старта и один стоп.

Из I2C чипа c адресом 0x50 по адресу 0x0007 прочиталось число 0x34.

Из I2C чипа c адресом 0×50 по адресу 0×0007 прочиталось число 0×34.

Запись в память выглядит так. В в спецификации чтение показано так.

Figure 6: Page Write

Figure 6: Page Write

На практике оказывается, что адрес это тоже 2 байта. Однако в спеке адрес опять выглядит как один байт. Вот работающая I2C осциллограмма записи в чип 0×50 по адресу 7 значения 0×34.

Write in I2C сhip 0x50, Addr 0x0007, Byte 0x34

Write in I2C сhip 0×50, Addr 0×0007, Byte 0×34

Тут стоит заметить, что чипу AT24C02 надо минимум 5ms, чтобы завершить запись в ячейки EEPROM.

38d33e38fbb63c0cff7d8ce27a04a650.png

Записывать можно максимум количество байт в станице. Для чипа AT24C02 это 8 байт. Иначе внутренний приемный буфер переполнится и данные не будут записаны. Ну сами представьте, куда денутся данные, если вы по I2C решите отправить сразу поезд байтов длинной в гигабайт?

Самый простой вариант — это записывать байт за байтом. Один I2C пакет на один байт. Но только тогда придется ждать 5ms окончания записи каждого байта. Всю память можно будет прошить за 1.5 секунд. Либо прописать 32 страницы и это потребует всего 0.19 сек.

Вообще не всегда надо писать. Может статься, что в области памяти что вы хотите прописать уже лежат абсолютно те же самые данные, которые вы хотите прописать. Тогда надо делать так называемый Lazy Write. Сначала прочитать область памяти и если там уже то, что мы хотим, что сказать вызывающей функции, что мы записали, а самим не записывать. Таким программным образом вы сохраните ресурс чипа и он вам прослужит дольше.

Вот так может выглядеть API для драйвера чипа AT24CXX. Функции для чтения и функции для записи.

#ifndef AT24CXX_DRV_H
#define AT24CXX_DRV_H

#include 
#include 
#include 

#include "at24cxx_config.h"
#include "at24cxx_types.h"

uint8_t at24cxx_read_byte_short(uint8_t num, uint16_t address);
bool at24cxx_read_byte(uint8_t num, uint16_t address, uint8_t* const data);
bool at24cxx_read(uint8_t num, uint16_t address, void* const data, size_t size);
bool at24cxx_read_address(uint8_t num, uint16_t* const address);
bool at24cxx_is_connected(uint8_t num);
bool at24cxx_init(void);
bool at24cxx_write_ctrl(uint8_t num, bool on_off);

bool at24cxx_write(uint8_t num, uint16_t address, 
                   const uint8_t* const data, size_t size);
bool at24cxx_write_byte(uint8_t num, uint16_t address, uint8_t data);
bool at24cxx_write_page(uint8_t num, uint16_t address, uint8_t* page);
bool at24cxx_erase(uint8_t num, uint16_t address, size_t size);
bool at24cxx_erase_chip(uint8_t num);

#endif /* AT24CXX_DRV_H */

Отладка драйвера I2C-EEPROM

Подали питание и в логе загрузке микроконтроллер написал, что обнаружил AT24Cxx чип.

03c72a6ce4946ea701d25551a21a8ab5.png

В функцию инициализации имеет смысл добавить функцию вычисления CRC8. Один байт проще запомнить. Так можно будет, например, через день определить не санкционное изменение I2C-EEPROM, если в логе загрузки CRC8 вдруг окажется другим.

Вот результат сканирования I2C шины на которой сидит AT24C02

475bd4aa706c613eda884577e9e91ab9.png

Вот кого мы тут обнаружили

Ответивший на чтенье адрес, hex

Ответивший на чтенье адрес, Bin

1

0×50

0101_0000

2

0×58

0101_1000

3

0xD0

1101_0000

4

0xD8

1101_1000

GPIO пины для I2C должны быть подтянуты к VCC.

546fc263d8a981442c685f72428bda78.png

Чтение байта по адресу 8. Прочиталось значение 0×55.

d1af3f3e6a281755bbadc137215ad19e.png

запись байта 0×85 по адресу 8

ae423459d6f6df091c1736b6ae75029c.png

Удаление это по сути прописывание значения 0xFF.

Можно также в супер цикле периодически читать адрес I2C-чипа. Это поможет оперативно обнаружить обрыв соединения I2C шины до того как это понадобится для записи или чтения.

Тестирование драйвера AT24Cxx

Для драйвера AT24C02 у меня заготовлены вот эти 9 тестов.

630b654ef43d00ab2a3d00f1073c063b.png

Прогоним модульные тесты…

61e2169f72b4bf408c7e482b69a4de8c.png

Видно что все тесты прошли!

f127a2c75c14a5cdeb44a176e84423d4.png

Успех!

Достоинства I2C-EEPROM на основе AT24Cxx

1--Энергонезависимость

2--EEPROM хороша тем, что можно прописывать отдельные FF.

3--два провода для доступа к памяти

Недостатки

1--Дорогая память для масштабирования.

2--Надо ждать 5ms окончания каждой записи.

3--В спеке не сказано, что адрес двухбайтовый.

4--Мало памяти. Всего 256 байт.

Итоги

При разработке этого драйвера я столкнулся с контр интуитивными вещами. В спеке не сказано, что адрес двухбайтовый. Тем не менее удалось разработать драйвер для этого ASIC.

В отладке кода очень помогла UART-CLI и модульные тесты. Во время разработки драйвера даже ни разу не пришлось воспользоваться JTAG пошаговой отладкой.

Если вам нужен Си-драйвер для семейства микросхем AT24Cxx, то пишете в личку.

Словарь

Акроним

Расшифровка

EEPROM

electrically erasable programmable read-only memory

I2C

Inter-Integrated Circuit

SCL

SERIAL CLOCK

SDA

SERIAL DATA

ASIC

application-specific integrated circuit

Links
https://docs.google.com/spreadsheets/d/11aj3NdqWaDlz4OA9JxOmdXYTAaJEBaWIYc7GP2Ownq0/edit#gid=0

http://www.hgsemi.com.cn
https://www.youtube.com/watch? v=s7MYZamZ4hw

https://www.youtube.com/watch? v=urfhXmCd-uA

Контрольные вопросы:

1--Какой бит в адреcе I2C соответствует записи данных?

2--Как отличить ошибку «не читается по I2C» от ошибки «не пишется по I2C»?

3--Что такое Lazy Write?

4--Чем I2C-EEPROM лучше SPI-NOR Flash?

© Habrahabr.ru