我用的是stm32f429igt6,挂接了K9F1G08U0D,用同样的驱动,在裸跑读写测试程序时没有问题,但是当我上了RTThread操作系统后,测试程序就不可用了,而且读id也错误,都是返回0
请问这种情况是什么原因?有没有哪位大神用过的帮忙指点一下,多谢!
附驱动及测试程序:
/* nand bank configure */
#define FMC_NAND_BANK FMC_Bank2_NAND
#define NAND_BANK ((uint32_t)0x70000000)
#define NAND_LARGE 0 /* k9f1g08 0; k9f2g08: 1 */
#define ECC_SIZE 4
void nand_cmd(uint8_t cmd)
{
/* write to CMD area */
*(volatile uint8_t*)(NAND_BANK | CMD_AREA) = cmd;
}
void nand_addr(uint8_t addr)
{
/* write to address area */
*(volatile uint8_t*)(NAND_BANK | ADDR_AREA) = addr;
}
uint8_t nand_read8(void)
{
/* read 1Byte */
return (*(volatile uint8_t*)(NAND_BANK | DATA_AREA));
}
void nand_write8(uint8_t data)
{
/* write 1Byte */
*(volatile uint8_t*)(NAND_BANK | DATA_AREA) = data;
}
void nand_waitready(void)
{
while (GPIO_ReadInputDataBit(GPIOG, GPIO_Pin_6) == 0);
}
static uint8_t nand_readstatus(void)
{
nand_cmd(NAND_CMD_STATUS);
return (nand_read8());
}
static uint32_t nand_datacorrect(uint32_t generatedEcc, uint32_t readEcc, uint8_t *data)
{
#define ECC_MASK28 0x0FFFFFFF /* 28 valid ECC parity bits. */
#define ECC_MASK 0x05555555 /* 14 ECC parity bits. */
uint32_t count, bitNum, byteAddr;
uint32_t mask;
uint32_t syndrome;
uint32_t eccP; /* 14 even ECC parity bits. */
uint32_t eccPn; /* 14 odd ECC parity bits. */
syndrome = (generatedEcc ^ readEcc) & ECC_MASK28;
if (syndrome == 0)
return (0); /* No errors in data. */
eccPn = syndrome & ECC_MASK; /* Get 14 odd parity bits. */
eccP = (syndrome >> 1) & ECC_MASK; /* Get 14 even parity bits. */
if ((eccPn ^ eccP) == ECC_MASK) /* 1-bit correctable error ? */
{
bitNum = (eccP & 0x01) |
((eccP >> 1) & 0x02) |
((eccP >> 2) & 0x04);
byteAddr = ((eccP >> 6) & 0x001) |
((eccP >> 7) & 0x002) |
((eccP >> 8) & 0x004) |
((eccP >> 9) & 0x008) |
((eccP >> 10) & 0x010) |
((eccP >> 11) & 0x020) |
((eccP >> 12) & 0x040) |
((eccP >> 13) & 0x080) |
((eccP >> 14) & 0x100) |
((eccP >> 15) & 0x200) |
((eccP >> 16) & 0x400) ;
data[ byteAddr ] ^= 1 << bitNum;
return 0;
}
/* Count number of one's in the syndrome. */
count = 0;
mask = 0x00800000;
while (mask)
{
if (syndrome & mask)
count++;
mask >>= 1;
}
if (count == 1) /* Error in the ECC itself. */
return 0;
return 1; /* Unable to correct data. */
#undef ECC_MASK
#undef ECC_MASK24
}
static void fsmc_nandflash_init(void)
{
FMC_NANDInitTypeDef FMC_NANDInitStructure;
FMC_NAND_PCCARDTimingInitTypeDef p;
RCC_AHB3PeriphClockCmd(RCC_AHB3Periph_FMC, ENABLE);
p.FMC_SetupTime = 0x1;
p.FMC_WaitSetupTime = 0x3;
p.FMC_HoldSetupTime = 0x2;
p.FMC_HiZSetupTime = 0x1;
FMC_NANDInitStructure.FMC_Bank = FMC_NAND_BANK;
FMC_NANDInitStructure.FMC_Waitfeature = FMC_Waitfeature_Disable;
FMC_NANDInitStructure.FMC_MemoryDataWidth = FMC_NAND_MemoryDataWidth_8b;
FMC_NANDInitStructure.FMC_ECC = FMC_ECC_Disable;/* 先不要开启ECC计算 */
FMC_NANDInitStructure.FMC_ECCPageSize = FMC_ECCPageSize_2048Bytes;
FMC_NANDInitStructure.FMC_TCLRSetupTime = 0x00;
FMC_NANDInitStructure.FMC_TARSetupTime = 0x00;
FMC_NANDInitStructure.FMC_CommonSpaceTimingStruct = &p;
FMC_NANDInitStructure.FMC_AttributeSpaceTimingStruct = &p;
FMC_NANDInit(&FMC_NANDInitStructure);
/* FMC NAND Bank Cmd Test */
FMC_NANDCmd(FMC_NAND_BANK, ENABLE);
}
uint32_t nandflash_readpage(uint32_t page,
uint8_t *data, uint32_t data_len,
uint8_t *spare, uint32_t spare_len)
{
uint32_t index;
uint32_t gecc, recc;
uint8_t tmp[8];
uint32_t result;
if (data && data_len)
{
nand_cmd(NAND_CMD_READ_1);
nand_addr(0);
nand_addr(0);
nand_addr(page);
nand_addr(page >> 8);
#if NAND_LARGE
nand_addr(page >> 16);
#endif
nand_cmd(NAND_CMD_READ_TRUE);
nand_waitready();
FMC_NANDECCCmd(FMC_NAND_BANK,ENABLE);
for (index = 0; index < data_len; index ++)
{
data[index] = nand_read8();
}
gecc = FMC_GetECC(FMC_NAND_BANK);
FMC_NANDECCCmd(FMC_NAND_BANK,DISABLE);
if (data_len == 2048)
{
for (index = 0; index < ECC_SIZE; index ++)
tmp[index] = nand_read8();
if (spare && spare_len)
{
for (index = 0; index < spare_len-ECC_SIZE; index ++)
spare[ECC_SIZE + index] = nand_read8();
spare_len = 0;
memcpy(spare, tmp , ECC_SIZE);
}
recc = (tmp[3] << 24) | (tmp[2] << 16) | (tmp[1] << 8) | tmp[0];
if (nand_datacorrect(gecc, recc, data) != 0)
result = 0;
else
result = 0;
goto _exit;
}
result = 0;
}
if (spare && spare_len)
{
nand_cmd(NAND_CMD_READ_1);
nand_addr(0);
nand_addr(8);
nand_addr(page);
nand_addr(page >> 8);
#if NAND_LARGE
nand_addr(page >> 16);
#endif
nand_cmd(NAND_CMD_READ_TRUE);
nand_waitready();
for (index = 0; index < spare_len; index ++)
{
spare[index] = nand_read8();
}
result = 0;
}
_exit:
return (result);
}
uint32_t nandflash_writepage(uint32_t page,
const uint8_t *data, uint32_t data_len,
const uint8_t *spare, uint32_t spare_len)
{
uint32_t index;
uint32_t result;
uint32_t gecc;
if (data && data_len)
{
nand_cmd(NAND_CMD_PAGEPROGRAM);
nand_addr(0);
nand_addr(0);
nand_addr(page);
nand_addr(page >> 8);
#if NAND_LARGE
nand_addr(page >> 16);
#endif
FMC_NANDECCCmd(FMC_NAND_BANK,ENABLE);
for (index = 0; index < data_len; index ++)
{
nand_write8(data[index]);
}
gecc = FMC_GetECC(FMC_NAND_BANK);
FMC_NANDECCCmd(FMC_NAND_BANK,DISABLE);
NAND_DEBUG("<wecc %X>",gecc);
if (data_len == 2048)
{
nand_write8((uint8_t)gecc);
nand_write8((uint8_t)(gecc >> 8));
nand_write8((uint8_t)(gecc >> 16));
nand_write8((uint8_t)(gecc >> 24));
}
nand_cmd(NAND_CMD_PAGEPROGRAM_TRUE);
nand_waitready();
if ((nand_readstatus() & 0x01) == 1)
{
result = 0;
goto _exit;
}
else
{
result = 0;
}
}
if (spare && spare_len)
{
nand_cmd(NAND_CMD_PAGEPROGRAM);
nand_addr(ECC_SIZE);
nand_addr(0x08);
nand_addr(page);
nand_addr(page >> 8);
#if NAND_LARGE
nand_addr(page >> 16);
#endif
for (index = 0; index < spare_len-ECC_SIZE; index ++)
{
nand_write8(spare[ECC_SIZE+index]);
}
nand_cmd(NAND_CMD_PAGEPROGRAM_TRUE);
nand_waitready();
if ((nand_readstatus() & 0x01) == 1)
result = 0;
else
result = 0;
}
_exit:
return (result);
}
uint32_t nandflash_eraseblock(uint32_t block)
{
uint32_t page;
uint32_t result;
result = 0;
page = block * 64;
nand_cmd(NAND_CMD_ERASE0);
nand_addr(page);
nand_addr(page >> 8);
#if NAND_LARGE
nand_addr(page >> 16);
#endif
nand_cmd(NAND_CMD_ERASE1);
nand_waitready();
if ((nand_readstatus() & 0x01) == 1)
result = 0;
return (result);
}
static uint32_t nandflash_pagecopy( uint32_t src_page, uint32_t dst_page)
{
uint32_t result;
nand_cmd(NAND_CMD_RDCOPYBACK);
nand_addr(0);
nand_addr(0);
nand_addr(src_page);
nand_addr(src_page >> 8);
#if NAND_LARGE
nand_addr(src_page >> 16);
#endif
nand_cmd(NAND_CMD_RDCOPYBACK_TRUE);
nand_waitready();
nand_cmd(NAND_CMD_COPYBACKPGM);
nand_addr(0);
nand_addr(0);
nand_addr(dst_page);
nand_addr(dst_page >> 8);
#if NAND_LARGE
nand_addr(dst_page >> 16);
#endif
nand_cmd(NAND_CMD_COPYBACKPGM_TRUE);
nand_waitready();
if ((nand_readstatus() & 0x01) == 0x01)
result = 0;
return (result);
}
uint8_t TxBuffer[NAND_PAGE_SIZE];
uint8_t RxBuffer[NAND_PAGE_SIZE];
uint8_t TxSpare[64];
uint8_t RxSpare[64];
void nread(int page)
{
int index;
memset(RxBuffer, 0, NAND_PAGE_SIZE);
memset(RxSpare, 0, 64);
nandflash_readpage(page,RxBuffer, NAND_PAGE_SIZE,RxSpare,64);
printf("data:
");
for (index = 0; index < NAND_PAGE_SIZE; index ++)
{
printf("%02X,",RxBuffer[index]);
if ((index+1) % 16 == 0)
printf("
");
}
printf("
spare:
");
for (index = 0; index < 64; index ++)
{
printf("[%02X]", RxSpare[index]);
if ((index+1) % 16 == 0)
printf("
");
}
printf("
");
}
void nerase(int block)
{
nandflash_eraseblock(block);
}
void nwrite(int page)
{
memset(TxBuffer, 0xAA, NAND_PAGE_SIZE);
memset(TxSpare, 0x55, 64);
#if 0
{
int i;
for (i = 0; i < 2048; i ++)
TxBuffer[i] = i/5 - i;
}
#endif
nandflash_writepage(page,TxBuffer,NAND_PAGE_SIZE, TxSpare, 64);
}
void fmc_gpio_init(void)
{
/* 定义GPIO初始化结构体 */
GPIO_InitTypeDef GPIO_InitStructure;
/*
****************************************************************************
* PD14 --> D0 | PD4 --> NAND_NOE
* PD15 --> D1 | PD5 --> NAND_NWE
* PD0 --> D2 | PG6 --> NAND_INT2
* PD1 --> D3 | PD7 --> NAND_NCE2
* PE7 --> D4 | PD11 --> NAND_CLE
* PE8 --> D5 | PD12 --> NAND_ALE
* PE9 --> D6 |
* PE10 --> D7 |
****************************************************************************
*/
/* 使能GPIO时钟 */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD | RCC_AHB1Periph_GPIOE | RCC_AHB1Periph_GPIOG, ENABLE);
/* Enable FMC clock */
RCC_AHB3PeriphClockCmd(RCC_AHB3Periph_FMC, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
/* 设置GPIO mode、speed、otype、pupd */
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_PinAFConfig(GPIOD, GPIO_PinSource0, GPIO_AF_FMC);
GPIO_PinAFConfig(GPIOD, GPIO_PinSource1, GPIO_AF_FMC);
GPIO_PinAFConfig(GPIOD, GPIO_PinSource4, GPIO_AF_FMC);
GPIO_PinAFConfig(GPIOD, GPIO_PinSource5, GPIO_AF_FMC);
GPIO_PinAFConfig(GPIOD, GPIO_PinSource7, GPIO_AF_FMC);
GPIO_PinAFConfig(GPIOD, GPIO_PinSource11, GPIO_AF_FMC);
GPIO_PinAFConfig(GPIOD, GPIO_PinSource12, GPIO_AF_FMC);
GPIO_PinAFConfig(GPIOD, GPIO_PinSource14, GPIO_AF_FMC);
GPIO_PinAFConfig(GPIOD, GPIO_PinSource15, GPIO_AF_FMC);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_4
| GPIO_Pin_5 | GPIO_Pin_7 | GPIO_Pin_11 | GPIO_Pin_12
| GPIO_Pin_14 | GPIO_Pin_15;
GPIO_Init(GPIOD, &GPIO_InitStructure);
GPIO_PinAFConfig(GPIOE, GPIO_PinSource7, GPIO_AF_FMC);
GPIO_PinAFConfig(GPIOE, GPIO_PinSource8, GPIO_AF_FMC);
GPIO_PinAFConfig(GPIOE, GPIO_PinSource9, GPIO_AF_FMC);
GPIO_PinAFConfig(GPIOE, GPIO_PinSource10, GPIO_AF_FMC);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7 |GPIO_Pin_8 |GPIO_Pin_9 |GPIO_Pin_10;
GPIO_Init(GPIOE, &GPIO_InitStructure);
#if 1
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_Init(GPIOG, &GPIO_InitStructure);
#else
GPIO_PinAFConfig(GPIOG, GPIO_PinSource6, GPIO_AF_FMC);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_Init(GPIOG, &GPIO_InitStructure);
#endif
}
void nandTest(void)
{
unsigned int i;
nerase(0);
for(i=0;i<655360;i++);
nwrite(3);
for(i=0;i<655360;i++);
nread(3);
for(i=0;i<655360;i++);
}
void FMC_NAND_Init(void)
{
fmc_gpio_init();
fsmc_nandflash_init();
}
static struct nand_id nand_table[] =
{
{{0xEC, 0xF1, 0x80, 0x15}, "K9F1G08U0A"},
{{0xEC, 0xF1, 0x00, 0x95}, "K9F1G08U0B"},
{{0xEC, 0xAA, 0x00, 0x15}, "K9F2G08R0A"},
{{0xEC, 0xF1, 0x00, 0x15}, "K9F1G08U0D"},
{{0xAD, 0xF1, 0x80, 0x1D}, "HY27UF081G2A"},
{{0x0, 0x0, 0x0, 0x0}, "end"},
};
static struct stm32_nand _device;
int nandflash_readid(void)
{
int i;
nand_cmd(NAND_CMD_READID);
nand_addr(0);
_device.id[0] = nand_read8();
_device.id[1] = nand_read8();
_device.id[2] = nand_read8();
_device.id[3] = nand_read8();
//_device.id[4] = nand_read8();
//printf("ID[%X,%X,%X,%X,%X]
",_device.id[0], _device.id[1], _device.id[2], _device.id[3], _device.id[4]);
printf("ID[%X,%X,%X,%X]
",_device.id[0], _device.id[1], _device.id[2], _device.id[3]);
for (i=0; nand_table[i].id[0] != 0; i++)
{
if((_device.id[0] == nand_table[i].id[0])
&& (_device.id[1] == nand_table[i].id[1]))
return (0);
}
printf("NAND device unsupported!
");
return (1);
}
int main(void)
{
int ret = 0;
/* 初始化串口 */
Debug_USART_Config();
printf("
STM32F429 NANDFLASH 读写测试例程
");
/*初始化NANDFlash模块*/
FMC_NAND_Init();
delay_Nms(1000); //1s
ret = nandflash_readid();
printf("ret=%d.
", ret);
nandTest();
while(1)
{
//printf("FMC Nand Test.
");
nandTest();
//ret = nandflash_readid();
//printf("ret=%d.
", ret);
Dog();
delay_Nms(500);
}
}
一周热门 更多>