Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: ATSAM4S + память F-RAM FM25V20
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
Haamu
Память подключена к шине SPI, ногх WP и HOLD установлены единицы. SPI Mode 0, частота 20Мгц (хотя пробовал и Mode 3 и частоту менял). Другая микросхема на той же шине SPI работает нормально.
Пробовал прочитать Status регистр и Devise ID, в результате читаются все нули.
Читаю, как написано в даташите, например для Status-регистра:
1)Отправляю 0x05
2)Отправляю 0xFF
3)Смотрю что пришло, а пришел 0.
Кто сталкивался с подобной памятью, подскажите, что я делаю не так? Может какие-то хитрости есть, которых я не увидел, читая даташит?
Golikov A.
что с чип селектом то?
у меня вот такая инициализация, это от другой фрамки и другого проца, но это не важно
CODE


//настройки FRAM, значение статусного регистра при инициализации
//записываем в регистр статуса 0х00
//ставим WPEN в 0, отключаем ножку защиты записи
//ставим BP1, BP0 в 0, все блоки F-RAM не защищены от записи
#define FRAM_STAT_REG 0x00

/****************************************************************
Функция инициализации F-RAM.
входные данные:
нет
выходные данные:
код ошибки
0 - нет ошибок
****************************************************************/
int FRAMInit(void)
{
//задержку перед первым обращением к FRAM после подания питания можно не делать, так как
//есть задержка перед пуском контроллера после установления питания, а она значительно больше

FRAM_CS_UP; //на всякий случай, этого можно и не делать, так как важен уровень а не фронт

FRAM_HOLD_UP; //убираем сигнал ХОЛД с F-RAM, не используем этот режим

//коммуникации с F-RAM может осуществляются через SPI, несколько байтными посылками.
//Чтобы коммуникация не была прервана прерываниями, в которых другие модули
//также могут задействовать SPI, и прервать текущую посылку, испортить данные,
//запрещаем прерывания на время посылки (время между чип селекати F-RAM).
//если SPI реализован программно на выделенных контактах, и прерывания не требуется запрещать
//можно не определять макрос SPI_CLEAR_GIF
#ifdef FRAM_CLEAR_GIF
//на случай если прерывания были уже запрещены к моменту вызову функции
//сохраним статус прерываний
char IntStat=FRAM_GET_GIF_STATUS;
FRAM_CLEAR_GIF; //запрещаем прерывания
#endif

//выбираем FRAM, чипселект в 0
FRAM_CS_DOWN;

SendFRAMByte(FRAM_WREN); //разрешение записи для записи регистра статуса
FRAM_CS_UP; //снимает выбор F-RAM, ставим чип селект в 1

//новая командная посылка, прерывания остаются запрещенными
FRAM_CS_DOWN; //выбираем F-RAM, ставим чипселект в 0
SendFRAMByte(FRAM_WRST); //режим записи регистра статуса
SendFRAMByte(FRAM_STAT_REG); //записываем статусный регистр

FRAM_CS_UP;//снимает выбор F-RAM, ставим чип селект в 1

#ifdef FRAM_CLEAR_GIF
//восстанавливаем значение флага прерываний на момент входа в функцию,
//на случай если флаг был снят в других модулях
FRAM_RESTORE_GIF(IntStat);
#endif

return 0;
}



и к этому такие чтение - запись

CODE
/****************************************************************
Функция записи данных во F-RAM.
входные данные:
Addr - адрес записи данных (адрес 16 бит, FRAM до 512 кБит)
Data - данные для записи
Length - длинна данных в байтах
выходные данные:
код ошибки
0 - нет ошибок
****************************************************************/
int WriteFRAM(unsigned long int Addr, char *Data, unsigned Length)
{
//коммуникации с F-RAM может осуществляются через SPI, несколько байтными посылками.
//Чтобы коммуникация не была прервана прерываниями, в которых другие модули
//также могут задействовать SPI, и прервать текущую посылку, испортить данные,
//запрещаем прерывания на время посылки (время между чип селекати F-RAM).
//если SPI реализован программно на выделенных контактах, и прерывания не требуется запрещать
//можно не определять макрос SPI_CLEAR_GIF
#ifdef FRAM_CLEAR_GIF
//на случай если прерывания были уже запрещены к моменту вызову функции
//сохраним статус прерываний
char IntStat=FRAM_GET_GIF_STATUS;
FRAM_CLEAR_GIF; //запрещаем прерывания
#endif

//выбираем FRAM, чипселект в 0
FRAM_CS_DOWN;

SendFRAMByte(FRAM_WREN); //разрешения запси
FRAM_CS_UP; //выбираем F-RAM, ставим чипселект в 0

//новая командная посылка, прерывания остаются запрещенными
FRAM_CS_DOWN; //выбираем F-RAM, ставим чипселект в 0
SendFRAMByte(FRAM_WRITE); //режим записи в память
//передаем адрес данных для записи
#ifdef FRAM_17BIT_ADDRES //если используется 17 битная адресация для FRAM>512Кбит
SendFRAMByte((Addr>>16)&0xFF); //старший байт адреса, используется младший бит
#endif
SendFRAMByte((Addr>>8)&0xFF); //второй байт адреса
SendFRAMByte(Addr&0xFF); //младший байт адреса

for(unsigned int i=0;i<Length;i++)//цикл записи по длине данных
SendFRAMByte(Data[i]);

FRAM_CS_UP;//снимает выбор F-RAM, ставим чип селект в 1

#ifdef FRAM_CLEAR_GIF
//восстанавливаем значение флага прерываний на момент входа в функцию,
//на случай если флаг был снят в других модулях
FRAM_RESTORE_GIF(IntStat);
#endif

return 0;
}

/****************************************************************
Функция чтения данных из F-RAM.
входные данные:
Addr - адрес чтения данных (адрес 16 бит, FRAM до 512 кБит)
Data - буфер данных для сохранения прочитанных данных
Length - длинна данных в байтах
выходные данные:
код ошибки
0 - нет ошибок
****************************************************************/
int ReadFRAM(unsigned long int Addr, char *Data, unsigned Length)
{
//коммуникации с F-RAM может осуществляются через SPI, несколько байтными посылками.
//Чтобы коммуникация не была прервана прерываниями, в которых другие модули
//также могут задействовать SPI, и прервать текущую посылку, испортить данные,
//запрещаем прерывания на время посылки (время между чип селекати F-RAM).
//если SPI реализован программно на выделенных контактах, и прерывания не требуется запрещать
//можно не определять макрос SPI_CLEAR_GIF
#ifdef FRAM_CLEAR_GIF
//на случай если прерывания были уже запрещены к моменту вызову функции
//сохраним статус прерываний
char IntStat=FRAM_GET_GIF_STATUS;
FRAM_CLEAR_GIF; //запрещаем прерывания
#endif

//выбираем FRAM, чипселект в 0
FRAM_CS_DOWN;

SendFRAMByte(FRAM_READ); //режим чтения памяти
//передаем адрес данных для чтения
#ifdef FRAM_17BIT_ADDRES //если используется 17 битная адресация для FRAM>512Кбит
SendFRAMByte((Addr>>16)&0xFF); //старший байт адреса, используется младший бит
#endif
SendFRAMByte((Addr>>8)&0xFF); //второй байт адреса
SendFRAMByte(Addr&0xFF); //младший байт адреса
for(unsigned int i=0;i<Length;i++)//цикл чтения по длинне данных
ReadFRAMByte(&Data[i]);

FRAM_CS_UP;//снимает выбор F-RAM, ставим чип селект в 1

#ifdef FRAM_CLEAR_GIF
//восстанавливаем значение флага прерываний на момент входа в функцию,
//на случай если флаг был снят в других модулях
FRAM_RESTORE_GIF(IntStat);
#endif

return 0;
}





Haamu
Всё как положено, перед передачей опускаю в ноль, в конце передачи поднимаю обратно в единицу. Для уверенности даже мультиметром проверил.
Golikov A.
ну остается проверить клоки, частоты, и что данные идут физически до ножек. Это очень простая и тупая память, если питание и сигналы есть, все должно быть ок...

кстати ответ на запрос статуса может быть и 0 на самом деле... вот с ID да... там что-то другое должно быть
не фигню сказал, оба не 0 должны быть
DmitryM
Цитата(Haamu @ Apr 29 2014, 16:13) *
3)Смотрю что пришло, а пришел 0.
Кто сталкивался с подобной памятью, подскажите, что я делаю не так? Может какие-то хитрости есть, которых я не увидел, читая даташит?

Если мсх не отвечает, должны читаться 1. SO подтянут? Смотрите времена TpowerUp и Trecovery(сомнительно), они довольно значительные.
Haamu
Цитата(DmitryM @ Apr 29 2014, 17:36) *
Если мсх не отвечает, должны читаться 1. SO подтянут?

А должен быть подтянут? К питанию? У меня не подтянут. Попробовал подтянуть к питанию, ничего не изменилось. Разве что теперь не нули читаются а единицы.
mempfis_
Цитата(Haamu @ Apr 29 2014, 16:13) *
Кто сталкивался с подобной памятью, подскажите, что я делаю не так? Может какие-то хитрости есть, которых я не увидел, читая даташит?


В документации хитростей не обнаружено. Подобная микросхема fm25cl64 с идентичным набором команд (в ней отсутствует только команда SLEEP) работает без проблем.
Проверьте время после активации CS и до начала передачи данных. Маловероятно, но может быть память находится в слипе и её необходимо выдерживать время выхода из слипа после активации. Также стоит проверить режим работы SPI и временные параметры тактирования. Естественно всё с помощью осциллографа, а не тестера.
Там у Вас действительно 20МГц? У памяти предел 40 - может где ошиблись в настройках SPI.
Jury093
Цитата(Haamu @ Apr 29 2014, 17:51) *
А должен быть подтянут? К питанию? У меня не подтянут. Попробовал подтянуть к питанию, ничего не изменилось. Разве что теперь не нули читаются а единицы.

SI/SO местами не попутаны?
задвигаете MSB вперед?
это учитываете:
Код
The device detects the SPI mode from the status of the SCK pin
when the device is selected by bringing the CS pin LOW.
DmitryM
Цитата(Haamu @ Apr 29 2014, 16:51) *
А должен быть подтянут? К питанию? У меня не подтянут. Попробовал подтянуть к питанию, ничего не изменилось. Разве что теперь не нули читаются а единицы.

А что будет на висящем в воздухе входе мк? Ведь когда нет общения с мсх памяти у неё SO в Hi-Z состоянии. Конечно нужно PullUp (или внешний или внутренний в мк).
KnightIgor
Цитата(DmitryM @ Apr 29 2014, 18:02) *
А что будет на висящем в воздухе входе мк?

Наводки. Разброд и шатание. Встроенные диоды должны защитить от пробоя от накопления заряда, но посадить висящий конец на какой-либо потенциал будет по-пацански.
Golikov A.
какая разница что на висящем конце (глупо звучит), если он отпущен, то там ничего никому не нужно, а когда нужны данные то там появиться правильный сигнал (ну кроме экзотических случаев, которые должны быть описаны в инструкции). Потому стоит начать с понижения частот, и контроля происходящего оссцилографом, а подтяжки это чисто для определенности, по-пацански как сказали...
DmitryM
Цитата(Golikov A. @ Apr 30 2014, 01:04) *
какая разница что на висящем конце (глупо звучит), если он отпущен


в оригинале было "входе мк". Потом можно не удивляться повышенному энергопотреблению и проч.
Haamu
Не уверен, кто именно подтягивает (у меня помимо памяти на шине SPI еще ЦАП висит и развязывающая микросхема (к ней потом будет подключаться еще другая плата)), но в спокойном состоянии и MISO и MOSI находятся в высоком состоянии.
Смотрел осциллографом. В настройках сейчас Mode 0, 1МГц. Всё как должно быть, по первому восходящему фронту клока по линии MOSI передаются данные, старшим битом впереед, в это время на линии MISO ноль...
Попробовал паузы делать после установки CS и между байтами в 1-2 мкс. Пробовал на другой точно такой же плате. Даже на всякий случай попробовал развернуть зеркально байт команды. И ничего не изменилось...
mempfis_
Цитата(Haamu @ Apr 30 2014, 09:06) *
Попробовал паузы делать после установки CS и между байтами в 1-2 мкс. Пробовал на другой точно такой же плате. Даже на всякий случай попробовал развернуть зеркально байт команды. И ничего не изменилось...


Обращаться к других устройствам SPI пробовали? Если остальные устройства на этой шине работают, а не работает только память, то вероятно проблема в памяти. Может быть у Вас ВСЕ микросхемы памяти битые изначально. Или подделки. Или её убили при сборке на всех платах. Если вместо FRAM на проводках припаять любую DATA FLASH и протестировать? Может быть у Вас несколько CS активируется?
Мой опыт общения с FRAM показал что на её освоение тратится не более часа (при наличии опыта работы с любой DATA FLASH) и работает она с пол пинка. Так что я склоняюсь к тому, что микросхемы битые (при условии что остальные SPI-устройства действительно не мешают работе памяти).
Golikov A.
а конфликтов осцилом не видно? может правда двойной CS где пролез?
Haamu
Нет, конфликтов не видно. Да и проверил на всякий случай, опускается в ноль только нужный CS, остальные остаются в единице. Видимо все-таки дохлая память.
Golikov A.
а питание, земля, правильность ног (MISO, MOSI), возможные непропаи проверили?
если картинка на осциле совпадает с описанием и ответа нет, то только неправильная работа микрухи, больше ничего...
DmitryM
Цитата(Haamu @ Apr 30 2014, 09:06) *
Попробовал паузы делать после установки CS и между байтами в 1-2 мкс.

Tpu = min = 1 ms, не us
jcxz
Цитата(DmitryM @ May 1 2014, 09:22) *
Tpu = min = 1 ms, не us

С чего вы взяли? FRAM она не такая медленная.
У меня во многих проектах используется FRAM на SPI (и на I2C). Везде на максимальной или близкой к максимальной частоте,
везде прекрасно работает. Никаких задержек между CS=0 и стартом, и стопом и CS=1 нигде нет. Все необходимые
задержки формирует SPI-модуль CPU.
Проблемы были вначале только с аппаратно формируемым сигналом CS. Когда сделал
его программным - больше проблем не было.

А у ТС какой CS? Программно формирует или от SPI-порта?
У меня проблема выражалась в том, что при частоте SPI==20МГц, DMA, аппаратном CS происходили редкие сбои.
CPU - LPC1758, LPC1778.
Выявить их удалось только осциллом причём на большой частоте в ждущем режиме - очень короткие просадки CS -
положительные импульсы порядка десятков нсек. Видимо DMA где-то не успевает. Хотя в SPI имеется FIFO.
Видимо CPU занимает шину и DMA изредка не успевает прокачать.
DmitryM
Цитата(jcxz @ May 1 2014, 10:02) *
С чего вы взяли? FRAM она не такая медленная.

Из datasheet.
jcxz
а точнее? Приведите выдержку.
Golikov A.
в даташите там все наносекунды
самая длинное время деселекта 60 нСек
время между чипселектом и первым фронтом клока 10-12 нСек зависит от питания

а вот время PowerUp действительно 1 милисекунда, причем считая не от падания питания, а от момента его достаточного уровня.

http://static.uralchip.ru/content/pdfs/284/9105149.pdf

да аппаратный CS часто после каждого слова возвращает чипселект обратно, для этой памяти так нельзя,он всю посылку должен быть выбран. Но у автора на шине несколько устройств, так что вряд-ли у него чипселект аппаратный, как бы он тогда выбирал бы?
jcxz
Цитата(Golikov A. @ May 1 2014, 15:26) *
да аппаратный CS часто после каждого слова возвращает чипселект обратно, для этой памяти так нельзя,он всю посылку должен быть выбран. Но у автора на шине несколько устройств, так что вряд-ли у него чипселект аппаратный, как бы он тогда выбирал бы?

А вы знаете SPI-периферию атмеловских армов?
Вот например в OMAP L-138 SPI-порты имеют по несколько штук аппаратных чипселектов.
И ими можно рулить прямо в процессе записи в data-регистр SPI (в старших битах регистра находятся биты управления
этими CS, и вместе с операцией записи данных в порт можно устанавливать нужный CS. Там-же кстати насколько помню
можно сразу задавать какие-то задержки относительно CS, этой-же записью).
Может у атмела тоже что-то подобное есть?

В LPC CS не должен возвращаться назад после каждой записи, ибо там FIFO, да ещё DMA должно по идее успевать
подкачивать след. слово пока выдвигается предыдущее. Но не всегда видать успевает. sad.gif
Golikov A.
А правда ваша, в этом проце 4 чипселекта, вот диковинка какая... я правда сначала даже не понял как вы определили что за проц, а потом понял что в названии темы написанsm.gif.

А про LPC 1768 как показала мое исследование с осциллографом для его SSP, чипселект ведет себя по разному в зависимости от скорости передачи. На одних скоростях чипселект падал на каждое слов, на максимальных на всю посылку. И зависит от того как данные лезут по DMA или через FIFO.
gappi
Haamu, Вы в итоге разобрались со своей проблемой?
У меня например после подачи команды на чтение статус регистра всегда отвечает 0x0F
Пробовал записывать и отчищать защиту от записи - содержание статус регистра (врнее, то что читается не изменяется)
Клоки, ноги проверял.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.