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);
}