1
\$\begingroup\$

Recently I was looking for a replacement for my old flash memory chip. I've soldered a S29AL016J memory chip in my boards and started checking if everything worked correctly like with my previous memory. I've encountered some strange behavior of the new memory which I cannot explain.

When I configure the memory peripheral to drive WE# line high during reading (like it is in the most of memories) everything is fine, but if the peripheral is configured to drive WE# line low during reading the memory chip also drives data lines! The previous memory just left the lines as they were (all lines low).

Here are some results I've collected during testing:

Code to read data:

uint16_t var = *((uint16_t*)0x80000000);

old memory:

Peripheral configured to drive WE# low during reading:

CE# - low
OE# - low
WE# - low
ADDR - 0x0000

variable "var" - 0x0000

Peripheral configured to drive WE# line high during reading:

CE# - low;
OE# - low;
WE# - high;
ADDR - 0x0000;

variable "var" - actual data stored in memory

S29AL016J

Peripheral configured to drive WE# line high during reading:

CE# - low;
OE# - low;
WE# - low;
ADDR - 0x0000;

variable "var" - actual data stored in memory even if WE# is driven low!

Periph configured to drive WE# line high during reading:

CE# - low;
OE# - low;
WE# - high;
ADDR - 0x0000;

variable "var" - actual data stored in memory

So it looks like it doesn't matter if the microcontroller drives the WE# line low or high during reading operation, it will put its data on the data lines anyway. It looks like some flash chip's internal state machine checks if the address set on the address lines is a "special" one (0x555 etc.) to start some command and if not, it executes a read operation and exposes data on data lines. If in the code I perform the read operation, the MCU should set the data pin as floating inputs, right?

So to sum up, I would like to ask if this is normal behavior, or if there is something strange, or the issue may be in some other place? I use exactly the same copy of the PCB and replaced only the flash memory chip.

Here is a snippet of code which I've used to compare behavior between both chips:

//set EMC to drive WE# line low during reading
//EMC_cfg_we(FALSE);

//set EMC to drive WE# line high during reading
EMC_cfg_we(TRUE);

while(1)
{
   uint8_t test = ( *( Uint16 * )(0x80000000L)) & 0xFF;
   uart_putc(test);
   delay_ms(500);
}
\$\endgroup\$
0
\$\begingroup\$

The driving of the control signals is wrong so no wonder the flash behaves strangely.

You are not supposed to set WE# and OE# low at the same time, they are active low signals.

Only one of them is allowed to be activated, or low, at any given time, and when not needed, they should idle high.

\$\endgroup\$
2
  • \$\begingroup\$ Yup, that's why I'm asking ;) I'm not very familiar with such interface. I only wonder if there is any "obvious" explanation why with such set of CE, OE and WE lines some chips will drive data lines and some other not. \$\endgroup\$
    – voldi
    Nov 18 '21 at 20:00
  • \$\begingroup\$ Yes, the obvious explanation is that while the interface between chips are standardized and thus identical, there are cases that are undefined in the standard because they make no sense, no one would read and write at same time. Each chip manufacturer only needs to implement the defined interface in a defined fashion, and can optimize internal logic however they wish to implement the defined cases. The S29AL016J will actually do what the block diagram says - the OE# really controls the output buffers which makes the data pins outputs. The WE# only makes the control block to read in a command. \$\endgroup\$
    – Justme
    Nov 18 '21 at 21:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.