update
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
49
src/fpga.c
49
src/fpga.c
@@ -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) {
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -41,3 +41,8 @@ volatile uint8_t led_state;
|
||||
*/
|
||||
void update_leds(void) {
|
||||
}
|
||||
|
||||
void toggle_busy_led(void) {
|
||||
PORTB &= ~_BV(PB1);
|
||||
DDRB ^= _BV(PB1);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
26
src/main.c
26
src/main.c
@@ -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;
|
||||
|
||||
36
src/memory.c
36
src/memory.c
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
11
src/snes.c
11
src/snes.c
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user