/** * @brief Initializes the NAND device. * @retval NAND memory status */ uint8_t BSP_NAND_Init(void) { nandHandle.Instance = FSMC_NAND_DEVICE; /*NAND Configuration */ Timing.SetupTime = 0; Timing.WaitSetupTime = 2; Timing.HoldSetupTime = 1; Timing.HiZSetupTime = 0; nandHandle.Init.NandBank = FSMC_NAND_BANK2; nandHandle.Init.Waitfeature = FSMC_NAND_PCC_WAIT_FEATURE_ENABLE; nandHandle.Init.MemoryDataWidth = FSMC_NAND_PCC_MEM_BUS_WIDTH_8; nandHandle.Init.EccComputation = FSMC_NAND_ECC_ENABLE; nandHandle.Init.ECCPageSize = FSMC_NAND_ECC_PAGE_SIZE_512BYTE; nandHandle.Init.TCLRSetupTime = 0; nandHandle.Init.TARSetupTime = 0; nandHandle.Info.BlockNbr = NAND_MAX_ZONE; nandHandle.Info.BlockSize = NAND_BLOCK_SIZE; nandHandle.Info.ZoneSize = NAND_ZONE_SIZE; nandHandle.Info.PageSize = NAND_PAGE_SIZE; nandHandle.Info.SpareAreaSize = NAND_SPARE_AREA_SIZE; /* NAND controller initialization */ NAND_MspInit(); if(HAL_NAND_Init(&nandHandle, &Timing, &Timing) != HAL_OK) { return NAND_ERROR; } else { return NAND_OK; } }
/** * @brief Main program * @param None * @retval None */ int main(void) { /* STM32F103xG HAL library initialization: - Configure the Flash prefetch - Systick timer is configured by default as source of time base, but user can eventually implement his proper time base source (a general purpose timer for example or other time source), keeping in mind that Time base duration should be kept 1ms since PPP_TIMEOUT_VALUEs are defined and handled in milliseconds basis. - Set NVIC Group Priority to 4 - Low Level Initialization */ HAL_Init(); /* Configure LED1, LED2 and LED3 */ BSP_LED_Init(LED1); BSP_LED_Init(LED2); BSP_LED_Init(LED3); /* Configure the system clock to 72 MHz */ SystemClock_Config(); /*##-1- Configure the NAND device ##########################################*/ /* NAND device configuration */ nandHandle.Instance = FSMC_NAND_DEVICE; /*NAND Configuration */ NAND_Timing.SetupTime = 0; NAND_Timing.WaitSetupTime = 2; NAND_Timing.HoldSetupTime = 1; NAND_Timing.HiZSetupTime = 0; nandHandle.Init.NandBank = FSMC_NAND_BANK2; nandHandle.Init.Waitfeature = FSMC_NAND_PCC_WAIT_FEATURE_ENABLE; nandHandle.Init.MemoryDataWidth = FSMC_NAND_PCC_MEM_BUS_WIDTH_8; nandHandle.Init.EccComputation = FSMC_NAND_ECC_ENABLE; nandHandle.Init.ECCPageSize = FSMC_NAND_ECC_PAGE_SIZE_512BYTE; nandHandle.Init.TCLRSetupTime = 0; nandHandle.Init.TARSetupTime = 0; nandHandle.Info.BlockNbr = NAND_MAX_ZONE; nandHandle.Info.BlockSize = NAND_BLOCK_SIZE; nandHandle.Info.ZoneSize = NAND_ZONE_SIZE; nandHandle.Info.PageSize = NAND_PAGE_SIZE; nandHandle.Info.SpareAreaSize = NAND_SPARE_AREA_SIZE; /* Initialize the NAND controller */ if(HAL_NAND_Init(&nandHandle, &NAND_Timing, &NAND_Timing) != HAL_OK) { /* Initialization Error */ Error_Handler(); } /* Read NAND memory ID */ if(HAL_NAND_Read_ID(&nandHandle, &NAND_Id) != HAL_OK) { /* NAND read ID Error */ Error_Handler(); } /* Test the NAND ID correctness */ if((NAND_Id.Maker_Id != NAND_ST_MAKERID) || (NAND_Id.Device_Id != NAND_ST_DEVICEID)) { /* NAND ID not correct */ Error_Handler(); } /*##-2- Convert Address to NAND address#######################################*/ NAND_GetAddress(WRITE_READ_ADDR, &NAND_Address); /*##-3- Erase NAND memory ###################################################*/ if(HAL_NAND_Erase_Block(&nandHandle, &NAND_Address) != HAL_OK) { Error_Handler(); } /*##-4- NAND memory read/write access ######################################*/ /* Fill the buffer to write */ Fill_Buffer(nand_aTxBuffer, BUFFER_SIZE, 0xD210); /* Write data to the NAND memory */ if(HAL_NAND_Write_Page(&nandHandle, &NAND_Address, nand_aTxBuffer, NB_PAGE) != HAL_OK) { Error_Handler(); } /* Read back data from the NAND memory */ if(HAL_NAND_Read_Page(&nandHandle, &NAND_Address, nand_aRxBuffer, NB_PAGE) != HAL_OK) { Error_Handler(); } /*##-3- Checking data integrity ############################################*/ if(Buffercmp(nand_aTxBuffer, nand_aRxBuffer, BUFFER_SIZE) != PASSED) { /* KO */ /* Turn on LED2 */ BSP_LED_On(LED2); } else { /* OK */ /* Turn on LED1 */ BSP_LED_On(LED1); } /* Infinite loop */ while (1) { } }