Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Работа с NAND FLASH.
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
Jenya7
При обращении к памяти (чтение, запись) я передаю адрес (на картинке)
Скажем при стирании блока (на картинке) - я должен передать адрес блока – 11 бит? Или адрес блока – 11 бит + адрес страницы – 6 бит?
Если блок + страница то получается так?
Код
//////////////////////////////////// ERASE BLOCK  /////////////////////////////
   SPI2_CS0_OFF;
   SPI_rw_flash(NAND_FLASH_BLOCK_ERASE, &dummy);
   temp = 0 | (block_addr >> 10);
   SPI_rw_flash(temp, &dummy);  // Dummy+A16
   temp = block_addr >> 8;
   SPI_rw_flash(temp, &dummy);   //A15-A8
   temp =( block_addr<<3) | page_addr;
   SPI_rw_flash(temp, &dummy);   //A7-A0
   SPI2_CS0_ON;



или нет.
У нас дано
Block Address (2048 blocks/device): 11 bits
Page Address (64 pages/block): 6 bits
Исходя из этого строим Row Address uint32_t row_address = (block_address<<6) | page_address;
а теперь это адрес нужно передать тремя байтами
первый - temp = row_address >> 16;
второй - temp = row_address >> 8;
третий - temp = row_address & 0xFF;
получается так ?
Alex11
Про какую NAND речь-то идет? Мы все опять догадываться должны?
Jenya7
Цитата(Alex11 @ Jun 20 2018, 23:32) *
Про какую NAND речь-то идет? Мы все опять догадываться должны?

TC58CVG2S0HxAIx.

Скажем я хочу стереть блок
CODE
uint32_t NFLASH_WriteEnable(void)
{
uint8_t dummy, l_error, status;
uint32_t timeout = 0, count_cycles;

do
{
SPI2_CS0_OFF;
l_error = SPI_TransferByte(SPI2_BASE_PTR, NAND_FLASH_WRITE_ENABLE , &dummy);
SPI2_CS0_ON;

for(count_cycles = 0; count_cycles < NAND_FLASH_TIME_OUT; count_cycles++);

SPI2_CS0_OFF;

l_error |= SPI_TransferByte(SPI2_BASE_PTR, NAND_FLASH_GET_FEATURES, &dummy);
l_error |= SPI_TransferByte(SPI2_BASE_PTR, NAND_FLASH_STATUS_REGISTER_ADDRESS, &dummy);
l_error |= SPI_TransferByte(SPI2_BASE_PTR, 0x0, &status);

SPI2_CS0_ON;

for(count_cycles = 0; count_cycles < NAND_FLASH_TIME_OUT; count_cycles++);

if (timeout++ > NAND_FLASH_TIMEOUT)
return NAND_FLASH_WE_FAIL;

}
while ((status & WEL) == 0); //write enable flag

return NAND_FLASH_OK;
}
uint32_t NFLASH_CheckErase(void)
{
uint8_t dummy, l_error, status;
uint32_t timeout = 0, count_cycles;

do
{
SPI2_CS0_OFF;
l_error |= SPI_TransferByte(SPI2_BASE_PTR, NAND_FLASH_GET_FEATURES, &dummy);
l_error |= SPI_TransferByte(SPI2_BASE_PTR, NAND_FLASH_STATUS_REGISTER_ADDRESS, &dummy);
l_error |= SPI_TransferByte(SPI2_BASE_PTR, 0x0, &status);
SPI2_CS0_ON;

if ( timeout++ > NAND_FLASH_TIMEOUT)
return NAND_FLASH_ERASE_FAIL;

for(count_cycles = 0; count_cycles < NAND_FLASH_TIME_OUT; count_cycles++);
}
while ((status & ERS_F) == 1); //erase fail flag

return NAND_FLASH_OK;
}
uint32_t NFLASH_BlockErase(uint32_t block_addr)
{
uint8_t dummy, l_error, temp;
uint32_t count_cycles;
uint32_t status;

//status = NFLASH_CheckBusy();

//if (status == NAND_FLASH_OK)
//{
status = NFLASH_WriteEnable();
if (status == NAND_FLASH_OK)
{
SPI2_CS0_OFF;
l_error = SPI_TransferByte(SPI2_BASE_PTR, NAND_FLASH_BLOCK_ERASE, &dummy);
temp = block_addr >> 16;
l_error |= SPI_TransferByte(SPI2_BASE_PTR, temp, &dummy); // Dummy+A16
temp = block_addr >> 8;
l_error |= SPI_TransferByte(SPI2_BASE_PTR, temp, &dummy); //A15-A8
temp = block_addr & 0xFF;
l_error |= SPI_TransferByte(SPI2_BASE_PTR, temp, &dummy); //A7-A0
SPI2_CS0_ON;

for(count_cycles = 0; count_cycles < NAND_FLASH_TIME_OUT; count_cycles++);

status = NFLASH_CheckErase();
if (status != NAND_FLASH_OK)
return status;
}
else
return status;
//}
//else
//return status;

return NAND_FLASH_OK;
}
И потом
Код
row_address = (block_address<<6) | (page_address&0x3F);
NFLASH_BlockErase(row_address );

Я правильно понимаю процесс?
Alex11
У Вас же все черным по белому в DS написано. Для стирания нужно подать команду write enable - передать байт 0x06 с установленным CS, затем снять CS, подать команду стирания блока - установить обратно CS, передать последовательно байты 0xD8, A16, A15-A8, A7-A0, снять CS. Затем командой get feature проверить результат. В адресе используются только биты 16-6, остальные биты могут иметь любое значение. В байте А16 идут 7 бит нулей и A16 в младшем бите.
Jenya7
Цитата(Alex11 @ Jun 23 2018, 05:15) *
У Вас же все черным по белому в DS написано. Для стирания нужно подать команду write enable - передать байт 0x06 с установленным CS, затем снять CS, подать команду стирания блока - установить обратно CS, передать последовательно байты 0xD8, A16, A15-A8, A7-A0, снять CS. Затем командой get feature проверить результат. В адресе используются только биты 16-6, остальные биты могут иметь любое значение. В байте А16 идут 7 бит нулей и A16 в младшем бите.

спасибо. все наладил, все работает. сейчас думаю об алгоритмике логирования данных.
mantech
Цитата(Jenya7 @ Jun 23 2018, 08:14) *
спасибо. все наладил, все работает. сейчас думаю об алгоритмике логирования данных.


А перед этим еще и об алгоритмике выравнивания износа, раз уж с НАНДом связались...
Alex11
Если это логирование, а не файловая система - то можно обойтись тривиальной записью по кольцу, только не испортить все запиью указателя на конец в одну точку.
Jenya7
пишу на страницу. потом делаю дамп страницы. вижу попадаются битые записи. получается механизм ECC не работает.
aaarrr
Цитата(Jenya7 @ Jul 7 2018, 09:09) *
пишу на страницу. потом делаю дамп страницы. вижу попадаются битые записи. получается механизм ECC не работает.

Скорее с интерфейсом или ПО в очередной раз проблемы. ECC в нормальных условиях "работает" настолько редко, что вероятность увидеть описываемым способом битую запись крайне мала.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.