FRAM
- Войдите на сайт для отправки комментариев
Пт, 08/11/2019 - 00:25
Здравствуйте.
первоисточник https://github.com/nw-wind/FM24I2C https://habr.com/ru/post/319336/
библиотеки
#include "Wire.h" #if ARDUINO >= 100 #include <Arduino.h> #else #include <WProgram.h> #endif #ifndef _FM24I2C_H_ #define _FM24I2C_H_ class FM24I2C { private: int id; public: FM24I2C(int id_addr); ~FM24I2C(); void pack(int addr, void* data, int len); // Pack data into FRAM int unpack(int addr, void* data, int len); // Unpack data from FRAM. Returns number of bytes read. void inline writeUnsignedLong(int addr, unsigned long data) { pack(addr, (void*)&data, sizeof(unsigned long)); } unsigned long inline readUnsignedLong(int addr) { unsigned long data; return unpack(addr, (void*)&data, sizeof(unsigned long)) == sizeof(unsigned long) ? data : 0UL; } }; #endif
int#include "FM24I2C.h" FM24I2C::FM24I2C(int id_addr) { id=id_addr; } FM24I2C::~FM24I2C() {} void FM24I2C::pack(int addr, void* data, int len) { Wire.beginTransmission(id); Wire.write((byte*)&addr,2); Wire.write((byte*)data,len); Wire.endTransmission(true); } int FM24I2C::unpack(int addr, void* data, int len) { int rc; byte *p; Wire.beginTransmission(id); Wire.write((byte*)&addr,2); Wire.endTransmission(false); Wire.requestFrom(id,len); for (rc=0, p=(byte*)data; Wire.available() && rc < len; rc++, p++) { *p=Wire.read(); } return(rc); }
Продолжу во втором топике.
Начну с того, что приложенный пример неправилен, там вытряхивается в сериал не буфер, а исходные массивы.
Если вытряхивать буфер, то там ничто.
писал разные тесты, чтобы вытряхивать элементы массива структур.
уже от отчаяния стал закидывать по одной структуре (лимит 32 байта для Wire). все равно какая то хрень.
такое ощущение, что неправильно адресуется сама микросхема FRAM, лопатил библиотеку по принципу EEPROMовских, все равно не пашить.
это вроде что то делает , но делает и за пределами адресного пространства 8192
памажите чем можите :) сильно хочется писать состояние много много раз, не думая о ресурсе записей
Может просто микроскхема нерабочая? И вообще что именно и как подключено?
как писал первоисточник, "Протокол i2c для FRAM сильно проще, чем для EEPROM"
так попробуйте как для EEPROM, поскольку под видом фрам часто продают перемаркер
Подключена обычно , i2c- 5 и 6 ноги, 1,2,3,4 ноги вместе дабы 50 адрес, 8 нога питание.
Вроде в чипдипе покупал, не должен быть перемаркер.
Еепром библиотеку попробовал , выше написано.
Подключена обычно , i2c- 5 и 6 ноги, 1,2,3,4 ноги вместе дабы 50 адрес, 8 нога питание.
Ну, пин 1 вообще-то лучше никуда не подключать. Пины адреса (2 и 3) pulled down, так что их можно к земле и не подключать. А как это все к ардуине подключено и есть pull-up резисторы на линиях I2C?
inspiritus - какого обьема микросхема?
Адресация на ФРАМках разного обьема делается по разному - похоже пейсатели библиотек этого не подозревают...
8kх8
конечно же i2c подтянуты.
эта библиотека вообще ея не видит
посмотрел даташит - похоже что библиотека правильная.
Есть подозрение, что у вас проблемы с выравниванием данных в структуре. Попробуйте для начала писать и читать однородный массив. скажем
uint16_t data[8]
Если ошибки пропадут - значит делов том, что ваша структура на самом деле не 14 байт
Добавлю - с год назад мы с sadman41 тестировали FRAM на число перезаписей. Никаких библиотек не использовали, писали напрямую через Wire. Сейчас посмотрел свой тогдашний код - он практически совпадает с кодом библиотеки в первом сообщении. Думаю, должен работать
#137
#137
Ух ты!
А что на этом модуле fram стоит? Или eeprom?
eeprom
посмотрел даташит - похоже что библиотека правильная.
Есть подозрение, что у вас проблемы с выравниванием данных в структуре. Попробуйте для начала писать и читать однородный массив. скажем
uint16_t data[8]
Если ошибки пропадут - значит делов том, что ваша структура на самом деле не 14 байт
Хм.. странно
какая то мистика
увеличил вычисленную длину записи на 1, тк. у автора библы strlen(sabj)+1,
при этом если писать по одной записи в адреса 0, 14,28... но с увеличенной длиной, все ок,
а в автомате лажа
но только до 7 элемента, далее ок
чуть исправил, но все равно странно - сначала криво, потом как надо.
хм, а кто вас учил вот так вот ссылку на элемент массива записывать?
(void*)&tpa_status[i]
Компилятор не ругается, случаем?
чуть исправленный пример автора
тоже показывает кривизну в адресации
кстати автор ответил, что есть непофикшенный баг в адресации, проблему он нашел, но некогда
и более на связь не выходил
такой способ обращения взял из примера для структуры с авторского поста с гитхаба, тоже удивился.
компилятор вообще молчок, даже если сообщения все включены
баг в адресации может быть двух видов
- формирование адреса для обращения к чипу
- передача сформированного адреса чипу
эти направления и ковыряю уже два дня.
inspiritus - зачем вам эта кривая библиотека? Добро бы там было что-то сложное - а то вся либа - это буквально 10 строк.
есть же даташит, возьмите да напишите прямо по нему. Жалко у меня FRAM на 4к бита - там принцип адресации чуть другой, а то я бы сам написал
нашел полезное обсуждение по теме
http://forum.amperka.ru/threads/Советую-детальку-eeprom-fram.16761/page-2
Ну разумеется лучше организовать жёсткий диск с файлами, именами и расширением.
В итоге, вкуривши, по совету мудрейшего b707, даташит и дискуссию , по указанной выше ссылке написал такой пример для своей заморочки, который работает именно так, как мне необходимо.
то есть две функции - читающую и пишущую во FRAM FM24LC64 массив структур
микросхема куплена в чипдипе за 84 рубля и предполагается к применению в модуле мониторинга состояния станка для постоянной записи статусов на случай отказа питания вместо eeprom, системы поддержания питания на аккумуляторе и детектирования перехода на него.
по возможности запакую в виде библиотеки и выложу.
еще раз благодарность b707 за волшебное побуждение к творчеству и sadman41 за помощь.
ну и отлично
Верно я понял, что вся разница заключается в очередности передачи байтов адреса?
было
стало
ЗЫ а что более конкретно не помог - извиняйте, болею....
Некоторые правки, которые бы сделал я, оставаясь в авторской концепции:
Ага, согласен :) спасибо sadman41!
в очередности передачи байтов адреса?
видимо да, сейчас в отъезде, доеду до дома, скорректирую библиотеку из хабра, наверно заработает.
Жалко у меня FRAM на 4к бита - там принцип адресации чуть другой, а то я бы сам написал
А нельзя ознакомится с вашим кодом для 4 килобит?
Я прост сейчас развлекаюсь с FM24C04A, и пока не могу понять, как оно работает. За основу взят код подобный тому, что в этой теме. Но скажем если с записью массива типа char у меня вопросов не возникает, то банальная побайтовая работа приводит к сбоям и зависаниям. И логику пока понять не могу. Хоть убей. :(
Увидеть бы гарантированно рабочий код, чтобы было от чего оттолкнуться.
Чип отвечает по адресам 0x50, 0x51 если что. Судя по сканеру. Что меня уже чутка озадачивает, с учетом 8 страниц.
К сбоям и зависаниям чего и какого вида?
Чип отвечает по адресам 0x50, 0x51 если что. Судя по сканеру. Что меня уже чутка озадачивает, с учетом 8 страниц.
4 мегабита - это 2 страницы, как раз с адресами 0x50, 0x51 если что.
Увидеть бы гарантированно рабочий код, чтобы было от чего оттолкнуться.
посмотрите в этой ветке начиная со страницы 4 - там люди в итоге разобрались, что к чему
http://forum.amperka.ru/threads/%D0%A1%D0%BE%D0%B2%D0%B5%D1%82%D1%83%D1%8E-%D0%B4%D0%B5%D1%82%D0%B0%D0%BB%D1%8C%D0%BA%D1%83-eeprom-fram.16761/page-4
если не поможет - позже поищу свой код, сейчас на работе запарка...
Подобная картина обычно бывает, когда ошибаемся в границах массива, например. Т.е. просто шаманские глюки. Или скажем читаем не из того места и не в том количестве, куда писали. И получаем мусор. Я подозреваю, что где-то я косячу по глупому скорее всего. Код покажу сейчас,не весь, но все что связано.
Так вот если я работаю с массивом hs_c1 - все отлично и корректно:
К краху приводит именно чтение, не запись. Но при этом тоже самое чтение с массивом hs_c1 замечательно работает.
Чечако, та же ошибка, что у всех - в строке 10 длина адреса ОДИН байт. а не два.
У микросхем с обьемом памяти до, если правильно помню, 16 кбит - адрес однобайтный, выше - два байта
Странно, конечно, что с массивом нормально. Выше inspiritus выяснил, что надо в адресе байты переворачивать.
Странно, конечно, что с массивом нормально. Выше inspiritus выяснил, что надо в адресе байты переворачивать.
для 4 Кбит нечего переворачивать. адрес 1 байт
Но для более других-то надо же, как я понимаю. А ошибка присутствует и такая в исходнике.
Странно, конечно, что с массивом нормально. Выше inspiritus выяснил, что надо в адресе байты переворачивать.
для 4 Кбит нечего переворачивать. адрес 1 байт
Переворачивать я пробовал - пофигу. Как правильно поправить код? Если я тупо 2 поменяю на 1, ничего не меняется. массив работает корректно как и раньше, байт приводит к сбоям.
Но для более других-то надо же, как я понимаю. А ошибка присутствует и такая в исходнике.
для разных обьемов - разный вид адреса. Я об этом твержу уже в третьей ветке...
Дак я спорю что ли?
Если не разберетесь - попозжа могу в ящике поискать свою фрамку.
Как правильно поправить код?
как-то так. Обратите внимание на тип переменной addr - это ансигнед байт. а не инт
Да, еще, len - максимум 31 байт, как я помню.
Как правильно поправить код?
как-то так. Обратите внимание на тип переменной addr - это ансигнед байт. а не инт
Да, еще, len - максимум 32 байта
len у меня 1 в случае байта, я выше показывал код. Ничего не меняется. Массив по прежнему работает корректно, байт по прежнему приводит к сбоям. И по факту или не сохраняется, или не оттуда читается. Ибо я счетчик туда пишу, в текстовый массив преобразую туда и обратно через string. Адрес я исправил в обоих функциях, понятное дело.
Вот код, который крутится в цикле - по сути два счетчика, вызов раз в секунду.
Соответственно, счетчик сохраняемый через массив работает корректно, после перезагрузки контроллера продолжает с того же места. Счетчик на byte - где-то на 15-16 цикле приводит к сбоям, ну и всегда начинается с нуля, что говорит о том, что его значение или не сохраняется, или не считывается.
Я понимаю, что это какая-то глупость скорее всего, но глаз видимо замылился.
len у меня 1 в случае байта, я выше показывал код.
выше вы показывали код, где адрес был 2 байта.
Извините, что я с вами как с новичком - но, пожалуйста, выложите актуальную версию кода с правильным адресом и правильной длиной....
Извините, что я с вами как с новичком - но, пожалуйста, выложите актуальную версию кода с правильным адресом и правильной длиной....
Извиняться не надо, я действительно туплю: Сейчас вот так:
По len - я про вашу фразу о ограничении длинной буфера по умолчанию в 32 (31). По факту у меня оно или всегда 5 для массива, или всегда 1 для байта. Код вызова функций в посту выше на один. :) Фрагмент вызывается по контролю millis примерно раз в секунду, если это важно.
С этим кодом сбой происходит стабильно на 39 секунде примерно с момента перезапуска контроллера по reset
в строках 7 и 19 false и true попробуйте убрать.
в строках 7 и 19 false и true попробуйте убрать.
Монопенисуально. Вот текущий код - я вообще сделал отдельный скетч, привожу целиком.
На 29 итерации все умирает. Выглядит в сериале вот так:
При этом сбой идет и при чтении ccc1 из fram - он вероятно возвращает ноль. Далее 30 у ccc2 и привет. Висим до резета. После резета ccc1 2524, значит считал 2523.
Адрес записи байта я поменял на 110 вместо 30 просто ради эксперимента.
Если закомментировать чтение байта с адреса 110, т.е. 34 строку скетча - все работает без проблем.
на строку 52 вставьте вывод hs_str в Сериал
Чечако, в 34 строке добавь & перед hs_ccc2
на строку 52 вставьте вывод hs_str в Сериал
На первых 30 сбойнула судя по выводу, на вторых повисли - фрагмент сериала прилагаю:
Я добавил вывод количества считанных байт, вот текущий код:
Чечако, в 34 строке добавь & перед hs_ccc2
Если так сделать - hs_ccc2 обнуляется каждую итерацию.
Но вот если & добавить не только в 34, но и в строку записи тоже - которая 54 в том примере примере, то все работает и не виснет... :-/
Можно объяснить, в чем магия?
Можно объяснить, в чем магия?
какая магия? у вас же в процедуразх записи и считывания используется указатель...
какая магия?
Как какая? Разве третий закон Кларка уже отменили?
Исходник (не сильно красивый):
Лог: