?? xmemtest.c
字號:
#include <string.h>#include <stdio.h>#include "utils.h"#include "uart.h"#include "xmemtest.h"extern u_char GetChar(void);#define MERR_BAD_ADDR 1#define MERR_BAD_DATA 2#define MERR_STICKY_WRITE 3#define MERR_STICKY_READ 4#define MERR_STICKY_ALE 5#define MERR_STICKY_DATABUS 6#define MERR_STICKY_ADDRBUS 7#define MERR_SHORT_DATABUS 8#define MERR_SHORT_ADDRBUS 9static int merr;static u_char merr_bits;static void *merr_addr;/* PORTA: AD0..7 *//* PORTC: A8..15 *//* * PG0: \WR * PG1: \RD * PG2: ALE * PG3: TOSC2 * PG4: TOSC1 *//*! * \brief Disable external memory interface. * * On return, control bus signals are high and address * and data bus are low. */void XMemDisable(void){ /* Disable external memory bus. */#if defined(__AVR_AT90CAN128__) cbi(XMCRA, SRE);#else cbi(MCUCR, SRE);#endif#ifdef __AVR_ENHANCED__ /* Disable write signal. */ sbi(PORTG, PORTG0); sbi(DDRG, PORTG0); /* Disable read signal. */ sbi(PORTG, PORTG1); sbi(DDRG, PORTG1); /* Set ALE high, which makes latch transparent. */ sbi(PORTG, PORTG2); sbi(DDRG, PORTG2);#endif /* Set latch register to zero. */ outb(PORTA, 0); outb(DDRA, 0xFF);#ifdef __AVR_ENHANCED__ cbi(PORTG, PORTG2); sbi(PORTG, PORTG2);#endif /* Set high address bus to zero. */ outb(PORTC, 0);#ifdef __AVR_ENHANCED__ outb(DDRC, 0xFF);#endif}#ifdef __AVR_ENHANCED__void XMemLatch(u_char val){ /* Port A is connected to latch inputs. */ outb(PORTA, val); outb(DDRA, 0xFF); /* Falling edge will set the latch. */ cbi(PORTG, PORTG2);}void MemWrite(uptr_t addr, ureg_t data){ /* Set high address byte. */ outb(PORTC, addr >> 8); /* Set low address byte. */ outb(PORTA, (u_char)addr); /* ALE falling */ cbi(PORTG, PORTG2); /* Set data byte. */ outb(PORTC, data); /* Low pulse on write. */ cbi(PORTG, PORTG0); cbi(PORTG, PORTG0); /* If ALE is high, then latch is transparent. */ sbi(PORTG, PORTG2);}ureg_t MemRead(uptr_t addr){ u_char rc; /* Set high address byte. */ outb(PORTC, addr >> 8); /* Set low address byte. */ outb(PORTC, (u_char)addr); /* ALE falling */ cbi(PORTG, PORTG2); /* Read signal falling. */ cbi(PORTG, PORTG1); /* Read data byte. */ rc = inb(PORTC); /* Read signal rising. */ sbi(PORTG, PORTG1); /* If ALE is high, then latch is transparent. */ sbi(PORTG, PORTG2); return rc;}/*! * \brief Detect sticky memory bus bits and shortcuts. */int XMemTestBus(void){ u_char wb; /* * Disable external memory bus. This will set the control bus * signals high, clear the address latch and set all data and * address bus lines to low. */ XMemDisable(); /* * First check for sticky control bus signals. We switch them * to inputs, but they should be kept high because the pullup * is enabled. If they become low, something is wrong. */ cbi(DDRG, PORTG0); if((inb(PING) & _BV(PORTG0)) != _BV(PORTG0)) { merr = MERR_STICKY_WRITE; return -1; } sbi(DDRG, PORTG0); cbi(DDRG, PORTG1); if((inb(PING) & _BV(PORTG0)) != _BV(PORTG0)) { merr = MERR_STICKY_READ; return -1; } sbi(DDRG, PORTG1); cbi(DDRG, PORTG2); if((inb(PING) & _BV(PORTG0)) != _BV(PORTG0)) { merr = MERR_STICKY_ALE; return -1; } /* * Check the data bus for any sticky bits. Note, that ALE is * still low, so the latch contents (all zero) will appear on * the high byte address bus lines. We switch AD0..AD7 into * input mode, enable the pullups and expect all line kept * high. */ outb(DDRA, 0); outb(PORTA, 0xFF); Delay(16); if(inb(PINA) != 0xFF) { merr_bits = ~inb(PINA); merr = MERR_STICKY_DATABUS; return -1; } /* * Do a walking bit test to find shortcuts. */ for(wb = 1; wb; wb <<= 1) { outb(PORTA, ~wb); outb(DDRA, wb); Delay(16); if(inb(PINA) != (u_char)~wb) { merr = MERR_SHORT_DATABUS; return -1; } }; outb(PORTA, 0); outb(DDRA, 0xFF);#ifdef __AVR_ENHANCED__ /* * Checking the high address bus is easy. */ outb(DDRC, 0); outb(PORTC, 0xFF); Delay(16); if(inb(PINC) != 0xFF) { merr_bits = ~inb(PINC); merr = MERR_STICKY_ADDRBUS; return -1; } for(wb = 1; wb; wb <<= 1) { outb(PORTC, ~wb); outb(DDRC, wb); Delay(16); if(inb(PINC) != (u_char)~wb) { merr = MERR_SHORT_ADDRBUS; return -1; } }; outb(PORTC, 0); outb(DDRC, 0xFF);#endif return 0;}#endif/*! * \brief Test external SRAM. * * \return Number of bytes available. */size_t XMemTest(void){ volatile u_char *mem; u_char wb; u_char pattern[] = { 0x00, 0xFF, 0x55, 0xAA }; u_char *last = (u_char *)-1;#ifdef __AVR_ENHANCED__ /* * Test external memory bus on ATmega128 systems. */ if(XMemTestBus()) { return 0; }#endif /* * Enable external RAM. */#if defined(__AVR_AT90CAN128__) outb(XMCRA, BV(SRE));#else outb(MCUCR, BV(SRE));#endif /* * Let's see, how many kBytes we have. A simple pattern test on the * first bytes of each kilobyte boundary will do. */ for (mem = (u_char *)(RAMEND + 1); mem <= last; mem += 1024) { memcpy((void *)mem, pattern, sizeof(pattern)); if(memcmp((void *)mem, pattern, sizeof(pattern))) { last = (u_char *)(mem - 1); } /* * External RAM may not start at kilobyte boundary. Set the * address to full kilobytes after first test. */ else if(mem == (u_char *)(RAMEND + 1)) { mem = (u_char *)((uptr_t)mem & ~0x3FF); } } /* * Set all bits in RAM. */ for (mem = (u_char *)(RAMEND + 1); mem <= (u_char *)last; mem += 256) { memset((void *)mem, 0xFF, 256); } /* * Do an extensive test. */ for (mem = (u_char *)(RAMEND + 1); mem <= (u_char *)last; mem++) { /* * The next RAM location must still have all bits set. If not, * any manipulation on lower addresses may have modified this * one. Probably an address bus problem. */ if(*mem != 0xFF) { merr_bits = ~*mem; merr_addr = (void *)mem; merr = MERR_BAD_ADDR; break; } /* * Do a walking bit test including all bits zero on the current * RAM location. */ wb = 1; *mem = wb; do { if(*mem != wb) { break; } wb <<= 1; *mem = wb; } while(wb); /* * If the walking bit test hasn't finished or if not all bits * are cleared, then this data byte is broken. */ if(wb || *mem) { if(wb) { merr_bits = *mem & ~wb; } else { merr_bits = *mem; } merr_addr = (void *)mem; merr = MERR_BAD_DATA; break; } } return (size_t)last - RAMEND;}/*! * \brief Test external banked SRAM. * * Banked memory is asumed on top of non-banked memory and the * start of banked memory is assumed on a 256 byte boundary. * * \return Number of banks available. */int XMemBankTest(size_t *xramsize){ volatile u_char *breg = (u_char *)((size_t)-1 & ~0xFF); volatile u_char *bmem = 0; size_t bsize = 16384; u_char *bend = (u_char *)bmem + bsize; u_char *xramend = (u_char *)(*xramsize + RAMEND + 1); volatile u_char *cp; u_char i; u_char j; /* * Determine the start address of banked memory. Switch to * bank 1 and set every 256th byte to 1. Then switch to bank 0 * and clear every 256th byte. Next switch back to bank 1 * and find the first location set to 1. */ *(breg + 1) = 1; for (cp = (u_char *)(RAMEND + 1); cp < xramend; cp += 256) { *cp = 1; } *breg = 0; for (cp = (u_char *)(RAMEND + 1); cp < xramend; cp += 256) { *cp = 0; } *(breg + 1) = 1; for (cp = (u_char *)(RAMEND + 1); cp < xramend; cp += 256) { if(*cp == 1) { bmem = cp; break; } } /* * No RAM location kept the value of 1. There is no banked memory. */ if(bmem == 0) { return 0; } *xramsize = xramend - bmem; for(i = 1; i; i++) { *(breg + i) = i; memset((void *)bmem, i, bsize); for(cp = bmem; cp < bend; cp++) { if(*cp != i) { break; } } if(cp < bend) { break; } /* * Test if non-banked memory is intact. */ for (cp = (u_char *)(RAMEND + 1); cp < bmem; cp += 256) { if(*cp) { break; } } if(cp < bmem) { break; } for(j = 0; j < i; j++) { *(breg + j) = j; for(cp = bmem; cp < bend; cp++) { if(*cp != j) { break; } } if(cp < bend) { break; } } if(j < i) { break; } } return i;}/* * Read/write external SRAM until key pressed. */void LoopSRAM(void){ register u_short pattern; volatile u_char *mem; uptr_t faddr = 0xFFFF; puts("Check address and data bus."); printf_P(presskey_P); for (;;) { for (pattern = 1; pattern; pattern <<= 1) { if (pattern <= RAMEND) mem = (u_char *) (pattern | (RAMEND + 1)); else mem = (u_char *) pattern; *mem = (u_char) ((pattern >> 8) | pattern); } for (pattern = 1; pattern; pattern <<= 1) { if (pattern <= RAMEND) mem = (u_char *) (pattern | (RAMEND + 1)); else mem = (u_char *) pattern; if (*mem != (u_char) ((pattern >> 8) | pattern)) faddr = (uptr_t) mem; } Delay(5000); if (GetChar()) { printf("No RAM at 0x%04X\n", faddr); return; } }}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -