Skip to main content
Copy edited (e.g. ref. <https://ww1.microchip.com/downloads/en/DeviceDoc/doc2512.pdf>, <https://en.wiktionary.org/wiki/exercise#Verb>, and <https://en.wiktionary.org/wiki/nonexistent#Adjective>).
Source Link

ATMega8515 ATmega8515 - odd results when auto-detecting external SRAM

I'm using an ATMega8515ATmega8515 microcontroller for a one-off hobby project. This chip has an external memory interface which can directly address 64 kilobytes of external SRAM.

ATMega8515ATmega8515 datasheet.

For my project I need more than 64KB64 KB, so I'm supplementing this address space by manually bank-switching between 4four banks of 64KB64 KB each. This bank-switching is achieved by using two normal GPIO pins as additional address lines. This gives me a grand total of 256KB256 KB of external SRAM.

So far so good. I've wired up the first 128KB128 KB onto the main board and I'm planning to have the second 128KB128 KB on a plug-in expansion PCB, that I can add later on.

I'd like my project to be able to automatically detect how much SRAM is available, so I've written a function that excersisesexercises the SRAM by writing a pattern of data to each bank in turn and then reads it back again and displays it over a UART which I can read using MinicomMinicom under Linux.

Bank 0 and Bank 1 both work as expected, and I'm reading out the same data that I stored there.

But I am seeing some weird results when attempting to access the non-existentnonexistent Bank 2 and Bank 3. Since those chips are not present in the circuit yet, I was expecting to read back random garbage from those addresses since there would not be noany SRAM chip to drive the data bus.

Perfect results from Banks 0 andand 1...

The data read back from the non-existent addresses is not glitchy or noisy in any way, it's. It's rock-solid and repeatable.

How come the data lines appear to "remember" their voltage state from immediately before they were tri-stated by the 74HC573? The ATMega8515ATmega8515 will be reading the data a few nanoseconds after the data bus is tri-stated - could this state be retained through some stray capacitance in the wiring?

All this said, I don't think there is actually anything malfunctioning here - Ihere—I am attempting to access chips that are not there - whichthere—which is obviously "undefined behaviour".

Further infoinformation:

ATMega8515 - odd results when auto-detecting external SRAM

I'm using an ATMega8515 microcontroller for a one-off hobby project. This chip has an external memory interface which can directly address 64 kilobytes of external SRAM.

ATMega8515 datasheet.

For my project I need more than 64KB so I'm supplementing this address space by manually bank-switching between 4 banks of 64KB each. This bank-switching is achieved by using two normal GPIO pins as additional address lines. This gives me a grand total of 256KB of external SRAM.

So far so good. I've wired up the first 128KB onto the main board and I'm planning to have the second 128KB on a plug-in expansion PCB, that I can add later on.

I'd like my project to be able to automatically detect how much SRAM is available, so I've written a function that excersises the SRAM by writing a pattern of data to each bank in turn and then reads it back again and displays it over a UART which I can read using Minicom under Linux.

Bank 0 and Bank 1 both work as expected, I'm reading out the same data that I stored there.

But I am seeing some weird results when attempting to access the non-existent Bank 2 and Bank 3. Since those chips are not present in the circuit yet, I was expecting to read back random garbage from those addresses since there would be no SRAM chip to drive the data bus.

Perfect results from Banks 0 and 1...

The data read back from the non-existent addresses is not glitchy or noisy in any way, it's rock-solid and repeatable.

How come the data lines appear to "remember" their voltage state from immediately before they were tri-stated by the 74HC573? The ATMega8515 will be reading the data a few nanoseconds after the data bus is tri-stated - could this state be retained through some stray capacitance in the wiring?

All this said, I don't think there is actually anything malfunctioning here - I am attempting to access chips that are not there - which is obviously "undefined behaviour".

Further info:

ATmega8515 - odd results when auto-detecting external SRAM

I'm using an ATmega8515 microcontroller for a one-off hobby project. This chip has an external memory interface which can directly address 64 kilobytes of external SRAM.

ATmega8515 datasheet.

For my project I need more than 64 KB, so I'm supplementing this address space by manually bank-switching between four banks of 64 KB each. This bank-switching is achieved by using two normal GPIO pins as additional address lines. This gives me a grand total of 256 KB of external SRAM.

So far so good. I've wired up the first 128 KB onto the main board and I'm planning to have the second 128 KB on a plug-in expansion PCB, that I can add later on.

I'd like my project to be able to automatically detect how much SRAM is available, so I've written a function that exercises the SRAM by writing a pattern of data to each bank in turn and then reads it back again and displays it over a UART which I can read using Minicom under Linux.

Bank 0 and Bank 1 both work as expected, and I'm reading out the same data that I stored there.

But I am seeing some weird results when attempting to access the nonexistent Bank 2 and Bank 3. Since those chips are not present in the circuit yet, I was expecting to read back random garbage from those addresses since there would not be any SRAM chip to drive the data bus.

Perfect results from Banks 0 and 1...

The data read back from the non-existent addresses is not glitchy or noisy in any way. It's rock-solid and repeatable.

How come the data lines appear to "remember" their voltage state from immediately before they were tri-stated by the 74HC573? The ATmega8515 will be reading the data a few nanoseconds after the data bus is tri-stated - could this state be retained through some stray capacitance in the wiring?

All this said, I don't think there is actually anything malfunctioning here—I am attempting to access chips that are not there—which is obviously "undefined behaviour".

Further information:

Became Hot Network Question
More info about final resolution.
Source Link
Wossname
  • 656
  • 4
  • 14
Bank0[0x260]: 000x00
Bank0[0x261]: 010x01
Bank0[0x262]: 020x02
Bank0[0x263]: 030x03
Bank1[0x260]: 400x40
Bank1[0x261]: 410x41
Bank1[0x262]: 420x42
Bank1[0x263]: 430x43
Bank2[0x260]: 600x60
Bank2[0x261]: 610x61
Bank2[0x262]: 620x62
Bank2[0x263]: 630x63
Bank3[0x260]: 600x60
Bank3[0x261]: 610x61
Bank3[0x262]: 620x62
Bank3[0x263]: 630x63
  //Set wait states for UPPER sector to the maximum (slowest possible)
  MCUCR  |= (1 << SRW10);
  EMCUCR |= (1 << SRW11);

  //Set wait states for LOWER sector to the maximum (slowest possible)
  EMCUCR |= (1 << SRW01) & (1 << SRW00);

  //Enable the XMEM interface (p. 29, Mega8515 datasheet)
  MCUCR  |= (1 << SRE);

With many thanks to @TomCarpenter, the problem is solved...

Writing each byte in my 256KB XMEM address space to be the bit-wise NOT of the low byte of its own address causes any absent SRAM to reveal itself.

In other words, writing ~0x73 into address 0x0573 forces the data to be different to the low-byte of the address when the SRAM is present in that location.

When there is no SRAM present, the data read back from the SRAM is the same as the low-byte of the address, likely because of stray capacitance in the wiring.

I can now reliably detect present or absent SRAM chips!

Here's my new output from the terminal...

Bank0[0x260]: 0x9f //SRAM present
Bank0[0x261]: 0x9e //SRAM present
Bank0[0x262]: 0x9d //SRAM present
Bank0[0x263]: 0x9c //SRAM present
Bank1[0x260]: 0x9f //SRAM present
Bank1[0x261]: 0x9e //SRAM present
Bank1[0x262]: 0x9d //SRAM present
Bank1[0x263]: 0x9c //SRAM present
Bank2[0x260]: 0x60 //               SRAM MISSING
Bank2[0x261]: 0x61 //               SRAM MISSING
Bank2[0x262]: 0x62 //               SRAM MISSING
Bank2[0x263]: 0x63 //               SRAM MISSING
Bank3[0x260]: 0x60 //               SRAM MISSING
Bank3[0x261]: 0x61 //               SRAM MISSING
Bank3[0x262]: 0x62 //               SRAM MISSING
Bank3[0x263]: 0x63 //               SRAM MISSING
Bank0[0x260]: 00
Bank0[0x261]: 01
Bank0[0x262]: 02
Bank0[0x263]: 03
Bank1[0x260]: 40
Bank1[0x261]: 41
Bank1[0x262]: 42
Bank1[0x263]: 43
Bank2[0x260]: 60
Bank2[0x261]: 61
Bank2[0x262]: 62
Bank2[0x263]: 63
Bank3[0x260]: 60
Bank3[0x261]: 61
Bank3[0x262]: 62
Bank3[0x263]: 63
  //Set wait states for UPPER sector to the maximum (slowest possible)
  MCUCR  |= (1 << SRW10);
  EMCUCR |= (1 << SRW11);

  //Set wait states for LOWER sector to the maximum (slowest possible)
  EMCUCR |= (1 << SRW01) & (1 << SRW00);

  //Enable the XMEM interface (p. 29, Mega8515 datasheet)
  MCUCR  |= (1 << SRE);
Bank0[0x260]: 0x00
Bank0[0x261]: 0x01
Bank0[0x262]: 0x02
Bank0[0x263]: 0x03
Bank1[0x260]: 0x40
Bank1[0x261]: 0x41
Bank1[0x262]: 0x42
Bank1[0x263]: 0x43
Bank2[0x260]: 0x60
Bank2[0x261]: 0x61
Bank2[0x262]: 0x62
Bank2[0x263]: 0x63
Bank3[0x260]: 0x60
Bank3[0x261]: 0x61
Bank3[0x262]: 0x62
Bank3[0x263]: 0x63
  //Set wait states for UPPER sector to the maximum (slowest possible)
  MCUCR  |= (1 << SRW10);
  EMCUCR |= (1 << SRW11);

  //Set wait states for LOWER sector to the maximum (slowest possible)
  EMCUCR |= (1 << SRW01) & (1 << SRW00);

  //Enable the XMEM interface (p. 29, Mega8515 datasheet)
  MCUCR  |= (1 << SRE);

With many thanks to @TomCarpenter, the problem is solved...

Writing each byte in my 256KB XMEM address space to be the bit-wise NOT of the low byte of its own address causes any absent SRAM to reveal itself.

In other words, writing ~0x73 into address 0x0573 forces the data to be different to the low-byte of the address when the SRAM is present in that location.

When there is no SRAM present, the data read back from the SRAM is the same as the low-byte of the address, likely because of stray capacitance in the wiring.

I can now reliably detect present or absent SRAM chips!

Here's my new output from the terminal...

Bank0[0x260]: 0x9f //SRAM present
Bank0[0x261]: 0x9e //SRAM present
Bank0[0x262]: 0x9d //SRAM present
Bank0[0x263]: 0x9c //SRAM present
Bank1[0x260]: 0x9f //SRAM present
Bank1[0x261]: 0x9e //SRAM present
Bank1[0x262]: 0x9d //SRAM present
Bank1[0x263]: 0x9c //SRAM present
Bank2[0x260]: 0x60 //               SRAM MISSING
Bank2[0x261]: 0x61 //               SRAM MISSING
Bank2[0x262]: 0x62 //               SRAM MISSING
Bank2[0x263]: 0x63 //               SRAM MISSING
Bank3[0x260]: 0x60 //               SRAM MISSING
Bank3[0x261]: 0x61 //               SRAM MISSING
Bank3[0x262]: 0x62 //               SRAM MISSING
Bank3[0x263]: 0x63 //               SRAM MISSING
added 428 characters in body
Source Link
Wossname
  • 656
  • 4
  • 14

Further info:

Here is my XMEM feature initialisation:

  //Set wait states for UPPER sector to the maximum (slowest possible)
  MCUCR  |= (1 << SRW10);
  EMCUCR |= (1 << SRW11);

  //Set wait states for LOWER sector to the maximum (slowest possible)
  EMCUCR |= (1 << SRW01) & (1 << SRW00);

  //Enable the XMEM interface (p. 29, Mega8515 datasheet)
  MCUCR  |= (1 << SRE);

Further info:

Here is my XMEM feature initialisation:

  //Set wait states for UPPER sector to the maximum (slowest possible)
  MCUCR  |= (1 << SRW10);
  EMCUCR |= (1 << SRW11);

  //Set wait states for LOWER sector to the maximum (slowest possible)
  EMCUCR |= (1 << SRW01) & (1 << SRW00);

  //Enable the XMEM interface (p. 29, Mega8515 datasheet)
  MCUCR  |= (1 << SRE);
Source Link
Wossname
  • 656
  • 4
  • 14
Loading