|
|
  |
STM32F4 + SPI FLASH MX25L256, Данные читаются неверно |
|
|
|
May 20 2013, 09:12
|

Знающий
   
Группа: Свой
Сообщений: 618
Регистрация: 7-06-08
Из: USSR
Пользователь №: 38 121

|
Написал набор функций для записи данных во ФЛЭШ память. Пробую записать 256 одинаковых байт на страницу начальную памяти, ну и затем их считать, байты записываются как надо, проверял осциллографом, а вот считываются неверные. т.е. записал скажем 256 байтов, каждый со значением 0xaa, а считываю 256 байтов и все со значением 0x80. Я пробовал записать другой байт в количестве 256, считывалось тоже самое, а иногда считывается совсем другое число, но тоже в количестве 256. А один раз помню даже заработало как надо! Но это только один раз, а в общем считываются неверно. Причем считывание проверял не только в дебаггере, но и на ножках микросхемы памяти (т.е. это не СТм32 портит полученные данные) Ну вот мой код основной: CODE mem_init(); // изначально поднять сигнал сs
mem_xferstart(); mem_wren(); mem_xferend();
mem_xferstart(); status_reg = mem_rdsr(); mem_xferend();
// брейкпоинт mem_xferstart(); mem_pp(); mem_xferend();
mem_xferstart(); status_reg = mem_rdsr(); mem_xferend(); //брейкпоинт
mem_xferstart(); status_reg = mem_rdsr(); mem_xferend();
//брейкпоинт mem_xferstart(); mem_read(); mem_xferend();
а вот каждая функция в отдельности CODE uint8_t mem_xferstart(void) { GPIOx->ODR &= !CS_PIN; // pull LOW CS return 0; }
uint8_t mem_xferend(void) { while ( (( (SPIx -> SR) & SPI_SR_BSY ) == SET) ) ;
GPIOx->ODR |= CS_PIN;
return 0; }
uint8_t mem_getbyte(void) { // check if there is a byte in shift register while ( (( (SPIx -> SR) & SPI_SR_TXE ) == RESET) ) ;
SPIx -> DR = 0xff; // send dummy byte
// check if there is a byte in shift register while ( (( (SPIx -> SR) & SPI_SR_RXNE ) == RESET) ) ;
return SPIx->DR; }
uint8_t mem_sendbyte(uint8_t sendbyte) {
// check if sent byte came back to shift reg. while ( (( (SPIx -> SR) & SPI_SR_TXE ) == RESET) ) ;
SPIx -> DR = sendbyte; // send byte
// check if sent byte came back to shift reg. while ( (( (SPIx -> SR) & SPI_SR_RXNE ) == RESET) ) ;
return SPIx->DR; }
uint8_t mem_rdsr(void) {
uint8_t sreg= 0;
//mem_xferstart(); mem_sendbyte(RDSR); sreg = mem_getbyte();
return sreg; }
uint8_t mem_wren(void) {
//mem_xferstart(); mem_sendbyte(WREN);
return 0; }
вот конкретно функция записи 256 байт CODE uint8_t mem_pp(void) {
uint8_t btw[256]; uint8_t byteread = 0; int i = 0;
// init the array of 256 bytes for(i=0;i<=255;i++) { btw[i]=0xaa; }
//mem_xferstart(); mem_sendbyte(PP); mem_sendbyte(0x0); mem_sendbyte(0x0); mem_sendbyte(0x0);
for(i=0;i<=255;i++) { mem_sendbyte(btw[i]); }
return 0; } а вот функция чтения 256 байт CODE uint8_t mem_read() {
uint8_t btr[256]; // array for read bytes
int i = 0; // loop var.
// init the array of 256 bytes with zeros for(i=0;i<=255;i++) { btr[i]=0; }
mem_sendbyte(READ); // READ command mem_sendbyte(0x0); // address mem_sendbyte(0x0); mem_sendbyte(0x0);
// read every byte into array of bytes for(i=0;i<=255;i++) { btr[i] = mem_getbyte(); }
//for (;;);
return 0; } И еще никаких подтяжек нету на чипе памяти. Чип соединен с платой Дискавери короткими проводами, скорость передачи малая. Чип отзывается нормально на простые команды приведенные выше в процессе коммуникации. Что еще я тут мог упустить?
Сообщение отредактировал IgorKossak - May 20 2013, 13:33
Причина редактирования: [codebox] для длинного кода, [code] - для короткого!!!
--------------------
Нажми на кнопку - получишь результат, и твоя мечта осуществится
|
|
|
|
|
May 20 2013, 11:16
|
Участник

Группа: Участник
Сообщений: 37
Регистрация: 16-06-11
Пользователь №: 65 731

|
BlackOps Не совсем понятно, есть ли где-нибудь ожидание окончания записи (между записью и чтением не увидел) и перед записью стирается ли сектор/страница (что там)
Сообщение отредактировал aoreh - May 20 2013, 11:20
|
|
|
|
|
May 20 2013, 13:21
|
Местный
  
Группа: Участник
Сообщений: 218
Регистрация: 24-06-10
Пользователь №: 58 127

|
Цитата И еще никаких подтяжек нету на чипе памяти. Положено подтягивать через 2 кОм.
|
|
|
|
|
May 20 2013, 14:01
|
Участник

Группа: Участник
Сообщений: 37
Регистрация: 16-06-11
Пользователь №: 65 731

|
Цитата(BlackOps @ May 20 2013, 16:23)  У меня там брейк поинт после записи стоит, а потом опять статусный регистр проверяю и вижу бит записи уже на нуле, начинаю читать. что со стиранием перед тем как писать, в коде ниче не видно, правильно делали? страницы точно "чистые"? и есть ссылка на даташит, сходу не находится?
Сообщение отредактировал aoreh - May 20 2013, 14:07
|
|
|
|
|
May 20 2013, 14:36
|

Знающий
   
Группа: Свой
Сообщений: 618
Регистрация: 7-06-08
Из: USSR
Пользователь №: 38 121

|
Цитата(aoreh @ May 20 2013, 19:01)  что со стиранием перед тем как писать, в коде ниче не видно, правильно делали? страницы точно "чистые"? и есть ссылка на даташит, сходу не находится? стирание перед чтением? нет этого я не делал, это стандартная процедура, без этого нельзя страницу писать? вот даташит http://www.macronix.com/QuickPlace/hq/Page...6Mb,%20v1.3.pdfсейчас попробую со стиранием перед записью кстати, я поставил подтяжку 10К на землю на: MISO,MOSI,SCK И подтяжку на питание в 10К на CS тоже самое, это не помогает..
--------------------
Нажми на кнопку - получишь результат, и твоя мечта осуществится
|
|
|
|
|
May 20 2013, 14:49
|
Знающий
   
Группа: Участник
Сообщений: 959
Регистрация: 11-01-06
Из: Санкт-Петербург
Пользователь №: 13 050

|
Цитата(vlad_new @ May 20 2013, 17:21)  Положено подтягивать через 2 кОм. приведите выдержку из даташита, там где "положено".. 2ТС я бы пошел по след. траектории - считал Id флеша - стер командой весь флеш - считал страницу и убедился, что чип чистый - попробовал записать страницу
|
|
|
|
|
May 20 2013, 14:53
|

Знающий
   
Группа: Свой
Сообщений: 618
Регистрация: 7-06-08
Из: USSR
Пользователь №: 38 121

|
Цитата(Jury093 @ May 20 2013, 19:49)  приведите выдержку из даташита, там где "положено"..
2ТС я бы пошел по след. траектории - считал Id флеша - стер командой весь флеш - считал страницу и убедился, что чип чистый - попробовал записать страницу 1) Id флеша считывается нормально и правильно (3 байта) 2) Попробовал перед записью стереть весь чип, так вот стираю чип, пишу, а после уже читаю, и интерестно то, что после этого чтения я все байты как 0хфф читаю!
--------------------
Нажми на кнопку - получишь результат, и твоя мечта осуществится
|
|
|
|
|
May 20 2013, 16:19
|
Участник

Группа: Участник
Сообщений: 37
Регистрация: 16-06-11
Пользователь №: 65 731

|
Цитата(BlackOps @ May 20 2013, 17:53)  1) Id флеша считывается нормально и правильно (3 байта)
2) Попробовал перед записью стереть весь чип, так вот стираю чип, пишу, а после уже читаю, и интерестно то, что после этого чтения я все байты как 0хфф читаю! Стирание - конечно, обычно стирание идет блоками, а запись страницами и да, перед записью или далеко заранее -уже какой алгоритм, но прямо перед записью, страница должна быть 0xff т.е. для простоты в вашем случае алгоритм такой: 1. стереть нулевой сектор (блок) 2. подождать готовности 3. считали, убедились, что 0хфф 4. запись нулевой страницы 5. ждем готовности 6. читаем вы не пропустили "2"? если пропустили, то все сходится, оно игнорит 3-4 и вы ждете готовности в "5", потом читаете фф ПС. на 6-й странице даташита: Any page to be programed should have page in the erased state frst.
Сообщение отредактировал aoreh - May 20 2013, 16:32
|
|
|
|
|
May 20 2013, 17:22
|

Знающий
   
Группа: Свой
Сообщений: 618
Регистрация: 7-06-08
Из: USSR
Пользователь №: 38 121

|
Короче, сделал все именно так, теперь заработало.
Вобщем там я смотрю три разные команды на стирание: Sector Erase на 4Кбайт Block Erase на 64Кбайт Block Erase 32K на 32Кбайт
я применил Sector Erase, и после этого выжидал (правда в дебаггере, пока не кодом проверял) и уже могу читать нормально то что записываю. Я просто не обратил внимание на этот момент стирания, да..и кстати, таким образом если в чипе заявлено: Typical 100,000 erase/program cycles то выходит уже не 100 000, а сразу 50 000, т.к. надо стирать перед записью, или erase/program они имели ввиду цикл стирание И запись?
И еще, не в подтяжках значит дело было которые я потом налепил. Пока я с прототипом играюсь, но такой вот вопрос: мне стоит поставить всетаки подтяжки как описал в предыдущем посте на финальную плату? (когда STM32 будет работать на полную скорость допустимой для SPI) ?
--------------------
Нажми на кнопку - получишь результат, и твоя мечта осуществится
|
|
|
|
|
May 20 2013, 17:31
|
Участник

Группа: Участник
Сообщений: 37
Регистрация: 16-06-11
Пользователь №: 65 731

|
Цитата(BlackOps @ May 20 2013, 20:22)  я применил Sector Erase, и после этого выжидал (правда в дебаггере, пока не кодом проверял) и уже могу читать нормально то что записываю. Я просто не обратил внимание на этот момент стирания, да..и кстати, таким образом если в чипе заявлено: Typical 100,000 erase/program cycles то выходит уже не 100 000, а сразу 50 000, т.к. надо стирать перед записью, или erase/program они имели ввиду цикл стирание И запись? обратите внимание, что ерэйз достаточно долгая операция (в сравнении с записью). я всегда считал, что именно 100000 циклов (т.е. пополам делить не нужно) Цитата(BlackOps @ May 20 2013, 20:22)  И еще, не в подтяжках значит дело было которые я потом налепил. Пока я с прототипом играюсь, но такой вот вопрос: мне стоит поставить всетаки подтяжки как описал в предыдущем посте на финальную плату? (когда STM32 будет работать на полную скорость допустимой для SPI) ? а зачем? можно было бы предположить, что чтобы вход стм-а (MISO) не висел в воздухе, когда нет CS на памяти, но, почему тогда просто интернал пуллап/даун не включить? я не ставил (правда чип другой и на истину не претендую  )
Сообщение отредактировал aoreh - May 20 2013, 17:32
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|