cancel
Showing results for 
Search instead for 
Did you mean: 

Writing to External Flash

siddj
Associate II
Posted on May 15, 2009 at 14:40

Writing to External Flash

3 REPLIES 3
siddj
Associate II
Posted on May 17, 2011 at 12:53

I am writing to external flash using STM32F103. I am trying to understand the FSMC_NAND example in the sample code library of FW LIB. I am stuck at the following code/functions.

/* FSMC NAND memory address computation */

#define ADDR_1st_CYCLE(ADDR) (u8)((ADDR)& 0xFF) /* 1st addressing cycle */

#define ADDR_2nd_CYCLE(ADDR) (u8)(((ADDR)& 0xFF00) >> 8) /* 2nd addressing cycle */

#define ADDR_3rd_CYCLE(ADDR) (u8)(((ADDR)& 0xFF0000) >> 16) /* 3rd addressing cycle */

#define ADDR_4th_CYCLE(ADDR) (u8)(((ADDR)& 0xFF000000) >> 24) /* 4th addre

It takes four address cycles to write to this 512Mb chip. Can someone please explain to me why aretheir shifts in the 2nd,3rd,and 4th cycle.

Also ADDR is not defined anywhere, in terms of syntax, what does it mean?

u32 FSMC_NAND_ReadSmallPage(u8 *pBuffer, NAND_ADDRESS Address, u32 NumPageToRead)

{

u32 index = 0x00, numpageread = 0x00, addressstatus = NAND_VALID_ADDRESS;

u32 status = NAND_READY, size = 0x00;

while((NumPageToRead != 0x0) && (addressstatus == NAND_VALID_ADDRESS))

{

/* Page Read command and page address */

*(vu8 *)(Bank_NAND_ADDR | CMD_AREA) = NAND_CMD_AREA_A;

*(vu8 *)(Bank_NAND_ADDR | ADDR_AREA) = 0x00;

*(vu8 *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_1st_CYCLE(ROW_ADDRESS);

*(vu8 *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_2nd_CYCLE(ROW_ADDRESS);

*(vu8 *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_3rd_CYCLE(ROW_ADDRESS);

*(vu8 *)(Bank_NAND_ADDR | CMD_AREA) = NAND_CMD_AREA_TRUE1;

/* Calculate the size */

size = NAND_PAGE_SIZE + (NAND_PAGE_SIZE * numpageread);

/* Get Data into Buffer */

for(; index < size; index++)

{

pBuffer[index]= *(vu8 *)(Bank_NAND_ADDR | DATA_AREA);

}

numpageread++;

NumPageToRead--;

Definitions:

#define NAND_CMD_AREA_A ((u8)0x00)

#define CMD_AREA (u32)(1<

#define ADDR_AREA (u32)(1<

/* FSMC NAND memory parameters */

#define NAND_PAGE_SIZE ((u16)0x0200) /* 512 bytes per page w/o Spare Area */

#define NAND_BLOCK_SIZE ((u16)0x0020) /* 32x512 bytes pages per block */

#define NAND_ZONE_SIZE ((u16)0x0400) /* 1024 Block per zone */

#define NAND_SPARE_AREA_SIZE ((u16)0x0010) /* last 16 bytes as spare area */

#define NAND_MAX_ZONE ((u16)0x0004) /* 4 zones of 1024 block */

In this code it reads a page. Again ''ROW_ADDRESS'' is not defined anywhere. Can someone please explain the syntax. Also the ''or'' operator keeps on beating me. What does it exactly do when you are equating it to another variable or constant?

Please,please help! If you need more info I will gladly provide it.

dimasusl
Associate II
Posted on May 17, 2011 at 12:53

ROW_ADDRESS is defined in fsmc_nand.c file

#define ROW_ADDRESS (Address.Page + (Address.Block + (Address.Zone * NAND_ZONE_SIZE)) * NAND_BLOCK_SIZE)

jpeacock2
Associate II
Posted on May 17, 2011 at 12:53

>> It takes four address cycles to write to this 512Mb chip. Can someone please explain to me why aretheir shifts in the 2nd,3rd,and 4th cycle.

Assuming you are looking at a eval kit with the STM NAND512W3A2CN6 memory, this part is an 8-bit part, so the 32-bit address of the block in the NAND chip has to be written in four cycles, shifting an 8 bit section into the low 8 bits before writing to the FSMC data bus.