Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: STM32F4 + SPI FLASH MX25L256
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
BlackOps
Написал набор функций для записи данных во ФЛЭШ память.
Пробую записать 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;
}


И еще никаких подтяжек нету на чипе памяти.
Чип соединен с платой Дискавери короткими проводами, скорость передачи малая.
Чип отзывается нормально на простые команды приведенные выше в процессе коммуникации.

Что еще я тут мог упустить?
aoreh
BlackOps
Не совсем понятно, есть ли где-нибудь ожидание окончания записи (между записью и чтением не увидел) и перед записью стирается ли сектор/страница (что там)
vlad_new
Цитата
И еще никаких подтяжек нету на чипе памяти.

Положено подтягивать через 2 кОм.

BlackOps
Цитата(aoreh @ May 20 2013, 16:16) *
BlackOps
Не совсем понятно, есть ли где-нибудь ожидание окончания записи (между записью и чтением не увидел) и перед записью стирается ли сектор/страница (что там)

У меня там брейк поинт после записи стоит, а потом опять статусный регистр проверяю и вижу бит записи уже на нуле, начинаю читать.
aoreh
Цитата(BlackOps @ May 20 2013, 16:23) *
У меня там брейк поинт после записи стоит, а потом опять статусный регистр проверяю и вижу бит записи уже на нуле, начинаю читать.

что со стиранием перед тем как писать, в коде ниче не видно, правильно делали? страницы точно "чистые"?
и есть ссылка на даташит, сходу не находится?
BlackOps
Цитата(aoreh @ May 20 2013, 19:01) *
что со стиранием перед тем как писать, в коде ниче не видно, правильно делали? страницы точно "чистые"?
и есть ссылка на даташит, сходу не находится?

стирание перед чтением? нет этого я не делал, это стандартная процедура, без этого нельзя страницу писать?

вот даташит
http://www.macronix.com/QuickPlace/hq/Page...6Mb,%20v1.3.pdf

сейчас попробую со стиранием перед записью

кстати, я поставил подтяжку 10К на землю на: MISO,MOSI,SCK
И подтяжку на питание в 10К на CS

тоже самое, это не помогает..
Jury093
Цитата(vlad_new @ May 20 2013, 17:21) *
Положено подтягивать через 2 кОм.

приведите выдержку из даташита, там где "положено"..

2ТС я бы пошел по след. траектории
- считал Id флеша
- стер командой весь флеш
- считал страницу и убедился, что чип чистый
- попробовал записать страницу
BlackOps
Цитата(Jury093 @ May 20 2013, 19:49) *
приведите выдержку из даташита, там где "положено"..

2ТС я бы пошел по след. траектории
- считал Id флеша
- стер командой весь флеш
- считал страницу и убедился, что чип чистый
- попробовал записать страницу



1) Id флеша считывается нормально и правильно (3 байта)

2) Попробовал перед записью стереть весь чип, так вот стираю чип, пишу, а после уже читаю, и интерестно то, что после этого чтения я все байты как 0хфф читаю!
aoreh
Цитата(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.
BlackOps
Короче, сделал все именно так, теперь заработало.

Вобщем там я смотрю три разные команды на стирание:
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) ?
aoreh
Цитата(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 на памяти, но, почему тогда просто интернал пуллап/даун не включить? я не ставил (правда чип другой и на истину не претендую sm.gif )
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.