|
|
  |
Подключение Nand Flash к stm32 |
|
|
|
Dec 15 2015, 18:08
|
Группа: Участник
Сообщений: 9
Регистрация: 8-12-15
Пользователь №: 89 623

|
Подключил and flash Samsung K9G1G08U0D по FSMC к stm. Настроил пины и хэндлер, используя HAL библиотеку пытаюсь прочитать ID девайса, на что функция возвращает все 0 (то есть Marker_id, Device_id и тд равны 0), судя по документации, я должен получать Marker_Id = 0xEC, Device_Id=0xF1 вот пример кода CODE NAND_HandleTypeDef hnand;
void initNand(void) { HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_0); HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
initNandGPIO(); initNandHandler(); }
void initNandGPIO(void) { GPIO_InitTypeDef GPIO_InitStruct;
__GPIOE_CLK_ENABLE(); __GPIOD_CLK_ENABLE();
GPIO_InitStruct.Pin = GPIO_PIN_7 | GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_HIGH; GPIO_InitStruct.Alternate = GPIO_AF12_FSMC; HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_14 | GPIO_PIN_15 | GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_7; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_HIGH; GPIO_InitStruct.Alternate = GPIO_AF12_FSMC; HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
HAL_NVIC_SetPriority(FSMC_IRQn, 0, 0); HAL_NVIC_EnableIRQ(FSMC_IRQn); }
void initNandHandler(void) { FSMC_NAND_PCC_TimingTypeDef ComSpaceTiming; FSMC_NAND_PCC_TimingTypeDef AttSpaceTiming;
hnand.Instance = FSMC_NAND_DEVICE; hnand.Init.NandBank = FSMC_NAND_BANK2; hnand.Init.Waitfeature = FSMC_NAND_PCC_WAIT_FEATURE_DISABLE; hnand.Init.MemoryDataWidth = FSMC_NAND_PCC_MEM_BUS_WIDTH_8; hnand.Init.EccComputation = FSMC_NAND_ECC_DISABLE; hnand.Init.ECCPageSize = FSMC_NAND_ECC_PAGE_SIZE_256BYTE; hnand.Init.TCLRSetupTime = 0; hnand.Init.TARSetupTime = 0; ComSpaceTiming.SetupTime = 252; ComSpaceTiming.WaitSetupTime = 252; ComSpaceTiming.HoldSetupTime = 252; ComSpaceTiming.HiZSetupTime = 252; AttSpaceTiming.SetupTime = 252; AttSpaceTiming.WaitSetupTime = 252; AttSpaceTiming.HoldSetupTime = 252; AttSpaceTiming.HiZSetupTime = 252;
HAL_NAND_Init(&hnand, &ComSpaceTiming, &AttSpaceTiming); }
void FSMC_IRQHandler(void) { HAL_NAND_IRQHandler(&hnand); }
void readId(void) { NAND_IDTypeDef NAND_ID; char buf[100];
if (HAL_NAND_Read_ID(&hnand, &NAND_ID) == HAL_OK) { sprintf(buf, "Nand Flash ID = %02X,%02X,%02X,%02X\n",NAND_ID.Maker_Id, NAND_ID.Device_Id, NAND_ID.Third_Id, NAND_ID.Fourth_Id); print(buf); } }
|
|
|
|
|
Dec 16 2015, 09:50
|
Группа: Участник
Сообщений: 9
Регистрация: 8-12-15
Пользователь №: 89 623

|
С Id разобрался, теперь выдает такой ID Nand Flash ID = 6B,4A,00,08 Что разнится с ID по документации Попробовал писать и читать страницы, все пишется и читается, но вот проблема теперь в том, что если я пишу, например "How are you?", то при чтении получаю "ow are you?" То есть при записи происходит смешение индекса Если записать строку побольше, то смещение тоже увеличивается, например подставлял фразу "Open On-Chip Debugger: OpenOCD User's Guide", вывело "Chip Debugger: OpenOCD User's Guide" Перед записью очищаю весь блок Код для чтения, записи и erase CODE void eraseBlock() { WriteReadAddr.Zone = 0x00; WriteReadAddr.Block = 0x00; WriteReadAddr.Page = 0x00;
HAL_NAND_Erase_Block(&hnand, &WriteReadAddr); }
void writePage(uint8_t *TxBuffer) { HAL_NAND_Write_Page(&hnand, &WriteReadAddr, TxBuffer, 1); print("Data has been written \r\n"); }
#define NAND_PAGE_SIZE ((uint16_t)0x0800) void readPage() { uint8_t RxBuffer [NAND_PAGE_SIZE]; HAL_NAND_Read_Page (&hnand, &WriteReadAddr, RxBuffer, 1); print("Read data \r\n"); char buf[100]; sprintf(buf, "%s ", RxBuffer); print(buf); }
Сообщение отредактировал Klaxons - Dec 16 2015, 09:51
|
|
|
|
|
Dec 16 2015, 13:46
|
Группа: Участник
Сообщений: 9
Регистрация: 8-12-15
Пользователь №: 89 623

|
Цитата(jcxz @ Dec 16 2015, 15:29)  Да у Вас и здесь "and flash Samsung K9G1G08U0D" хотя наверное должно быть что-то другое. Может проблема в этом?  Судя по маркировки у меня K9F1G08U0E, согласно документации маркер id должен быть равен EC, а девайс ID = f1 Причем иногда он у меня меняется
|
|
|
|
|
Dec 16 2015, 14:32
|
Группа: Участник
Сообщений: 9
Регистрация: 8-12-15
Пользователь №: 89 623

|
Цитата(scifi @ Dec 16 2015, 16:55)  Меняется? Я бы назвал это "плавающие биты". Наиболее вероятная причина - неправильная времянка доступа к памяти. Имеется ввиду этот блок? CODE /* ComSpaceTiming */ ComSpaceTiming.SetupTime = 252; ComSpaceTiming.WaitSetupTime = 252; ComSpaceTiming.HoldSetupTime = 252; ComSpaceTiming.HiZSetupTime = 252; /* AttSpaceTiming */ AttSpaceTiming.SetupTime = 252; AttSpaceTiming.WaitSetupTime = 252; AttSpaceTiming.HoldSetupTime = 252; AttSpaceTiming.HiZSetupTime = 252;
|
|
|
|
|
Dec 17 2015, 19:37
|
Группа: Участник
Сообщений: 9
Регистрация: 8-12-15
Пользователь №: 89 623

|
В документации к микроконтроллеру данные формулы для расчета времени доступа к памяти Код (SET + 1) x tHCLK >= max (tCS, tCLS, tALS, tCLR, tAR) - tWP
(WAIT + 1) x tHCLK >= max (tWP,tRP)
(HIZ + 1) x tHCLK >= max(tCS, tALS, tCLS) + (tWP - tDS)
(HOLD + 1) x tHCLK >= max (tCH, tCLH, tALH)
((WAIT+1)+(HOLD+1)+(SET+1))xtHCLK >= max(tWC/RC) Только не понятно, max - это максимальное значение из перечисленных параметром или сумма всех параметров? И еще не ясно как рассчитать tHCLK, использую контроллер stm32v407vg, тактируюсь от внешнего кварца на 8МГц, HCLK = 168МГц. Еще выяснил, что данные которые я писал, писал их не на внешние nand flash, а в память микроконтроллера, выяснилось это, когда выдернул флешку из контроллера, запустил код, а он все-равно читает какие-то данные. Теперь еще вопрос встал, как эти данные удалить, прошивал контроллер другой программой, потом снова этой и данные на месте. Функция eraseBlock и eraseAllBlocks(), листинг которых ниже также не дали результата. Ну и вопрос все же как "подружиться" с внешней памятью, пины настроил, сам handler fsmc инициализировал, обращаюсь по адресу 0x70000000, пишу и читаю блок 0, страницу 0 и начиная с 0 байта Код WriteReadAddr.Zone = 0x00; WriteReadAddr.Block = 0x00; WriteReadAddr.Page = 0x00; CODE void eraseBlock() { WriteReadAddr.Zone = 0x00; WriteReadAddr.Block = 0x00; WriteReadAddr.Page = 0x00; HAL_NAND_Erase_Block(&hnand, &WriteReadAddr); }
void eraseAllBlocks() { uint16_t i,j; for (i = 0x00; i<NAND_ZONE_SIZE; i++) { for (j=0x00; j<NAND_BLOCK_SIZE; j++) { WriteReadAddr.Zone = 0x00; WriteReadAddr.Block = i; WriteReadAddr.Page = j; HAL_NAND_Erase_Block(&hnand, &WriteReadAddr); } } }
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|