Перейти к содержанию

    

Работа с NAND FLASH.

При обращении к памяти (чтение, запись) я передаю адрес (на картинке)

Скажем при стирании блока (на картинке) - я должен передать адрес блока – 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;

получается так ?

post-71075-1529384521_thumb.png

post-71075-1529384535_thumb.png

Изменено пользователем Jenya7

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Про какую NAND речь-то идет? Мы все опять догадываться должны?

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Про какую NAND речь-то идет? Мы все опять догадываться должны?

TC58CVG2S0HxAIx.

 

Скажем я хочу стереть блок

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 );

Я правильно понимаю процесс?

TC58CVG2S0HxAIx_Rev1.1_2016_11_08.pdf

Изменено пользователем IgorKossak
[codebox] для длинного кода. [code]-для короткого!!!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

У Вас же все черным по белому в DS написано. Для стирания нужно подать команду write enable - передать байт 0x06 с установленным CS, затем снять CS, подать команду стирания блока - установить обратно CS, передать последовательно байты 0xD8, A16, A15-A8, A7-A0, снять CS. Затем командой get feature проверить результат. В адресе используются только биты 16-6, остальные биты могут иметь любое значение. В байте А16 идут 7 бит нулей и A16 в младшем бите.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
У Вас же все черным по белому в DS написано. Для стирания нужно подать команду write enable - передать байт 0x06 с установленным CS, затем снять CS, подать команду стирания блока - установить обратно CS, передать последовательно байты 0xD8, A16, A15-A8, A7-A0, снять CS. Затем командой get feature проверить результат. В адресе используются только биты 16-6, остальные биты могут иметь любое значение. В байте А16 идут 7 бит нулей и A16 в младшем бите.

спасибо. все наладил, все работает. сейчас думаю об алгоритмике логирования данных.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
спасибо. все наладил, все работает. сейчас думаю об алгоритмике логирования данных.

 

А перед этим еще и об алгоритмике выравнивания износа, раз уж с НАНДом связались...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Если это логирование, а не файловая система - то можно обойтись тривиальной записью по кольцу, только не испортить все запиью указателя на конец в одну точку.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

пишу на страницу. потом делаю дамп страницы. вижу попадаются битые записи. получается механизм ECC не работает.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
пишу на страницу. потом делаю дамп страницы. вижу попадаются битые записи. получается механизм ECC не работает.

Скорее с интерфейсом или ПО в очередной раз проблемы. ECC в нормальных условиях "работает" настолько редко, что вероятность увидеть описываемым способом битую запись крайне мала.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Для публикации сообщений создайте учётную запись или авторизуйтесь

Вы должны быть пользователем, чтобы оставить комментарий

Создать учетную запись

Зарегистрируйте новую учётную запись в нашем сообществе. Это очень просто!

Регистрация нового пользователя

Войти

Уже есть аккаунт? Войти в систему.

Войти
Авторизация