Recently,I am trying to migrate RL-FLASHFS to my board,which is composed stm32f103zet6 and hy27uf081g2a. But I failed. part of code :
/* NAND Page Layout Definition */ //These may be wrong,and I don't know how to change #define ON_POS_LSN 2 #define ON_POS_COR 1 #define ON_POS_BBM 0 #define ON_POS_ECC 8 #define ON_SECT_INC 512 #define ON_SPARE_OFS 2048 #define ON_SPARE_INC 16 /*----------------------------------------------------------------------------- * NAND driver prototypes *----------------------------------------------------------------------------*/ static U32 Init (NAND_DRV_CFG *cfg); static U32 UnInit (NAND_DRV_CFG *cfg); static U32 PageRead (U32 row, U8 *buf, NAND_DRV_CFG *cfg); static U32 PageWrite (U32 row, U8 *buf, NAND_DRV_CFG *cfg); static U32 BlockErase (U32 row, NAND_DRV_CFG *cfg); /*----------------------------------------------------------------------------- NAND Device Driver Control Block *----------------------------------------------------------------------------*/ ...... void NAND_Init(void) { ....... FSMC_NANDCmd(FSMC_Bank2_NAND, ENABLE); } void NAND_DeInit(void) { .... FSMC_NANDCmd(FSMC_Bank2_NAND, DISABLE); } ......... uint32_t NAND_ReadPage(uint32_t Address, uint8_t *pBuffer, NAND_DRV_CFG *cfg) { uint32_t index = 0x00, addressstatus = NAND_VALID_ADDRESS; uint32_t status = NAND_READY, size = 0x00; if(Address++ > (NAND_MAX_ZONE*NAND_ZONE_SIZE*NAND_BLOCK_SIZE)) { addressstatus = NAND_INVALID_ADDRESS; return (addressstatus); } /*!< Page Read command and page address */ *(__IO uint8_t *)(Bank_NAND_ADDR | CMD_AREA) = NAND_CMD_READ0; *(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_1st_CYCLE(Address); *(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_2nd_CYCLE(Address); *(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_3rd_CYCLE(Address); *(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_4th_CYCLE(Address); *(__IO uint8_t *)(Bank_NAND_ADDR | CMD_AREA) = NAND_CMD_READ_TRUE1; /**wait for ready**/ while( GPIO_ReadInputDataBit(GPIOD, GPIO_Pin_6) == 0 ); /*!< Calculate the size */ size = cfg->PageSize; /*!< Get Data into Buffer */ for(; index < size; index++) { pBuffer[index]= *(__IO uint8_t *)(Bank_NAND_ADDR | DATA_AREA); } status = NAND_GetStatus(); return (status | addressstatus); } uint32_t NAND_WritePage(uint32_t Address, uint8_t *pBuffer, NAND_DRV_CFG *cfg) { uint32_t index = 0x00, addressstatus = NAND_VALID_ADDRESS; uint32_t status = NAND_READY, size = 0x00; if(Address++ > (NAND_MAX_ZONE*NAND_ZONE_SIZE*NAND_BLOCK_SIZE)) { addressstatus = NAND_INVALID_ADDRESS; return (addressstatus); } /*!< Page write command and address */ *(__IO uint8_t *)(Bank_NAND_ADDR | CMD_AREA) = NAND_CMD_WRITE0; *(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_1st_CYCLE(Address); *(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_2nd_CYCLE(Address); *(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_3rd_CYCLE(Address); *(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_4th_CYCLE(Address); /*!< Calculate the size */ size = cfg->PageSize; /*!< Write data */ for(; index < size; index++) { *(__IO uint8_t *)(Bank_NAND_ADDR | DATA_AREA) = pBuffer[index]; } *(__IO uint8_t *)(Bank_NAND_ADDR | CMD_AREA) = NAND_CMD_WRITE_TRUE1; /**wait for ready singal**/ while( GPIO_ReadInputDataBit(GPIOD, GPIO_Pin_6) == 0 ); /*!< Check status for successful operation */ status = NAND_GetStatus(); return (status | addressstatus); } uint32_t NAND_EraseBlock(uint32_t Address) { uint32_t data = 0xff, status = NAND_ERROR; *(__IO uint8_t *)(Bank_NAND_ADDR | CMD_AREA) = NAND_CMD_ERASE0; *(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_3rd_CYCLE(Address); *(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_4th_CYCLE(Address); *(__IO uint8_t *)(Bank_NAND_ADDR | CMD_AREA) = NAND_CMD_ERASE1; /* Read status operation ------------------------------------ */ return(NAND_GetStatus()); } static U32 Init (NAND_DRV_CFG *cfg) { cfg->PgLay->Pos_LSN = ON_POS_LSN; cfg->PgLay->Pos_COR = ON_POS_COR; cfg->PgLay->Pos_BBM = ON_POS_BBM; cfg->PgLay->Pos_ECC = ON_POS_ECC; cfg->PgLay->SectInc = ON_SECT_INC; cfg->PgLay->SpareOfs = ON_SPARE_OFS; cfg->PgLay->SpareInc = ON_SPARE_INC; /**/ NAND_Init(); return RTV_NOERR; } static U32 UnInit (NAND_DRV_CFG *cfg) { NAND_DeInit(); return RTV_NOERR; } static U32 PageRead (U32 row, U8 *buf, NAND_DRV_CFG *cfg) { uint32_t status = NAND_READY; /* Determine Chip Select from instance number */ if(cfg->DrvInst == 0) { status = NAND_ReadPage(row, buf, cfg); if(!(status & NAND_READY)) { return ERR_NAND_HW_TOUT; } return RTV_NOERR; } else { return ERR_INVALID_PARAM; } } static U32 PageWrite (U32 row, U8 *buf, NAND_DRV_CFG *cfg) { uint32_t status = NAND_READY; /* Determine Chip Select from instance number */ if(cfg->DrvInst == 0) { status = NAND_WritePage(row, buf, cfg); if(!(status&NAND_READY)) { return ERR_NAND_PROG; } return RTV_NOERR; } else { return ERR_INVALID_PARAM; } } static U32 BlockErase (U32 row, NAND_DRV_CFG *cfg) { uint32_t status = NAND_READY; /* Determine Chip Select from instance number */ if(cfg->DrvInst == 0) { status = NAND_EraseBlock(row); if(status !=NAND_READY) { return ERR_NAND_ERASE; } return RTV_NOERR; } else { return ERR_INVALID_PARAM; } }
Some define and the function NAND_Init()
#define FSMC_Bank_NAND FSMC_Bank2_NAND #define Bank_NAND_ADDR Bank2_NAND_ADDR #define Bank2_NAND_ADDR ((uint32_t)0x70000000) #define NAND_PAGE_SIZE ((u16)0x0800) /* 2K bytes per page w/o Spare Area */ #define NAND_BLOCK_SIZE ((u16)0x0040) /* 64x2K bytes pages per block */ #define NAND_ZONE_SIZE ((u16)0x0400) /* 1024 Block per zone */ #define NAND_SPARE_AREA_SIZE ((u16)0x0040) /* last 64 bytes as spare area */ #define NAND_MAX_ZONE ((u16)0x0001) /* 1 zones of 1024 block */ /** * @brief FSMC NAND memory address computation */ #define ADDR_1st_CYCLE(PADDR) (uint8_t)(0x0) /* 1st addressing cycle */ #define ADDR_2nd_CYCLE(PADDR) (uint8_t)(0x0) /* 2nd addressing cycle */ #define ADDR_3rd_CYCLE(PADDR) (uint8_t)(PADDR & 0xFF) /* 3rd addressing cycle */ #define ADDR_4th_CYCLE(PADDR) (uint8_t)((PADDR>>8) & 0xFF) /* 4th addressing cycle */ /* FSMC NAND memory data computation */ #define DATA_1st_CYCLE(DATA) (uint8_t)((DATA)& 0xFF) /* 1st data cycle */ #define DATA_2nd_CYCLE(DATA) (uint8_t)(((DATA)& 0xFF00) >> 8) /* 2nd data cycle */ #define DATA_3rd_CYCLE(DATA) (uint8_t)(((DATA)& 0xFF0000) >> 16) /* 3rd data cycle */ #define DATA_4th_CYCLE(DATA) (uint8_t)(((DATA)& 0xFF000000) >> 24) /* 4th data cycle */ void NAND_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; FSMC_NAND_PCCARDTimingInitTypeDef p; FSMC_NANDInitTypeDef FSMC_NANDInitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOE, ENABLE); RCC_AHBPeriphClockCmd(RCC_AHBPeriph_FSMC,ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14 | GPIO_Pin_15 | GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_7 | GPIO_Pin_11 | GPIO_Pin_12; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_Init(GPIOD, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 GPIO_Init(GPIOE, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; GPIO_Init(GPIOD, &GPIO_InitStructure); p.FSMC_SetupTime = 0x1; p.FSMC_WaitSetupTime = 0x3; p.FSMC_HoldSetupTime = 0x2; p.FSMC_HiZSetupTime = 0x1; FSMC_NANDInitStructure.FSMC_Bank = FSMC_Bank2_NAND; FSMC_NANDInitStructure.FSMC_Waitfeature = FSMC_Waitfeature_Enable; FSMC_NANDInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_8b; FSMC_NANDInitStructure.FSMC_ECC = FSMC_ECC_Enable; FSMC_NANDInitStructure.FSMC_ECCPageSize = FSMC_ECCPageSize_2048Bytes; FSMC_NANDInitStructure.FSMC_TCLRSetupTime = 0x00; //CLE low to RE low FSMC_NANDInitStructure.FSMC_TARSetupTime = 0x00; //ALE low to RE low FSMC_NANDInitStructure.FSMC_CommonSpaceTimingStruct = &p; FSMC_NANDInitStructure.FSMC_AttributeSpaceTimingStruct = &p; FSMC_NANDInit(&FSMC_NANDInitStructure); FSMC_NANDCmd(FSMC_Bank2_NAND, ENABLE); }