This commit is contained in:
ikari
2009-09-01 13:43:25 +02:00
parent 6c3cb4c68d
commit 784b47d7ed
20 changed files with 507 additions and 320 deletions

View File

@@ -100,7 +100,7 @@ FORMAT = ihex
TARGET = $(OBJDIR)/sd2snes
# List C source files here. (C dependencies are automatically generated.)
SRC = main.c ff.c utils.c timer.c led.c diskio.c sdcard.c spi.c crc7.c snes.c fpga.c memory.c crc16.c fileops.c
SRC = main.c ff.c utils.c timer.c led.c diskio.c sdcard.c spi.c crc7.c snes.c fpga.c memory.c crc16.c fileops.c fpga_spi.c
ifeq ($(CONFIG_UART_DEBUG),y)
SRC += uart.c

View File

@@ -25,9 +25,9 @@
# This file is included in the main sd2iec Makefile and also parsed
# into autoconf.h.
CONFIG_MCU=atmega644p
CONFIG_MCU=atmega644
CONFIG_LINKER_RELAX=n
CONFIG_MCU_FREQ=14318180
CONFIG_MCU_FREQ=13500000
CONFIG_BOOTLOADER=y
CONFIG_BOOT_DEVID=0x4e534453
CONFIG_UART_DEBUG=y

View File

@@ -6,7 +6,8 @@
FPGA pin mapping
================
PSM:
====
FPGA AVR dir
------------------------
PROG_B PD3 OUT
@@ -14,6 +15,7 @@
CS_B PD7 OUT
INIT_B PB2 IN
RDWR_B PB3 OUT
D7 PC0 OUT
D6 PC1 OUT
D5 PC2 OUT
@@ -23,6 +25,12 @@
D1 PC6 OUT
D0 PC7 OUT
SSM:
====
PROG_B PD3 OUT
CCLK PD4 OUT
INIT_B PD7 IN
DIN PC7 OUT
*/
#include <avr/pgmspace.h>
@@ -33,6 +41,9 @@
#include "diskio.h"
#include "ff.h"
#include "fileops.h"
#include "fpga_spi.h"
#include "spi.h"
#include "avrcompat.h"
DWORD get_fattime(void) {
return 0L;
@@ -71,12 +82,12 @@ void set_cclk(uint8_t val) {
void fpga_init() {
DDRB |= _BV(PB3); // PB3 is output
DDRB &= ~_BV(PB2); // PB2 is input
DDRC = 0xff; // for FPGA config, all PORTC pins are outputs
DDRD &= ~_BV(PD7); // PD7 is input
DDRD |= _BV(PD3) | _BV(PD4) | _BV(PD7); // PD3, PD4, PD7 are outputs
DDRC = _BV(PC7); // for FPGA config, PC7 is output
DDRD |= _BV(PD3) | _BV(PD4); // PD3, PD4 are outputs
set_cclk(0); // initial clk=0
}
@@ -87,23 +98,26 @@ int fpga_get_done(void) {
void fpga_postinit() {
DDRA |= _BV(PA0) | _BV(PA1) | _BV(PA2) | _BV(PA4) | _BV(PA5) | _BV(PA6); // MAPPER+NEXTADDR output
DDRB |= _BV(PB2) | _BV(PB1) | _BV(PB0); // turn PB2 into output, enable AVR_BANK
DDRD |= _BV(PD7); // turn PD7 into output
}
void fpga_pgm(char* filename) {
set_prog_b(0);
uart_putc('P');
set_prog_b(1);
loop_until_bit_is_set(PINB, PB2);
loop_until_bit_is_set(PIND, PD7);
uart_putc('p');
FIL in;
FRESULT res;
// FIL in;
// FRESULT res;
UINT bytes_read;
// open configware file
res=f_open(&in, filename, FA_READ);
if(res) {
// res=f_open(&in, filename, FA_READ);
file_open(filename, FA_READ);
if(file_res) {
uart_putc('?');
uart_putc(0x30+file_res);
return;
}
// file open successful
@@ -111,14 +125,16 @@ void fpga_pgm(char* filename) {
set_rdwr_b(0);
for (;;) {
res = f_read(&in, file_buf, sizeof(file_buf), &bytes_read);
if (res || bytes_read == 0) break; // error or eof
// res = f_read(&in, file_buf, sizeof(file_buf), &bytes_read);
bytes_read = file_read();
if (file_res || bytes_read == 0) break; // error or eof
for(int i=0; i<bytes_read; i++) {
FPGA_SEND_BYTE(file_buf[i]);
//FPGA_SEND_BYTE(file_buf[i]);
FPGA_SEND_BYTE_SERIAL(file_buf[i]);
}
}
f_close(&in);
file_close();
fpga_postinit();
}
@@ -176,8 +192,11 @@ void set_avr_addr_en(uint8_t val) {
}
void set_avr_mapper(uint8_t val) {
PORTA &= 0xF0;
PORTA |= val&0x07;
SPI_SS_HIGH();
FPGA_SS_LOW();
spiTransferByte(0x30 | (val & 0x0f));
FPGA_SS_HIGH();
SPI_SS_LOW();
}
void set_avr_bank(uint8_t val) {

View File

@@ -21,6 +21,11 @@ void set_avr_bank(uint8_t val);
// some macros for bulk transfers (faster)
#define FPGA_SEND_BYTE(data) do {SET_AVR_DATA(data); CCLK();} while (0)
#define FPGA_SEND_BYTE_SERIAL(data) do {SET_AVR_DATA(data); CCLK();\
SET_AVR_DATA(data<<1); CCLK(); SET_AVR_DATA(data<<2); CCLK();\
SET_AVR_DATA(data<<3); CCLK(); SET_AVR_DATA(data<<4); CCLK();\
SET_AVR_DATA(data<<5); CCLK(); SET_AVR_DATA(data<<6); CCLK();\
SET_AVR_DATA(data<<7); CCLK();} while (0)
#define SET_CCLK() do {PORTD |= _BV(PD4);} while (0)
#define CLR_CCLK() do {PORTD &= ~_BV(PD4);} while (0)
#define CCLK() do {SET_CCLK(); CLR_CCLK();} while (0)

View File

@@ -41,3 +41,8 @@ volatile uint8_t led_state;
*/
void update_leds(void) {
}
void toggle_busy_led(void) {
PORTB &= ~_BV(PB1);
DDRB ^= _BV(PB1);
}

View File

@@ -39,6 +39,7 @@ extern volatile uint8_t led_state;
/* Update the LEDs to match the buffer state */
void update_leds(void);
void toggle_busy_led(void);
/* Wrapped in do..while to avoid "ambigious else" warnings */
#ifdef SINGLE_LED

View File

@@ -44,6 +44,7 @@
#include "snes.h"
#include "fileops.h"
#include "memory.h"
#include "fpga_spi.h"
char stringbuf[100];
@@ -152,36 +153,35 @@ int main(void) {
uart_putc('W');
fpga_init();
fpga_pgm("/sd2snes/main.bit");
fpga_spi_init();
uart_putc('!');
_delay_ms(100);
set_avr_bank(0);
//set_avr_bank(0);
set_avr_ena(0);
set_avr_read(1);
set_avr_write(1);
AVR_ADDR_RESET();
set_avr_addr_en(0);
// set_avr_read(1);
// set_avr_write(1);
// AVR_ADDR_RESET();
// set_avr_addr_en(0);
snes_reset(1);
uart_putc('(');
load_rom("/test.smc");
uart_putc(')');
uart_putc('[');
/*XXX uart_putc('[');
load_sram("/test.srm");
uart_putc(']');
uart_putc(']');*/
AVR_ADDR_RESET();
set_avr_mapper(0);
set_avr_mapper(1);
set_avr_ena(1);
set_avr_read(0);
set_avr_bank(0);
_delay_ms(100);
uart_puts_P(PSTR("SNES GO!"));
snes_reset(0);
DDRC = 0x00;
_delay_ms(6553.6);
while(1) {
snes_main_loop();
// snes_main_loop();
}
while(1) {
uint8_t data=PINC;

View File

@@ -10,29 +10,49 @@
#include "crc16.h"
#include "ff.h"
#include "fileops.h"
#include "spi.h"
#include "fpga_spi.h"
#include "avrcompat.h"
#include "led.h"
char* hex = "0123456789ABCDEF";
uint32_t load_rom(char* filename) {
// TODO Mapper, Mirroring, Bankselect
// snes_rom_properties_t romprops;
set_avr_bank(0);
AVR_ADDR_RESET();
SET_AVR_READ();
// set_avr_bank(0);
UINT bytes_read;
DWORD filesize;
UINT count=0;
file_open(filename, FA_READ);
filesize = file_handle.fsize;
if(file_res) return 0;
if(file_res) {
uart_putc('?');
uart_putc(0x30+file_res);
return 0;
}
// snes_rom_id(&romprops, &file_handle);
for(;;) {
FPGA_SS_HIGH();
SPI_SS_LOW();
bytes_read = file_read();
SPI_SS_HIGH();
if (file_res || !bytes_read) break;
for(int j=0; j<bytes_read; j++) {
SET_AVR_DATA(file_buf[j]);
AVR_WRITE();
AVR_NEXTADDR();
FPGA_SS_LOW();
_delay_us(1);
spiTransferByte(0x91); // write w/ increment
if(!(count++ % 16)) {
toggle_busy_led();
}
for(int j=0; j<bytes_read; j++) {
spiTransferByte(file_buf[j]);
// uart_putc((file_buf[j] > 0x20)
// && (file_buf[j] < ('z'+1)) ? file_buf[j]:'.');
// _delay_ms(2);
}
spiTransferByte(0x00); // dummy tx for increment+write pulse
_delay_us(10);
FPGA_SS_HIGH();
}
file_close();
return (uint32_t)filesize;

View File

@@ -536,6 +536,7 @@ DRESULT sd_read(BYTE drv, BYTE *buffer, DWORD sector, BYTE count) {
res = sendCommand(drv, READ_SINGLE_BLOCK, (sector+sec) << 9, 0);
if (res != 0) {
uart_putc('?');
SPI_SS_HIGH(drv);
disk_state = DISK_ERROR;
return RES_ERROR;
@@ -543,6 +544,7 @@ DRESULT sd_read(BYTE drv, BYTE *buffer, DWORD sector, BYTE count) {
// Wait for data token
if (!sdResponse(0xFE)) {
uart_putc('-');
SPI_SS_HIGH(drv);
disk_state = DISK_ERROR;
return RES_ERROR;

View File

@@ -17,7 +17,8 @@ uint32_t sram_crc, sram_crc_old;
uint32_t sram_size = 8192; // sane default
void snes_init() {
DDRD |= _BV(PD5); // PD5 = OUTPUT
DDRD |= _BV(PD5); // PD5 = RESET_DIR
DDRD |= _BV(PD6); // PD6 = RESET
snes_reset(1);
}
@@ -28,9 +29,13 @@ void snes_init() {
*/
void snes_reset(int state) {
if(state) {
PORTD &= ~ _BV(PD5);
DDRD |= _BV(PD6); // /RESET pin -> out
PORTD &= ~_BV(PD6); // /RESET = 0
PORTD |= _BV(PD5); // RESET_DIR = 1;
} else {
PORTD |= _BV(PD5);
PORTD &= ~_BV(PD5); // RESET_DIR = 0;
DDRD &= ~_BV(PD6); // /RESET pin -> in
PORTD |= _BV(PD6); // /RESET = 1
}
}

View File

@@ -67,7 +67,7 @@ void spiInit(void)
// leading edge rising, sample on leading edge, clock = f/4
SPCR = 0b01010000;
// Enable SPI double speed mode -> clock = f/8
// Enable SPI double speed mode -> clock = f/2
SPSR = _BV(SPI2X);
// clear status