[Из песочницы] Подключение Xmega к FRAM по SPI

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

На мой взгляд, в данный момент самое оптимальное решение для таких случаев, это FRAM память. Можно было бы записывать необходимые данные циклически во Flash, постоянно инкрементируя адрес для новых значений, но в данном случае возникала необходимость где-то сохранять указатель на самые последние значения, либо полностью считывать Flash и затем уже извлекать «самые свежие» данные.

У Lapis Semiconductor есть три линейки FRAM микросхем, которые обмениваются с ведущим устройством по I2C или SPI, либо по параллельному интерфейсу. Преимущества последовательных интерфейсов перед параллельным очевидны. Что же касается I2C и SPI, то скорость передачи данных по SPI в 4 раза выше чем по I2C, но и потребление в связи с этим выше практически в 16 раз.

Мне же выбирать не приходилось, в наличии была только MR45V256 c 32 Кб памяти и SPI интерфейсом. 32 Кб для моих нужд более чем достаточно, поэтому оставшуюся память я использовал для записи всевозможной технической информации и логирования команд полученных от оператора.

Работа с FRAM памятью очень простая. Любая операция начинается с перевода линии выбора ведомого устройства CS# в низкое состояние. Затем отправляется одна из команд операций, их всего 6:

— Чтение данных (READ)
 — Запись данных (WRITE)
 — Запись в регистр статуса FRAM (WRSR)
 — Чтение из регистра статуса FRAM (RDSR)
 — Установка защиты данных от перезаписи (WRDI)
 — Снятие защиты данных от перезаписи (WREN)

Защиту от перезаписи можно установить либо на первую четверть памяти, либо на первую половину или же на всю память полностью. В случаях с командами чтения и записи, после них необходимо отправить еще и шестнадцатеричный адрес, с которого начнется чтение/запись. Команда и адрес отправляются единоразово, в последующем микросхема сама инкрементирует адрес и передает все последующие данные, до тех пор пока CS# не будет переведен в высокое состояние.

Перед тем как начать запись в память, необходимо всегда устанавливать бит разрешения записи (WREN) в регистре статуса MR45V256. И только после этого передавать команду записи (WRITE).

image

В качестве ведущего устройства использовал микроконтроллер Xmega. SPI микроконтроллеров Xmega практически ничем не отличается от SPI в других микроконтроллерах Atmel. Наиболее заметное отличие это возможность использования DMA, но объемы передаваемой информации в данном случае у меня не большие, поэтому от использования DMA я отказался. Xmega поддерживает все 4 режима работы SPI (Mode 0,1,2,3). Стоит заметить, что MR45V256 поддерживает только Mode 0 и Mode 3.

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

// Директивы для SPIE
#define	FRAMPORT	PORTE // FRAM PORT
#define	SPIRESET	0
#define	SPICS		4
#define	SPIMOSI		5
#define	SPIMISO		6
#define SPISCK		7

// Функция инициализации SPIE(FRAM)
void SPIE_init()
{
	FRAMPORT.DIRCLR = (1<

Команды для стирания во FRAM не предусмотрено, так как данные можно перезаписывать без предварительного стирания, как например в других видах памяти. Но всё же иногда возникает необходимость полного «стирания» всей FRAM:
void FramErase(void)
{
	SPIE_init();
	FRAMPORT.OUTCLR = (1<

Если говорить о преимуществах использования FRAM, то в первую очередь это надёжность. Количество циклов записи 10 в 12 степени. Производитель обещает до 10 лет хранения информации без её потери. По сравнению с той же FLASH память FRAM обладает большим быстродействием и куда меньшим потреблением. Из минусов можно отметить если только не большой объём памяти, но с учетом тех задач для которых обычно используют FRAM, большие объемы не так важны.

Комментарии (0)

© Habrahabr.ru