Multiple flash devices under one driver ?

Hi,

We have two similar 8 MB AMD am29LV flash on our board, each with a 16 bit
bus width, which we would like to have appear as a single array of 16 MB.
Ultimately, the goal is that there is a single mount point for the entire 16
MB block and is available as a filesystem. I am looking for the fastest
possible way in which we can accomodate this.

Looking at the AMD mtd libraries that come with the 6.1 BSPs, with a minor
tweak, I should be able to use the am29f100s service routines for each of
the 8MB part however, I am not sure how to address the two devices as a
single array. Do I need to write a layer on top of the service routines
that calls these routine twice (in serial) to act on each of the two flash
devices ? Also, I am not looking for data redundancy between the two
devices so I guess I can’t serially issue two read/write commands to each of
the devices and have both of them read/write the same data.

Would appreciate any feedback I can get. We are using QNX 6.1 for our
development.

Thanks

  • Murtaza

Now, if the physical address of both chips are contiguous… the
auto-probe will figure it all out for you. If not, just tweak the “page”
routine so it looks like:

uint8_t *page (f3s_socket_t *socket, uint32_t flags, uint32_t offset,
int32_t *size)
{
if (offset < 8MB) return (window1 + offset);
else if (offset < 16MB) return (window2 + offset - 8MB);

errno = ERANGE;
return (NULL);
}

If this is a custom driver, you can even hard-wire the addresses
(easiest way but sloppy). Don’t forget to make the socket “open” routine
allocate both windows.

A “nicer” way is to find somewhere to hold the pointer to the second
window, or make socket->address point to an array of window pointers or
something. You get the picture.

Daryl Low

Murtaza wrote:

Hi,

We have two similar 8 MB AMD am29LV flash on our board, each with a 16 bit
bus width, which we would like to have appear as a single array of 16 MB.
Ultimately, the goal is that there is a single mount point for the entire 16
MB block and is available as a filesystem. I am looking for the fastest
possible way in which we can accomodate this.

Looking at the AMD mtd libraries that come with the 6.1 BSPs, with a minor
tweak, I should be able to use the am29f100s service routines for each of
the 8MB part however, I am not sure how to address the two devices as a
single array. Do I need to write a layer on top of the service routines
that calls these routine twice (in serial) to act on each of the two flash
devices ? Also, I am not looking for data redundancy between the two
devices so I guess I can’t serially issue two read/write commands to each of
the devices and have both of them read/write the same data.

Would appreciate any feedback I can get. We are using QNX 6.1 for our
development.

Thanks

  • Murtaza

Aha! Yes! That makes a huge difference! I had (incorrectly) assumed that
your chips were configured serially and non-contiguously (ie. chip1
0x7800000-0x787FFFF, chip2 0x7900000-0x797FFFFF with a hole between).

Instead, your chips are interleaved 16-bit + 16-bit over a 32-bit bus.
So that they alternate every 2 bytes (ie. 0x11 0x11 0x22 0x22 0x11
0x11…). This configuration is very common and automatically supported
and (usually) detected. Just give the right address and window size. In
rare occasions, you might have to manually force the interleave to 2.

Internally, the driver uses a multiplier (ie. 0x00010001) so that a
command such as 0xAB becomes 0xAB* 0x00010001 => 0x00AB00AB, thus
causing both chips to get the command 0xAB. The resulting “virtual
mega-chip” should have twice the block size and I/O performance compared
to a single large chip.

Daryl Low

Murtaza wrote:

Thanks Daryl. The address is in the range of 0x7800.0000 - 0x78FF.FFFF.
This is a 16MB address space that can be accessed over a 32 bit bus width.
The lower 16 bits interfaces with the first 8MB chip while the upper 16
interfaces with the second 8MB.

While looking at the flash filesystem headers, I came across the f3s_dbase
structure which contains a variable called “chip_inter” /* interleave for
chips on bus */.

I am wondering what this chip_inter means and whether it applies to my case.

  • Murtaza

Thanks Daryl. The address is in the range of 0x7800.0000 - 0x78FF.FFFF.
This is a 16MB address space that can be accessed over a 32 bit bus width.
The lower 16 bits interfaces with the first 8MB chip while the upper 16
interfaces with the second 8MB.

While looking at the flash filesystem headers, I came across the f3s_dbase
structure which contains a variable called “chip_inter” /* interleave for
chips on bus */.

I am wondering what this chip_inter means and whether it applies to my case.

  • Murtaza

“Daryl Low” <dlo*w@qnx.com> wrote in message
news:3E5D1BC7.7050209@qnx.com

Now, if the physical address of both chips are contiguous… the
auto-probe will figure it all out for you. If not, just tweak the “page”
routine so it looks like:

uint8_t *page (f3s_socket_t *socket, uint32_t flags, uint32_t offset,
int32_t *size)
{
if (offset < 8MB) return (window1 + offset);
else if (offset < 16MB) return (window2 + offset - 8MB);

errno = ERANGE;
return (NULL);
}

If this is a custom driver, you can even hard-wire the addresses
(easiest way but sloppy). Don’t forget to make the socket “open” routine
allocate both windows.

A “nicer” way is to find somewhere to hold the pointer to the second
window, or make socket->address point to an array of window pointers or
something. You get the picture.

Daryl Low

Murtaza wrote:
Hi,

We have two similar 8 MB AMD am29LV flash on our board, each with a 16
bit
bus width, which we would like to have appear as a single array of 16
MB.
Ultimately, the goal is that there is a single mount point for the
entire 16
MB block and is available as a filesystem. I am looking for the
fastest
possible way in which we can accomodate this.

Looking at the AMD mtd libraries that come with the 6.1 BSPs, with a
minor
tweak, I should be able to use the am29f100s service routines for each
of
the 8MB part however, I am not sure how to address the two devices as a
single array. Do I need to write a layer on top of the service
routines
that calls these routine twice (in serial) to act on each of the two
flash
devices ? Also, I am not looking for data redundancy between the two
devices so I guess I can’t serially issue two read/write commands to
each of
the devices and have both of them read/write the same data.

Would appreciate any feedback I can get. We are using QNX 6.1 for our
development.

Thanks

  • Murtaza

    \