#include "parallel_nand_port_stm32f407ve.h" #include "stm32f4xx_hal.h" #include "stm32f4xx_hal_nand.h" #define PNAND_F407_BANK2_BASE 0x70000000UL #define PNAND_F407_CMD_AREA (1UL << 16) #define PNAND_F407_ADDR_AREA (1UL << 17) static NAND_HandleTypeDef hnand; static int f407_init(void) { GPIO_InitTypeDef io; FSMC_NAND_PCC_TimingTypeDef common; FSMC_NAND_PCC_TimingTypeDef attribute; __HAL_RCC_GPIOD_CLK_ENABLE(); __HAL_RCC_GPIOE_CLK_ENABLE(); __HAL_RCC_FSMC_CLK_ENABLE(); io.Mode = GPIO_MODE_AF_PP; io.Pull = GPIO_NOPULL; io.Speed = GPIO_SPEED_FREQ_VERY_HIGH; io.Alternate = GPIO_AF12_FSMC; io.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7 | GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_14 | GPIO_PIN_15; HAL_GPIO_Init(GPIOD, &io); io.Pin = GPIO_PIN_7 | GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10; HAL_GPIO_Init(GPIOE, &io); 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_2048BYTE; hnand.Init.TCLRSetupTime = 2U; hnand.Init.TARSetupTime = 2U; common.SetupTime = 2U; common.WaitSetupTime = 5U; common.HoldSetupTime = 3U; common.HiZSetupTime = 2U; attribute = common; return HAL_NAND_Init(&hnand, &common, &attribute) == HAL_OK ? 0 : -1; } static void f407_select(void) { /* FSMC_NCE2 активируется доступом. */ } static void f407_deselect(void) { } static void f407_write_command(pnand_octet_t value) { *(__IO uint8_t *)(PNAND_F407_BANK2_BASE | PNAND_F407_CMD_AREA) = (uint8_t)value; } static void f407_write_address(pnand_octet_t value) { *(__IO uint8_t *)(PNAND_F407_BANK2_BASE | PNAND_F407_ADDR_AREA) = (uint8_t)value; } static void f407_write_data(pnand_octet_t value) { *(__IO uint8_t *)PNAND_F407_BANK2_BASE = (uint8_t)value; } static pnand_octet_t f407_read_data(void) { return *(__IO uint8_t *)PNAND_F407_BANK2_BASE; } static int f407_is_ready(void) { return HAL_GPIO_ReadPin(GPIOD, GPIO_PIN_6) == GPIO_PIN_SET; } static void f407_set_wp(int enabled) { /* WP# аппаратный в базовой схеме. */ (void)enabled; } static void f407_delay_us(unsigned long us) { uint32_t cycles = (SystemCoreClock / 3000000UL) * (uint32_t)us; while (cycles-- != 0U) __NOP(); } static const parallel_nand_port_t f407_port = { f407_init, f407_select, f407_deselect, f407_write_command, f407_write_address, f407_write_data, f407_read_data, f407_is_ready, f407_set_wp, f407_delay_us, 0 }; const parallel_nand_port_t *parallel_nand_port_stm32f407ve(void) { return &f407_port; }