reset detection

This commit is contained in:
ikari 2009-11-15 21:43:20 +01:00
parent 32fb6f3188
commit 0b46b04dd9
6 changed files with 119 additions and 39 deletions

Binary file not shown.

View File

@ -154,40 +154,53 @@ int main(void) {
set_avr_ena(0); set_avr_ena(0);
snes_reset(1); snes_reset(1);
sram_writelong(0x12345678, SRAM_SCRATCHPAD);
*fs_path=0; *fs_path=0;
uint16_t curr_dir_id = scan_dir(fs_path, 0, 0); // generate files footprint
dprintf("curr dir id = %x\n", curr_dir_id);
uint16_t saved_dir_id; uint16_t saved_dir_id;
get_db_id(&saved_dir_id);
uint16_t mem_dir_id = sram_readshort(SRAM_DIRID);
uint32_t mem_magic = sram_readlong(SRAM_SCRATCHPAD);
led_pwm(); led_pwm();
if((get_db_id(&saved_dir_id) != FR_OK) // no database? if((mem_magic != 0x12345678) || (mem_dir_id != saved_dir_id)) {
|| saved_dir_id != curr_dir_id) { // files changed? // XXX uint16_t curr_dir_id = scan_dir(fs_path, 0, 0); // generate files footprint
dprintf("saved dir id = %x\n", saved_dir_id); dprintf("curr dir id = %x\n", curr_dir_id);
_delay_ms(50);
dprintf("rebuilding database..."); led_pwm();
_delay_ms(50);
curr_dir_id = scan_dir(fs_path, 1, 0); // then rebuild database if((get_db_id(&saved_dir_id) != FR_OK) // no database?
sram_writeblock(&curr_dir_id, SRAM_DB_ADDR, 2); || saved_dir_id != curr_dir_id) { // files changed? // XXX
uint32_t endaddr, direndaddr; dprintf("saved dir id = %x\n", saved_dir_id);
sram_readblock(&endaddr, SRAM_DB_ADDR+4, 4); _delay_ms(50);
sram_readblock(&direndaddr, SRAM_DB_ADDR+8, 4); dprintf("rebuilding database...");
dprintf("%lx %lx\n", endaddr, direndaddr); _delay_ms(50);
save_sram((uint8_t*)"/sd2snes/sd2snes.db", endaddr-SRAM_DB_ADDR, SRAM_DB_ADDR); curr_dir_id = scan_dir(fs_path, 1, 0); // then rebuild database
save_sram((uint8_t*)"/sd2snes/sd2snes.dir", direndaddr-(SRAM_DIR_ADDR), SRAM_DIR_ADDR); sram_writeblock(&curr_dir_id, SRAM_DB_ADDR, 2);
dprintf("done\n"); uint32_t endaddr, direndaddr;
sram_hexdump(SRAM_DB_ADDR, 0x400); sram_readblock(&endaddr, SRAM_DB_ADDR+4, 4);
} else { sram_readblock(&direndaddr, SRAM_DB_ADDR+8, 4);
dprintf("loading db...\n"); dprintf("%lx %lx\n", endaddr, direndaddr);
load_sram((uint8_t*)"/sd2snes/sd2snes.db", SRAM_DB_ADDR); save_sram((uint8_t*)"/sd2snes/sd2snes.db", endaddr-SRAM_DB_ADDR, SRAM_DB_ADDR);
load_sram((uint8_t*)"/sd2snes/sd2snes.dir", SRAM_DIR_ADDR); save_sram((uint8_t*)"/sd2snes/sd2snes.dir", direndaddr-(SRAM_DIR_ADDR), SRAM_DIR_ADDR);
} dprintf("done\n");
sram_hexdump(SRAM_DB_ADDR, 0x400);
} else {
dprintf("different card, consistent db, loading db...\n");
load_sram((uint8_t*)"/sd2snes/sd2snes.db", SRAM_DB_ADDR);
load_sram((uint8_t*)"/sd2snes/sd2snes.dir", SRAM_DIR_ADDR);
}
// save_sram((uint8_t*)"/debug.smc", 0x400000, 0); // save_sram((uint8_t*)"/debug.smc", 0x400000, 0);
// uart_putc('['); // uart_putc('[');
// load_sram((uint8_t*)"/test.srm", SRAM_SAVE_ADDR); // load_sram((uint8_t*)"/test.srm", SRAM_SAVE_ADDR);
// uart_putc(']'); // uart_putc(']');
sram_writeshort(curr_dir_id, SRAM_DIRID);
sram_writelong(0x12345678, SRAM_SCRATCHPAD);
} else {
dprintf("same card, loading db...\n");
load_sram((uint8_t*)"/sd2snes/sd2snes.db", SRAM_DB_ADDR);
load_sram((uint8_t*)"/sd2snes/sd2snes.dir", SRAM_DIR_ADDR);
}
uart_putc('('); uart_putc('(');
load_rom((uint8_t*)"/sd2snes/menu.bin"); load_rom((uint8_t*)"/sd2snes/menu.bin");
set_rom_mask(0x3fffff); // force mirroring off set_rom_mask(0x3fffff); // force mirroring off
@ -229,6 +242,9 @@ int main(void) {
dprintf("cmd was %x, going to snes main loop\n", cmd); dprintf("cmd was %x, going to snes main loop\n", cmd);
cmd=0; cmd=0;
while(1) { while(1) {
if(get_snes_reset()) {
dprintf("RESET\n");
}
snes_main_loop(); snes_main_loop();
} }

View File

@ -17,6 +17,7 @@
#include "smc.h" #include "smc.h"
#include "fpga_spi.h" #include "fpga_spi.h"
#include "memory.h" #include "memory.h"
#include "snes.h"
char* hex = "0123456789ABCDEF"; char* hex = "0123456789ABCDEF";
@ -48,6 +49,16 @@ uint8_t sram_readbyte(uint32_t addr) {
return val; return val;
} }
void sram_writeshort(uint16_t val, uint32_t addr) {
set_avr_addr(addr);
spi_fpga();
spiTransferByte(0x91); // WRITE
spiTransferByte(val&0xff); // 7-0
spiTransferByte((val>>8)&0xff); // 15-8
spiTransferByte(0x00); // dummy
spi_none();
}
void sram_writelong(uint32_t val, uint32_t addr) { void sram_writelong(uint32_t val, uint32_t addr) {
set_avr_addr(addr); set_avr_addr(addr);
spi_fpga(); spi_fpga();
@ -60,6 +71,18 @@ void sram_writelong(uint32_t val, uint32_t addr) {
spi_none(); spi_none();
} }
uint16_t sram_readshort(uint32_t addr) {
set_avr_addr(addr);
spi_fpga();
spiTransferByte(0x81);
spiTransferByte(0x00);
uint32_t val = spiTransferByte(0x00);
val |= ((uint32_t)spiTransferByte(0x00)<<8);
spi_none();
return val;
}
uint32_t sram_readlong(uint32_t addr) { uint32_t sram_readlong(uint32_t addr) {
set_avr_addr(addr); set_avr_addr(addr);
spi_fpga(); spi_fpga();
@ -227,12 +250,17 @@ uint32_t calc_sram_crc(uint32_t base_addr, uint32_t size) {
uint32_t count; uint32_t count;
uint16_t crc; uint16_t crc;
crc=0; crc=0;
crc_valid=1;
set_avr_addr(base_addr); set_avr_addr(base_addr);
spi_fpga(); spi_fpga();
spiTransferByte(0x81); spiTransferByte(0x81);
spiTransferByte(0x00); spiTransferByte(0x00);
for(count=0; count<size; count++) { for(count=0; count<size; count++) {
data = spiTransferByte(0); data = spiTransferByte(0);
if(get_snes_reset()) {
crc_valid = 0;
break;
}
crc += crc16_update(crc, &data, 1); crc += crc16_update(crc, &data, 1);
} }
spi_none(); spi_none();

View File

@ -10,15 +10,18 @@
#define SRAM_CMD_ADDR (0x601004L) #define SRAM_CMD_ADDR (0x601004L)
#define SRAM_FD_ADDR (0x601000L) #define SRAM_FD_ADDR (0x601000L)
#define SRAM_SAVE_ADDR (0x600000L) #define SRAM_SAVE_ADDR (0x600000L)
#define SRAM_SCRATCHPAD (0x7FFFF0L) #define SRAM_SCRATCHPAD (0x7FFF00L)
#define SRAM_DIRID (0x7FFFF0L)
#define SRAM_RELIABILITY_SCORE (0x100) #define SRAM_RELIABILITY_SCORE (0x100)
uint32_t load_rom(uint8_t* filename); uint32_t load_rom(uint8_t* filename);
uint32_t load_sram(uint8_t* filename, uint32_t base_addr); uint32_t load_sram(uint8_t* filename, uint32_t base_addr);
void sram_hexdump(uint32_t addr, uint32_t len); void sram_hexdump(uint32_t addr, uint32_t len);
uint8_t sram_readbyte(uint32_t addr); uint8_t sram_readbyte(uint32_t addr);
uint16_t sram_readshort(uint32_t addr);
uint32_t sram_readlong(uint32_t addr); uint32_t sram_readlong(uint32_t addr);
void sram_writebyte(uint8_t val, uint32_t addr); void sram_writebyte(uint8_t val, uint32_t addr);
void sram_writeshort(uint16_t val, uint32_t addr);
void sram_writelong(uint32_t val, uint32_t addr); void sram_writelong(uint32_t val, uint32_t addr);
void sram_readblock(void* buf, uint32_t addr, uint16_t size); void sram_readblock(void* buf, uint32_t addr, uint16_t size);
void sram_writeblock(void* buf, uint32_t addr, uint16_t size); void sram_writeblock(void* buf, uint32_t addr, uint16_t size);

View File

@ -31,34 +31,60 @@ void snes_init() {
void snes_reset(int state) { void snes_reset(int state) {
if(state) { if(state) {
DDRD |= _BV(PD6); // /RESET pin -> out DDRD |= _BV(PD6); // /RESET pin -> out
PORTD &= ~_BV(PD6); // /RESET = 0 PORTD &= ~_BV(PD6); // /RESET = 0
PORTD |= _BV(PD5); // RESET_DIR = 1; PORTD |= _BV(PD5); // RESET_DIR = 1;
} else { } else {
PORTD &= ~_BV(PD5); // RESET_DIR = 0; PORTD &= ~_BV(PD5); // RESET_DIR = 0;
DDRD &= ~_BV(PD6); // /RESET pin -> in DDRD &= ~_BV(PD6); // /RESET pin -> in
PORTD |= _BV(PD6); // /RESET = 1 PORTD |= _BV(PD6); // /RESET = pullup
} }
} }
/*
* gets the SNES reset state.
*
* returns: 1 when reset, 0 when not reset
*/
uint8_t get_snes_reset() {
// DDRD &= ~_BV(PD6); // /RESET pin -> in
// PORTD &= ~_BV(PD5); // RESET_DIR (external buffer) = 0
return !(PIND & _BV(PD6));
}
/* /*
* SD2SNES main loop. * SD2SNES main loop.
* monitors SRAM changes and other things * monitors SRAM changes and other things
*/ */
uint32_t diffcount = 0, samecount = 0;
void snes_main_loop() { void snes_main_loop() {
if(initloop) { if(initloop) {
saveram_crc_old = calc_sram_crc(saveram_base_addr, saveram_size); saveram_crc_old = calc_sram_crc(saveram_base_addr, saveram_size);
initloop=0; initloop=0;
} }
saveram_crc = calc_sram_crc(saveram_base_addr, saveram_size); saveram_crc = calc_sram_crc(saveram_base_addr, saveram_size);
if(saveram_crc != saveram_crc_old) { if(crc_valid) {
uart_putc('U'); if(saveram_crc != saveram_crc_old) {
uart_puthexshort(saveram_crc); if(samecount) {
uart_putcrlf(); diffcount=1;
set_busy_led(1); } else {
save_sram((uint8_t*)"/test.srm", saveram_size, saveram_base_addr); diffcount++;
set_busy_led(0); }
samecount=0;
}
if(saveram_crc == saveram_crc_old) {
samecount++;
}
if(diffcount>=1 && samecount==3) {
uart_putc('U');
uart_puthexshort(saveram_crc);
uart_putcrlf();
set_busy_led(1);
save_sram((uint8_t*)"/test.srm", saveram_size, saveram_base_addr);
set_busy_led(0);
}
saveram_crc_old = saveram_crc;
} }
saveram_crc_old = saveram_crc; dprintf("valid=%d diffcount=%ld samecount=%ld\n", crc_valid, diffcount, samecount);
} }
/* /*
@ -69,7 +95,12 @@ uint8_t menu_main_loop() {
uint8_t cmd = 0; uint8_t cmd = 0;
sram_writebyte(0, SRAM_CMD_ADDR); sram_writebyte(0, SRAM_CMD_ADDR);
while(!cmd) { while(!cmd) {
cmd = sram_readbyte(SRAM_CMD_ADDR); if(!get_snes_reset()) {
cmd = sram_readbyte(SRAM_CMD_ADDR);
}
if(get_snes_reset()) {
cmd = 0;
}
} }
return cmd; return cmd;
} }

View File

@ -4,9 +4,11 @@
#ifndef SNES_H #ifndef SNES_H
#define SNES_H #define SNES_H
uint8_t crc_valid;
void snes_init(void); void snes_init(void);
void snes_reset(int state); void snes_reset(int state);
uint8_t get_snes_reset(void);
void snes_main_loop(void); void snes_main_loop(void);
uint8_t menu_main_loop(void); uint8_t menu_main_loop(void);
void get_selected_name(uint8_t* lfn); void get_selected_name(uint8_t* lfn);