Here is my test code. The disabled enable_sram/disable_sram functions were me testing the memory controller enable/disable at different places in the test routine. That makes on difference. There functions to do it with the memory controller and also bitbang which are selected with defines.
#include <avr/io.h>
#include "util\atomic.h"
#include "avr/pgmspace.h"
#include "avr/wdt.h"
#include "stdio.h"
#include "cdelay.h"
#include "ddrpin.h"
#define F_CPU 14745600
#define UART_RXBUFFERSIZE 64
#define UART_TXBUFFERSIZE 64
#define A15_PORT PORTC
#define A15_PIN 7
#define BANK_PORT PORTF
#define MREQ_PORT PORTE
#define MREQ_PIN 5
#define LATCH_PORT PORTE
#define LATCH_PIN 4
#define MEMORY
//#define BITBANG
//____________________________________________________________________________________________________________________________________
volatile unsigned char RxBuffer[UART_RXBUFFERSIZE],RxPtrIn,RxPtrOut,RxItems,TxBuffer[UART_TXBUFFERSIZE],TxPtrIn,TxPtrOut,TxItems;
void uart_putc(unsigned char AChar)
{
//delay if the buffer is full
for(;TxItems==UART_TXBUFFERSIZE;)
;
//add char to the buffer
TxBuffer[TxPtrIn]=AChar;
TxPtrIn++;
if (TxPtrIn==UART_TXBUFFERSIZE)
TxPtrIn=0;
ATOMIC_BLOCK(ATOMIC_FORCEON)
{
TxItems++;
UCSR0B|=_BV(UDRIE0);
}
}
void uart_puts(char *AString)
{
char c;
while ((c=*AString++))
uart_putc(c);
}
void uart_puts_P(const char *AString)
{
char c;
while ((c=pgm_read_byte(AString++)))
uart_putc(c);
}
unsigned char uart_getc()
{
unsigned char c1;
if (!RxItems)
return 0;
c1=RxBuffer[RxPtrOut];
RxPtrOut++;
if (RxPtrOut==UART_RXBUFFERSIZE)
RxPtrOut=0;
ATOMIC_BLOCK(ATOMIC_FORCEON)
{
RxItems--;
}
return c1;
}
void uart_clear_rx_buffer()
{
ATOMIC_BLOCK(ATOMIC_FORCEON)
{
RxPtrIn=0;
RxPtrOut=0;
RxItems=0;
}
}
void uart_clear_tx_buffer()
{
ATOMIC_BLOCK(ATOMIC_FORCEON)
{
TxPtrIn=0;
TxPtrOut=0;
TxItems=0;
UCSR0B&=~_BV(UDRIE0);
}
}
ISR(USART0_UDRE_vect)
{
if (!TxItems)
{
UCSR0B&=~_BV(UDRIE0);
return;
}
UDR0=TxBuffer[TxPtrOut];
TxPtrOut++;
if (TxPtrOut==UART_TXBUFFERSIZE)
TxPtrOut=0;
TxItems--;
}
ISR(USART0_RX_vect)
{
char c1;
c1=UDR0;
if (RxItems==UART_RXBUFFERSIZE)
return;
RxBuffer[RxPtrIn]=c1;
RxPtrIn++;
if (RxPtrIn==UART_RXBUFFERSIZE)
RxPtrIn=0;
RxItems++;
}
char s1[64];
// memory interface
#ifdef MEMORY
void enable_sram()
{
//memory controller
XMCRB=_BV(XMM0); //we control A15 manually through PC7
//XMCRA=_BV(SRW11) | _BV(SRW10); //2 wait plus
//XMCRA=_BV(SRW11); //2 wait
//XMCRA=_BV(SRW10); //1 wait
//XMCRB|=_BV(XMBK); //bus keep
MCUCR=_BV(SRE);
//A15
DDR(A15_PORT)|=_BV(A15_PIN);
//BANK0-3
DDR(BANK_PORT)|=0x0f;
//MREQ
DDR(MREQ_PORT)|=_BV(MREQ_PIN);
//LATCH
DDR(LATCH_PORT)|=_BV(LATCH_PIN);
}
void disable_sram()
{
//memory controller
XMCRB=0;
XMCRA=0;
MCUCR=0;
//A15
DDR(A15_PORT)&=~_BV(A15_PIN);
//BANK0-3
DDR(BANK_PORT)&=~0x0f;
//MREQ
DDR(MREQ_PORT)&=~_BV(MREQ_PIN);
//LATCH
DDR(LATCH_PORT)&=~_BV(LATCH_PIN);
}
uint8_t getbyte(uint16_t AAddress)
{
return *(volatile uint8_t*)AAddress;
}
void setbyte(uint16_t AAddress, uint8_t AByte)
{
*(uint8_t*)AAddress=AByte;
}
#endif
#ifdef BITBANG
// bit bang
#define RD 1
#define WR 0
#define ALE 2
void enable_sram()
{
PORTG|=_BV(WR) | _BV(RD); //RD + WR
DDRG=_BV(WR) | _BV(RD) | _BV(ALE);
DDRC=0xff;
DDRA=0xff;
//A15
//DDR(A15_PORT)|=_BV(A15_PIN);
//BANK0-3
DDR(BANK_PORT)|=0x0f;
//MREQ
DDR(MREQ_PORT)|=_BV(MREQ_PIN);
//LATCH
DDR(LATCH_PORT)|=_BV(LATCH_PIN);
}
void disable_sram()
{
//memory controller
DDRG=0;
PORTG=0;
DDRC=0;
DDRA=0;
//A15
//DDR(A15_PORT)&=~_BV(A15_PIN);
//BANK0-3
DDR(BANK_PORT)&=~0x0f;
//MREQ
DDR(MREQ_PORT)&=~_BV(MREQ_PIN);
//LATCH
DDR(LATCH_PORT)&=~_BV(LATCH_PIN);
}
uint8_t getbyte(uint16_t AAddress)
{
uint8_t c1;
c1=(AAddress>>8) & 0x7f;
PORTC=(PORTC & 0x80) | c1;
PORTA=AAddress & 255;
PORTG|=_BV(ALE); //ALE
PORTG&=~_BV(ALE); //ALE
DDRA=0;
PORTG&=~_BV(RD); //RD
asm volatile ("nop");
asm volatile ("nop");
c1=PINA;
PORTG|=_BV(RD); //RD
DDRA=0xff;
return c1;
}
void setbyte(uint16_t AAddress, uint8_t AByte)
{
uint8_t c1;
c1=(AAddress>>8) & 0x7f;
PORTC=(PORTC & 0x80) | c1;
PORTA=AAddress & 255;
PORTG|=_BV(ALE); //ALE
PORTG&=~_BV(ALE); //ALE
PORTA=AByte;
PORTG&=~_BV(WR); //WR
PORTG|=_BV(WR); //WR
}
#endif
void A15_high()
{
A15_PORT|=_BV(A15_PIN);
}
void A15_low()
{
A15_PORT&=~_BV(A15_PIN);
}
void setbank(uint8_t ABank)
{
BANK_PORT=(BANK_PORT & 0xf0) | ABank;
}
void dump(uint16_t AAddress, uint16_t ALines)
{
uint8_t c1,c2;
uint16_t ui1;
for (ui1=AAddress;;)
{
sprintf(s1,"%04x: ",ui1);
uart_puts(s1);
for (c2=0;c2<16;c2++)
{
c1=*(uint8_t*)(ui1+c2);
sprintf(s1,"%02x ",c1);
uart_puts(s1);
}
uart_puts("\n\r");
ui1+=16;
ALines--;
if (ALines==0)
break;
}
}
const char PROGMEM testsram1[]="Testing 512K Static RAM (pass %d)...";
const char PROGMEM testsram2[]="\n\r";
const char PROGMEM ramfail[]="\n\rRAM FAIL bank %d 0x%04x should be 0x%02x but was 0x%02x\n\rHALTED.\n\r";
void srampass(uint8_t AVerify, uint8_t ASource, uint8_t ADest)
{
uint16_t ui1;
uint8_t c1,c2;
//enable_sram();
c2=0;
for (c2=0;c2<16;c2++)
{
if (c2==15)
A15_high();
else
{
A15_low();
setbank(c2);
}
//enable_sram();
for(ui1=0x8000;;)
{
if (AVerify)
{
//c1=*(volatile uint8_t*)ui1;
//enable_sram();
c1=getbyte(ui1);
//c3=getbyte(ui1);
//c4=getbyte(ui1);
//disable_sram();
if (c1!=ASource)
{
sprintf_P(s1,ramfail,c2,ui1,ASource,c1);
uart_puts(s1);
//halt
for(;;);
}
}
//*(uint8_t*)ui1=ADest;
//enable_sram();
setbyte(ui1,ADest);
//disable_sram();
ui1++;
if (ui1==0)
break;
}
//disable_sram();
}
//disable_sram();
}
uint16_t pass=1;
void testsram()
{
//test begin
sprintf_P(s1,testsram1,pass++);
uart_puts(s1);
#define FIRST 0x55
#define SECOND 0xaa
enable_sram();
//pass 1 - set 0x55
srampass(0,0,FIRST);
uart_putc('1');
//pass 2 - verify 0x55, set 0xaa
srampass(1,FIRST,SECOND);
uart_putc('2');
//pass 3 - verify 0xaa, set 0x00
srampass(1,SECOND,FIRST);
uart_putc('3');
//pass 4 - verify 0x55, set 0xaa
srampass(1,FIRST,SECOND);
uart_putc('4');
//pass 5 - verify 0xaa, set 0x00
srampass(1,SECOND,0);
uart_putc('5');
disable_sram();
//test end
uart_puts_P(testsram2);
}
int main(void)
{
//disable wdt
wdt_reset();
wdt_disable();
//half speed
// XDIV=255; //half speed
// XDIV=253; //quarter speed
//enable interrupts
sei();
//enable usart0 at 9600bps
UBRR0L=95;
UCSR0B=_BV(RXCIE0) | _BV(RXEN0) | _BV(TXEN0);
uart_clear_rx_buffer();
uart_clear_tx_buffer();
//for(;;);
//test sram
for(;;)
testsram();
//halt
for(;;)
;
}