From a9b84c3e0bd4689d91e0295ab1f02c6641a7f01f Mon Sep 17 00:00:00 2001 From: ikari Date: Mon, 6 Sep 2010 23:51:48 +0200 Subject: [PATCH] archive MK1 AVR source --- cic/supercic/supercic-key.asm | 2 + mk1-src/Makefile | 619 ++++++++++++++++++++++++++++++++++ {src => mk1-src}/avrcompat.h | 0 mk1-src/conf2h.awk | 29 ++ mk1-src/config | 47 +++ {src => mk1-src}/config.h | 0 {src => mk1-src}/crc16.c | 0 {src => mk1-src}/crc16.h | 0 {src => mk1-src}/crc32.c | 0 {src => mk1-src}/crc32.h | 0 {src => mk1-src}/crc7.c | 0 {src => mk1-src}/crc7.h | 0 {src => mk1-src}/crcgen-new.c | 0 {src => mk1-src}/diskio.c | 0 {src => mk1-src}/diskio.h | 0 {src => mk1-src}/eeprom.c | 0 {src => mk1-src}/eeprom.h | 0 {src => mk1-src}/ff.c | 0 {src => mk1-src}/ff.h | 0 {src => mk1-src}/fileops.c | 0 {src => mk1-src}/fileops.h | 0 {src => mk1-src}/filetypes.c | 0 {src => mk1-src}/filetypes.h | 0 {src => mk1-src}/fpga.c | 0 {src => mk1-src}/fpga.h | 0 {src => mk1-src}/fpga_spi.c | 0 {src => mk1-src}/fpga_spi.h | 0 {src => mk1-src}/gcctest.awk | 0 {src => mk1-src}/integer.h | 0 {src => mk1-src}/led.c | 0 {src => mk1-src}/led.h | 0 mk1-src/main.c | 400 ++++++++++++++++++++++ {src => mk1-src}/memory.c | 0 {src => mk1-src}/memory.h | 0 {src => mk1-src}/sdcard.c | 0 {src => mk1-src}/sdcard.h | 0 {src => mk1-src}/smc.c | 0 {src => mk1-src}/smc.h | 0 {src => mk1-src}/snes.c | 0 {src => mk1-src}/snes.h | 0 {src => mk1-src}/spi.c | 0 {src => mk1-src}/spi.h | 0 {src => mk1-src}/src2doxy.pl | 0 {src => mk1-src}/time.h | 0 {src => mk1-src}/timer.c | 0 {src => mk1-src}/timer.h | 0 {src => mk1-src}/uart.c | 0 {src => mk1-src}/uart.h | 0 {src => mk1-src}/ustring.h | 0 {src => mk1-src}/utils.c | 0 {src => mk1-src}/utils.h | 0 src/Makefile | 406 +++------------------- src/config | 48 +-- src/main.c | 462 ++++--------------------- 54 files changed, 1220 insertions(+), 793 deletions(-) create mode 100644 mk1-src/Makefile rename {src => mk1-src}/avrcompat.h (100%) create mode 100644 mk1-src/conf2h.awk create mode 100644 mk1-src/config rename {src => mk1-src}/config.h (100%) rename {src => mk1-src}/crc16.c (100%) rename {src => mk1-src}/crc16.h (100%) rename {src => mk1-src}/crc32.c (100%) rename {src => mk1-src}/crc32.h (100%) rename {src => mk1-src}/crc7.c (100%) rename {src => mk1-src}/crc7.h (100%) rename {src => mk1-src}/crcgen-new.c (100%) rename {src => mk1-src}/diskio.c (100%) rename {src => mk1-src}/diskio.h (100%) rename {src => mk1-src}/eeprom.c (100%) rename {src => mk1-src}/eeprom.h (100%) rename {src => mk1-src}/ff.c (100%) rename {src => mk1-src}/ff.h (100%) rename {src => mk1-src}/fileops.c (100%) rename {src => mk1-src}/fileops.h (100%) rename {src => mk1-src}/filetypes.c (100%) rename {src => mk1-src}/filetypes.h (100%) rename {src => mk1-src}/fpga.c (100%) rename {src => mk1-src}/fpga.h (100%) rename {src => mk1-src}/fpga_spi.c (100%) rename {src => mk1-src}/fpga_spi.h (100%) rename {src => mk1-src}/gcctest.awk (100%) rename {src => mk1-src}/integer.h (100%) rename {src => mk1-src}/led.c (100%) rename {src => mk1-src}/led.h (100%) create mode 100644 mk1-src/main.c rename {src => mk1-src}/memory.c (100%) rename {src => mk1-src}/memory.h (100%) rename {src => mk1-src}/sdcard.c (100%) rename {src => mk1-src}/sdcard.h (100%) rename {src => mk1-src}/smc.c (100%) rename {src => mk1-src}/smc.h (100%) rename {src => mk1-src}/snes.c (100%) rename {src => mk1-src}/snes.h (100%) rename {src => mk1-src}/spi.c (100%) rename {src => mk1-src}/spi.h (100%) rename {src => mk1-src}/src2doxy.pl (100%) rename {src => mk1-src}/time.h (100%) rename {src => mk1-src}/timer.c (100%) rename {src => mk1-src}/timer.h (100%) rename {src => mk1-src}/uart.c (100%) rename {src => mk1-src}/uart.h (100%) rename {src => mk1-src}/ustring.h (100%) rename {src => mk1-src}/utils.c (100%) rename {src => mk1-src}/utils.h (100%) diff --git a/cic/supercic/supercic-key.asm b/cic/supercic/supercic-key.asm index 8bbb6c6..99980fe 100644 --- a/cic/supercic/supercic-key.asm +++ b/cic/supercic/supercic-key.asm @@ -673,6 +673,8 @@ longwait0 ; --------change region in eeprom and die-------- die + movlw 0x3a ;wait 50ms before writing + call longwait ;("error" might be due to power loss) banksel EEADR clrw movwf EEADR diff --git a/mk1-src/Makefile b/mk1-src/Makefile new file mode 100644 index 0000000..1aa2435 --- /dev/null +++ b/mk1-src/Makefile @@ -0,0 +1,619 @@ +# Hey Emacs, this is a -*- makefile -*- + +# Define version number +MAJOR = 0 +MINOR = 0 +PATCHLEVEL = 1 +FIX = + +# Forces bootloader version to 0, comment out for release +#PRERELEASE = + +#---------------------------------------------------------------------------- +# WinAVR Makefile Template written by Eric B. Weddington, Joerg Wunsch, et al. +# +# Released to the Public Domain +# +# Additional material for this makefile was written by: +# Peter Fleury +# Tim Henigan +# Colin O'Flynn +# Reiner Patommel +# Markus Pfaff +# Sander Pool +# Frederik Rouleau +# Carlos Lamas +# +# +# Extensively modified for sd2iec by Ingo Korb +# +# To rebuild project do "make clean" then "make all". +#---------------------------------------------------------------------------- + +# Read configuration file +ifdef CONFIG + CONFIGSUFFIX = $(CONFIG:config%=%) +else + CONFIG = config + CONFIGSUFFIX = +endif + +# Enable verbose compilation with "make V=1" +ifdef V + Q := + E := @: +else + Q := @ + E := @echo +endif + +# Include the configuration file +include $(CONFIG) + +# Set MCU name and length of binary for bootloader +# WARNING: Fuse settings not tested! +MCU := $(CONFIG_MCU) +ifeq ($(MCU),atmega128) + BINARY_LENGTH = 0x1f000 +# EFUSE = 0xff +# HFUSE = 0x91 +# LFUSE = 0xaf +else ifeq ($(MCU),atmega1281) + BINARY_LENGTH = 0x1f000 + BOOTLDRSIZE = 0x0800 + EFUSE = 0xff + HFUSE = 0xd2 + LFUSE = 0xfc +else ifeq ($(MCU),atmega2561) + BINARY_LENGTH = 0x3f000 + EFUSE = 0xfd + HFUSE = 0x93 + LFUSE = 0xef +else ifeq ($(MCU),atmega644) + BINARY_LENGTH = 0xf000 + EFUSE = 0xfd + HFUSE = 0x91 +# LFUSE = 0xef + LFUSE = 0xaf +else ifeq ($(MCU),atmega644p) + BINARY_LENGTH = 0xf000 + EFUSE = 0xfd + HFUSE = 0x91 + LFUSE = 0xef +else +.PHONY: nochip +nochip: + @echo '==============================================================' + @echo 'No known target chip specified.' + @echo + @echo 'Please edit the Makefile.' + @exit 1 +endif + +# Directory for all generated files +OBJDIR := obj-$(CONFIG_MCU:atmega%=m%)$(CONFIGSUFFIX) + +# Output format. (can be srec, ihex, binary) +FORMAT = ihex + + +# Target file name (without extension). +TARGET = $(OBJDIR)/sd2snes + +# List C source files here. (C dependencies are automatically generated.) +SRC = main.c ff.c utils.c led.c diskio.c sdcard.c spi.c crc7.c snes.c fpga.c memory.c crc16.c fileops.c fpga_spi.c smc.c filetypes.c + +ifeq ($(CONFIG_UART_DEBUG),y) + SRC += uart.c +endif + +# List Assembler source files here. +# Make them always end in a capital .S. Files ending in a lowercase .s +# will not be considered source files but generated files (assembler +# output from the compiler), and will be deleted upon "make clean"! +# Even though the DOS/Win* filesystem matches both .s and .S the same, +# it will preserve the spelling of the filenames, and gcc itself does +# care about how the name is spelled on its command-line. +ASRC = + +# Optimization level, can be [0, 1, 2, 3, s]. +# 0 = turn off optimization. s = optimize for size. +# (Note: 3 is not always the best optimization level. See avr-libc FAQ.) +# Use s -mcall-prologues when you really need size... +OPT = s +#OPT = 3 -finline-functions + +# Debugging format. +# Native formats for AVR-GCC's -g are dwarf-2 [default] or stabs. +# AVR Studio 4.10 requires dwarf-2. +# AVR [Extended] COFF format requires stabs, plus an avr-objcopy run. +DEBUG = dwarf-2 + + +# List any extra directories to look for include files here. +# Each directory must be seperated by a space. +# Use forward slashes for directory separators. +# For a directory that has spaces, enclose it in quotes. +EXTRAINCDIRS = + + +# Compiler flag to set the C Standard level. +# c89 = "ANSI" C +# gnu89 = c89 plus GCC extensions +# c99 = ISO C99 standard (not yet fully implemented) +# gnu99 = c99 plus GCC extensions +CSTANDARD = -std=gnu99 + + +# Place -D or -U options here +CDEFS = -DF_CPU=$(CONFIG_MCU_FREQ)UL + +# Calculate bootloader version +ifdef PRERELEASE +BOOT_VERSION := 0 +else +BOOT_VERSION := 0x$(MAJOR)$(MINOR)$(PATCHLEVEL)$(FIX) +endif + +# Create a version number define +ifdef PATCHLEVEL +ifdef FIX +PROGRAMVERSION := $(MAJOR).$(MINOR).$(PATCHLEVEL).$(FIX) +else +PROGRAMVERSION := $(MAJOR).$(MINOR).$(PATCHLEVEL) +BOOT_VERSION := $(BOOT_VERSION)0 +endif +else +PROGRAMVERSION := $(MAJOR).$(MINOR) +BOOT_VERSION := $(BOOT_VERSION)00 +endif + +ifdef PRERELEASE +PROGRAMVERSION := $(PROGRAMVERSION)$(PRERELEASE) +endif + +LONGVERSION := -$(CONFIG_MCU:atmega%=m%)$(CONFIGSUFFIX) + +CDEFS += -DVERSION=\"$(PROGRAMVERSION)\" -DLONGVERSION=\"$(LONGVERSION)\" + +# Place -I options here +CINCS = + + +# Define programs and commands. +# CC must be defined here to generate the correct CFLAGS +SHELL = sh +CC = avr-gcc +OBJCOPY = avr-objcopy +OBJDUMP = avr-objdump +SIZE = avr-size +NM = avr-nm +AVRDUDE = avrdude +REMOVE = rm -f +COPY = cp +WINSHELL = cmd + + +#---------------- Compiler Options ---------------- +# -g*: generate debugging information +# -O*: optimization level +# -f...: tuning, see GCC manual and avr-libc documentation +# -Wall...: warning level +# -Wa,...: tell GCC to pass this to the assembler. +# -adhlns...: create assembler listing +CFLAGS = -g$(DEBUG) +CFLAGS += $(CDEFS) $(CINCS) +CFLAGS += -O$(OPT) +CFLAGS += -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums +CFLAGS += -Wall -Wstrict-prototypes -Werror +CFLAGS += -Wa,-adhlns=$(OBJDIR)/$(<:.c=.lst) +CFLAGS += -I$(OBJDIR) +CFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS)) +CFLAGS += $(CSTANDARD) +CFLAGS += -ffunction-sections -fdata-sections +#CFLAGS += -mcall-prologues + +# these are needed for GCC 4.3.2, which is more aggressive at inlining +# gcc-4.2 knows one of those, but it tends to increase code size +ifeq ($(shell $(CC) --version|gawk -f gcctest.awk),YES) +CFLAGS += --param inline-call-cost=3 +CFLAGS += -fno-inline-small-functions +CFLAGS += -fno-move-loop-invariants +CFLAGS += -fno-split-wide-types + +# turn these on to keep the functions in the same order as in the source +# this is only useful if you're looking at disassembly +#CFLAGS += -fno-reorder-blocks +#CFLAGS += -fno-reorder-blocks-and-partition +#CFLAGS += -fno-reorder-functions +#CFLAGS += -fno-toplevel-reorder +endif + +ifeq ($(CONFIG_STACK_TRACKING),y) + CFLAGS += -finstrument-functions +endif + + +#---------------- Assembler Options ---------------- +# -Wa,...: tell GCC to pass this to the assembler. +# -ahlms: create listing +# -gstabs: have the assembler create line number information; note that +# for use in COFF files, additional information about filenames +# and function names needs to be present in the assembler source +# files -- see avr-libc docs [FIXME: not yet described there] +ASFLAGS = -Wa,-adhlns=$(OBJDIR)/$(<:.S=.lst),-gstabs -I$(OBJDIR) + + +#---------------- Library Options ---------------- +# Minimalistic printf version +PRINTF_LIB_MIN = -Wl,-u,vfprintf -lprintf_min + +# Floating point printf version (requires MATH_LIB = -lm below) +PRINTF_LIB_FLOAT = -Wl,-u,vfprintf -lprintf_flt + +# If this is left blank, then it will use the Standard printf version. +PRINTF_LIB = +#PRINTF_LIB = $(PRINTF_LIB_MIN) +#PRINTF_LIB = $(PRINTF_LIB_FLOAT) + + +# Minimalistic scanf version +SCANF_LIB_MIN = -Wl,-u,vfscanf -lscanf_min + +# Floating point + %[ scanf version (requires MATH_LIB = -lm below) +SCANF_LIB_FLOAT = -Wl,-u,vfscanf -lscanf_flt + +# If this is left blank, then it will use the Standard scanf version. +SCANF_LIB = +#SCANF_LIB = $(SCANF_LIB_MIN) +#SCANF_LIB = $(SCANF_LIB_FLOAT) + + +MATH_LIB = -lm + + + +#---------------- External Memory Options ---------------- + +# 64 KB of external RAM, starting after internal RAM (ATmega128!), +# used for variables (.data/.bss) and heap (malloc()). +#EXTMEMOPTS = -Wl,-Tdata=0x801100,--defsym=__heap_end=0x80ffff + +# 64 KB of external RAM, starting after internal RAM (ATmega128!), +# only used for heap (malloc()). +#EXTMEMOPTS = -Wl,--defsym=__heap_start=0x801100,--defsym=__heap_end=0x80ffff + +EXTMEMOPTS = + + + +#---------------- Linker Options ---------------- +# -Wl,...: tell GCC to pass this to linker. +# -Map: create map file +# --cref: add cross reference to map file +LDFLAGS = -Wl,-Map=$(TARGET).map,--cref +LDFLAGS += $(EXTMEMOPTS) +LDFLAGS += $(PRINTF_LIB) $(SCANF_LIB) $(MATH_LIB) +LDFLAGS += -Wl,--gc-sections +ifeq ($(CONFIG_LINKER_RELAX),y) + LDFLAGS += -Wl,-O9,--relax +endif + + + +#---------------- Programming Options (avrdude) ---------------- + +# Programming hardware: alf avr910 avrisp bascom bsd +# dt006 pavr picoweb pony-stk200 sp12 stk200 stk500 stk500v2 +# +# Type: avrdude -c ? +# to get a full listing. +# +AVRDUDE_PROGRAMMER = dragon_isp + +# com1 = serial port. Use lpt1 to connect to parallel port. +AVRDUDE_PORT = usb # programmer connected to serial device + +AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex +# AVRDUDE_WRITE_EEPROM = -U eeprom:w:$(TARGET).eep + +# Allow fuse overrides from the config file +ifdef CONFIG_EFUSE + EFUSE := CONFIG_EFUSE +endif +ifdef CONFIG_HFUSE + HFUSE := CONFIG_HFUSE +endif +ifdef CONFIG_LFUSE + LFUSE := CONFIG_LFUSE +endif + +# Calculate command line arguments for fuses +AVRDUDE_WRITE_FUSES := +ifdef EFUSE + AVRDUDE_WRITE_FUSES += -U efuse:w:$(EFUSE):m +endif +ifdef HFUSE + AVRDUDE_WRITE_FUSES += -U hfuse:w:$(HFUSE):m +endif +ifdef LFUSE + AVRDUDE_WRITE_FUSES += -U lfuse:w:$(LFUSE):m +endif + + +# Uncomment the following if you want avrdude's erase cycle counter. +# Note that this counter needs to be initialized first using -Yn, +# see avrdude manual. +AVRDUDE_ERASE_COUNTER = -y + +# Uncomment the following if you do /not/ wish a verification to be +# performed after programming the device. +#AVRDUDE_NO_VERIFY = -V + +# Increase verbosity level. Please use this when submitting bug +# reports about avrdude. See +# to submit bug reports. +#AVRDUDE_VERBOSE = -v -v + +AVRDUDE_FLAGS = -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER) +AVRDUDE_FLAGS += $(AVRDUDE_NO_VERIFY) +AVRDUDE_FLAGS += $(AVRDUDE_VERBOSE) +AVRDUDE_FLAGS += $(AVRDUDE_ERASE_COUNTER) + + + +#---------------- Debugging Options ---------------- + +# For simulavr only - target MCU frequency. +DEBUG_MFREQ = $(CONFIG_MCU_FREQ) + +# Set the DEBUG_UI to either gdb or insight. +# DEBUG_UI = gdb +DEBUG_UI = insight + +# Set the debugging back-end to either avarice, simulavr. +DEBUG_BACKEND = avarice +#DEBUG_BACKEND = simulavr + +# GDB Init Filename. +GDBINIT_FILE = __avr_gdbinit + +# When using avarice settings for the JTAG +JTAG_DEV = /dev/com1 + +# Debugging port used to communicate between GDB / avarice / simulavr. +DEBUG_PORT = 4242 + +# Debugging host used to communicate between GDB / avarice / simulavr, normally +# just set to localhost unless doing some sort of crazy debugging when +# avarice is running on a different computer. +DEBUG_HOST = localhost + + + +#============================================================================ + + +# De-dupe the list of C source files +CSRC := $(sort $(SRC)) + +# Define all object files. +OBJ := $(patsubst %,$(OBJDIR)/%,$(CSRC:.c=.o) $(ASRC:.S=.o)) + +# Define all listing files. +LST := $(patsubst %,$(OBJDIR)/%,$(CSRC:.c=.lst) $(ASRC:.S=.lst)) + + +# Compiler flags to generate dependency files. +GENDEPFLAGS = -MMD -MP -MF .dep/$(@F).d + + +# Combine all necessary flags and optional flags. +# Add target processor to flags. +ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS) $(GENDEPFLAGS) +ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS) $(CDEFS) + + + + + +# Default target. +all: build + +build: elf bin hex + $(E) " SIZE $(TARGET).elf" + $(Q)$(ELFSIZE)|grep -v debug + +elf: $(TARGET).elf +bin: $(TARGET).bin +hex: $(TARGET).hex +eep: $(TARGET).eep +lss: $(TARGET).lss +sym: $(TARGET).sym + +# A little helper target for the maintainer =) +copy2card: + mount /mnt + cp $(TARGET).bin /mnt + umount /mnt + sync + + +# Doxygen output: +doxygen: + -rm -rf doxyinput + mkdir doxyinput + cp *.h *.c doxyinput + src2doxy.pl doxyinput/*.h doxyinput/*.c + doxygen doxygen.conf + +# Display size of file. +HEXSIZE = $(SIZE) --target=$(FORMAT) $(TARGET).hex +ELFSIZE = $(SIZE) -A $(TARGET).elf +AVRMEM = avr-mem.sh $(TARGET).elf $(MCU) + +# Program the device. +program: bin hex eep + $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) $(AVRDUDE_WRITE_EEPROM) + +# Set fuses of the device +fuses: $(CONFIG) + $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FUSES) + +# Generate avr-gdb config/init file which does the following: +# define the reset signal, load the target file, connect to target, and set +# a breakpoint at main(). +gdb-config: + @$(REMOVE) $(GDBINIT_FILE) + @echo define reset >> $(GDBINIT_FILE) + @echo SIGNAL SIGHUP >> $(GDBINIT_FILE) + @echo end >> $(GDBINIT_FILE) + @echo file $(TARGET).elf >> $(GDBINIT_FILE) + @echo target remote $(DEBUG_HOST):$(DEBUG_PORT) >> $(GDBINIT_FILE) +ifeq ($(DEBUG_BACKEND),simulavr) + @echo load >> $(GDBINIT_FILE) +endif + @echo break main >> $(GDBINIT_FILE) + +debug: gdb-config $(TARGET).elf +ifeq ($(DEBUG_BACKEND), avarice) + @echo Starting AVaRICE - Press enter when "waiting to connect" message displays. + @$(WINSHELL) /c start avarice --jtag $(JTAG_DEV) --erase --program --file \ + $(TARGET).elf $(DEBUG_HOST):$(DEBUG_PORT) + @$(WINSHELL) /c pause + +else + @$(WINSHELL) /c start simulavr --gdbserver --device $(MCU) --clock-freq \ + $(DEBUG_MFREQ) --port $(DEBUG_PORT) +endif + @$(WINSHELL) /c start avr-$(DEBUG_UI) --command=$(GDBINIT_FILE) + + + + +# Convert ELF to COFF for use in debugging / simulating in AVR Studio or VMLAB. +COFFCONVERT=$(OBJCOPY) --debugging \ +--change-section-address .data-0x800000 \ +--change-section-address .bss-0x800000 \ +--change-section-address .noinit-0x800000 \ +--change-section-address .eeprom-0x810000 + + +coff: $(TARGET).elf + $(COFFCONVERT) -O coff-avr $< $(TARGET).cof + + +extcoff: $(TARGET).elf + $(COFFCONVERT) -O coff-ext-avr $< $(TARGET).cof + + +# Generate autoconf.h from config +.PRECIOUS : $(OBJDIR)/autoconf.h +$(OBJDIR)/autoconf.h: $(CONFIG) | $(OBJDIR) + $(E) " CONF2H $(CONFIG)" + $(Q)gawk -f conf2h.awk $(CONFIG) > $(OBJDIR)/autoconf.h + +# Create final output files (.hex, .eep) from ELF output file. +ifeq ($(CONFIG_BOOTLOADER),y) +$(OBJDIR)/%.bin: $(OBJDIR)/%.elf + $(E) " BIN $@" + $(Q)$(OBJCOPY) -O binary -R .eeprom $< $@ + $(E) " CRCGEN $@" + -$(Q)crcgen-new $@ $(BINARY_LENGTH) $(CONFIG_BOOT_DEVID) $(BOOT_VERSION) + $(E) " COPY $(CONFIG_HARDWARE_NAME)-firmware-$(PROGRAMVERSION).bin" + $(Q)$(COPY) $@ $(OBJDIR)/$(CONFIG_HARDWARE_NAME)-firmware-$(PROGRAMVERSION).bin +else +$(OBJDIR)/%.bin: $(OBJDIR)/%.elf + $(E) " BIN $@" + $(Q)$(OBJCOPY) -O binary -R .eeprom $< $@ +endif + + +$(OBJDIR)/%.hex: $(OBJDIR)/%.elf + $(E) " HEX $@" + $(Q)$(OBJCOPY) -O $(FORMAT) -R .eeprom $< $@ + +$(OBJDIR)/%.eep: $(OBJDIR)/%.elf + -$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \ + --change-section-lma .eeprom=0 -O $(FORMAT) $< $@ + +# Create extended listing file from ELF output file. +$(OBJDIR)/%.lss: $(OBJDIR)/%.elf + $(E) " LSS $<" + $(Q)$(OBJDUMP) -h -S $< > $@ + +# Create a symbol table from ELF output file. +$(OBJDIR)/%.sym: $(OBJDIR)/%.elf + $(E) " SYM $<" + $(E)$(NM) -n $< > $@ + + + +# Link: create ELF output file from object files. +.SECONDARY : $(TARGET).elf +.PRECIOUS : $(OBJ) +$(OBJDIR)/%.elf: $(OBJ) + $(E) " LINK $@" + $(Q)$(CC) $(ALL_CFLAGS) $^ --output $@ $(LDFLAGS) + + +# Compile: create object files from C source files. +$(OBJDIR)/%.o : %.c | $(OBJDIR) $(OBJDIR)/autoconf.h + $(E) " CC $<" + $(Q)$(CC) -c $(ALL_CFLAGS) $< -o $@ + + +# Compile: create assembler files from C source files. +$(OBJDIR)/%.s : %.c | $(OBJDIR) $(OBJDIR)/autoconf.h + $(CC) -S $(ALL_CFLAGS) $< -o $@ + + +# Assemble: create object files from assembler source files. +$(OBJDIR)/%.o : %.S | $(OBJDIR) $(OBJDIR)/autoconf.h + $(E) " AS $<" + $(Q)$(CC) -c $(ALL_ASFLAGS) $< -o $@ + +# Create preprocessed source for use in sending a bug report. +$(OBJDIR)/%.i : %.c | $(OBJDIR) $(OBJDIR)/autoconf.h + $(CC) -E -mmcu=$(MCU) -I. $(CFLAGS) $< -o $@ + +# Create the output directory +$(OBJDIR): + $(E) " MKDIR $(OBJDIR)" + $(Q)mkdir $(OBJDIR) + +# Target: clean project. +clean: begin clean_list end + +clean_list : + $(E) " CLEAN" + $(Q)$(REMOVE) $(TARGET).hex + $(Q)$(REMOVE) $(TARGET).bin + $(Q)$(REMOVE) $(TARGET).eep + $(Q)$(REMOVE) $(TARGET).cof + $(Q)$(REMOVE) $(TARGET).elf + $(Q)$(REMOVE) $(TARGET).map + $(Q)$(REMOVE) $(TARGET).sym + $(Q)$(REMOVE) $(TARGET).lss + $(Q)$(REMOVE) $(OBJ) + $(Q)$(REMOVE) $(OBJDIR)/autoconf.h + $(Q)$(REMOVE) $(OBJDIR)/*.bin + $(Q)$(REMOVE) $(LST) + $(Q)$(REMOVE) $(CSRC:.c=.s) + $(Q)$(REMOVE) $(CSRC:.c=.d) + $(Q)$(REMOVE) .dep/* + $(Q)$(REMOVE) -rf codedoc + $(Q)$(REMOVE) -rf doxyinput + -$(Q)rmdir $(OBJDIR) + +# Include the dependency files. +-include $(shell mkdir .dep 2>/dev/null) $(wildcard .dep/*) + +# Manual dependency for the assembler module +# $(OBJDIR)/fastloader-ll.o: config.h $(OBJDIR)/autoconf.h + +# Listing of phony targets. +.PHONY : all begin finish end sizebefore sizeafter gccversion \ +build elf hex eep lss sym coff extcoff \ +clean clean_list program debug gdb-config doxygen + diff --git a/src/avrcompat.h b/mk1-src/avrcompat.h similarity index 100% rename from src/avrcompat.h rename to mk1-src/avrcompat.h diff --git a/mk1-src/conf2h.awk b/mk1-src/conf2h.awk new file mode 100644 index 0000000..3818f89 --- /dev/null +++ b/mk1-src/conf2h.awk @@ -0,0 +1,29 @@ +#! /usr/bin/gawk -f + +# Trivial little script to convert from a makefile-style configuration +# file to a C header. No copyright claimed. + +BEGIN { + print "// autoconf.h generated from " ARGV[1] " at " strftime() "\n" \ + "#ifndef AUTOCONF_H\n" \ + "#define AUTOCONF_H" +} + +/^#/ { sub(/^#/,"//") } + +/^CONFIG_.*=/ { + if (/=n$/) { + sub(/^/,"// "); + } else { + sub(/^/,"#define ") + if (/=y$/) { + sub(/=.*$/,"") + } else { + sub(/=/," ") + } + } +} + +{ print } + +END { print "#endif" } diff --git a/mk1-src/config b/mk1-src/config new file mode 100644 index 0000000..4655c16 --- /dev/null +++ b/mk1-src/config @@ -0,0 +1,47 @@ +# This may not look like it, but it's a -*- makefile -*- +# sd2snes - SD card based universal cartridge for the SNES +# Copyright (C) 2009-2010 Maximilian Rehkopf +# +# This file was adapted from sd2iec, written by Ingo Korb. +# Original disclaimer follows: +# +# sd2iec - SD/MMC to Commodore serial bus interface/controller +# Copyright (C) 2007-2009 Ingo Korb +# +# Inspiration and low-level SD/MMC access based on code from MMC2IEC +# by Lars Pontoppidan et al., see sdcard.c|h and config.h. +# +# FAT filesystem access based on code from ChaN, see tff.c|h. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; version 2 of the License only. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# +# This file is included in the main sd2iec Makefile and also parsed +# into autoconf.h. + +CONFIG_MCU=atmega644 +CONFIG_LINKER_RELAX=n +CONFIG_MCU_FREQ=12288000 +CONFIG_BOOTLOADER=y +CONFIG_BOOT_DEVID=0x4e534453 +CONFIG_UART_DEBUG=y +CONFIG_UART_BAUDRATE=384000 +CONFIG_UART_BUF_SHIFT=7 +CONFIG_HARDWARE_NAME=sd2snes +CONFIG_SD_AUTO_RETRIES=10 +#CONFIG_SD_DATACRC=y +CONFIG_EEPROM_SIZE=512 +CONFIG_EEPROM_OFFSET=512 +CONFIG_MAX_PARTITIONS=1 +#CONFIG_DEADLOCK_ME_HARDER=y diff --git a/src/config.h b/mk1-src/config.h similarity index 100% rename from src/config.h rename to mk1-src/config.h diff --git a/src/crc16.c b/mk1-src/crc16.c similarity index 100% rename from src/crc16.c rename to mk1-src/crc16.c diff --git a/src/crc16.h b/mk1-src/crc16.h similarity index 100% rename from src/crc16.h rename to mk1-src/crc16.h diff --git a/src/crc32.c b/mk1-src/crc32.c similarity index 100% rename from src/crc32.c rename to mk1-src/crc32.c diff --git a/src/crc32.h b/mk1-src/crc32.h similarity index 100% rename from src/crc32.h rename to mk1-src/crc32.h diff --git a/src/crc7.c b/mk1-src/crc7.c similarity index 100% rename from src/crc7.c rename to mk1-src/crc7.c diff --git a/src/crc7.h b/mk1-src/crc7.h similarity index 100% rename from src/crc7.h rename to mk1-src/crc7.h diff --git a/src/crcgen-new.c b/mk1-src/crcgen-new.c similarity index 100% rename from src/crcgen-new.c rename to mk1-src/crcgen-new.c diff --git a/src/diskio.c b/mk1-src/diskio.c similarity index 100% rename from src/diskio.c rename to mk1-src/diskio.c diff --git a/src/diskio.h b/mk1-src/diskio.h similarity index 100% rename from src/diskio.h rename to mk1-src/diskio.h diff --git a/src/eeprom.c b/mk1-src/eeprom.c similarity index 100% rename from src/eeprom.c rename to mk1-src/eeprom.c diff --git a/src/eeprom.h b/mk1-src/eeprom.h similarity index 100% rename from src/eeprom.h rename to mk1-src/eeprom.h diff --git a/src/ff.c b/mk1-src/ff.c similarity index 100% rename from src/ff.c rename to mk1-src/ff.c diff --git a/src/ff.h b/mk1-src/ff.h similarity index 100% rename from src/ff.h rename to mk1-src/ff.h diff --git a/src/fileops.c b/mk1-src/fileops.c similarity index 100% rename from src/fileops.c rename to mk1-src/fileops.c diff --git a/src/fileops.h b/mk1-src/fileops.h similarity index 100% rename from src/fileops.h rename to mk1-src/fileops.h diff --git a/src/filetypes.c b/mk1-src/filetypes.c similarity index 100% rename from src/filetypes.c rename to mk1-src/filetypes.c diff --git a/src/filetypes.h b/mk1-src/filetypes.h similarity index 100% rename from src/filetypes.h rename to mk1-src/filetypes.h diff --git a/src/fpga.c b/mk1-src/fpga.c similarity index 100% rename from src/fpga.c rename to mk1-src/fpga.c diff --git a/src/fpga.h b/mk1-src/fpga.h similarity index 100% rename from src/fpga.h rename to mk1-src/fpga.h diff --git a/src/fpga_spi.c b/mk1-src/fpga_spi.c similarity index 100% rename from src/fpga_spi.c rename to mk1-src/fpga_spi.c diff --git a/src/fpga_spi.h b/mk1-src/fpga_spi.h similarity index 100% rename from src/fpga_spi.h rename to mk1-src/fpga_spi.h diff --git a/src/gcctest.awk b/mk1-src/gcctest.awk similarity index 100% rename from src/gcctest.awk rename to mk1-src/gcctest.awk diff --git a/src/integer.h b/mk1-src/integer.h similarity index 100% rename from src/integer.h rename to mk1-src/integer.h diff --git a/src/led.c b/mk1-src/led.c similarity index 100% rename from src/led.c rename to mk1-src/led.c diff --git a/src/led.h b/mk1-src/led.h similarity index 100% rename from src/led.h rename to mk1-src/led.h diff --git a/mk1-src/main.c b/mk1-src/main.c new file mode 100644 index 0000000..ed24028 --- /dev/null +++ b/mk1-src/main.c @@ -0,0 +1,400 @@ +/* sd2snes - SD card based universal cartridge for the SNES + Copyright (C) 2009-2010 Maximilian Rehkopf + AVR firmware portion + + Inspired by and based on code from sd2iec, written by Ingo Korb et al. + See sdcard.c|h, config.h. + + FAT file system access based on code by ChaN, Jim Brain, Ingo Korb, + see ff.c|h. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 of the License only. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + main.c: initialization and flow +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "config.h" +#include "diskio.h" +#include "ff.h" +#include "led.h" +/* #include "timer.h" */ +#include "fpga.h" +#include "uart.h" +#include "ustring.h" +#include "utils.h" +#include "snes.h" +#include "fileops.h" +#include "memory.h" +#include "fpga_spi.h" +#include "spi.h" +#include "avrcompat.h" +#include "filetypes.h" +#include "sdcard.h" + +void writetest(void) { +// HERE BE LIONS, GET IN THE CAR + char teststring[58]; + while(1) { + sram_writeblock((void*)"Testtext of DOOM!!1! 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ", SRAM_SCRATCHPAD+0x20, 58); + sram_readblock((void*)teststring, SRAM_SCRATCHPAD+0x20, 58); + teststring[57]=0; + dprintf("%s\n", teststring); + } +// END OF LIONS +} + + +void memtest(void) { +/* HERE BE DRAGONS */ + uint32_t dbg_i; + for(dbg_i=0; dbg_i < 65536; dbg_i++) { + sram_writeshort((uint16_t)dbg_i&0xffff, dbg_i*2); + } + save_sram((uint8_t*)"/sd2snes/memtest", 0x20000, 0); + set_pwr_led(0); + while(1); +/* END OF DRAGONS */ +} + + +/* Make sure the watchdog is disabled as soon as possible */ +/* Copy this code to your bootloader if you use one and your */ +/* MCU doesn't disable the WDT after reset! */ +void get_mcusr(void) \ + __attribute__((naked)) \ + __attribute__((section(".init3"))); +void get_mcusr(void) +{ + MCUSR = 0; + wdt_disable(); +} + +#ifdef CONFIG_MEMPOISON +void poison_memory(void) \ + __attribute__((naked)) \ + __attribute__((section(".init1"))); +void poison_memory(void) { + register uint16_t i; + register uint8_t *ptr; + + asm("clr r1\n"); + /* There is no RAMSTARt variable =( */ + if (RAMEND > 2048 && RAMEND < 4096) { + /* 2K memory */ + ptr = (void *)RAMEND-2047; + for (i=0;i<2048;i++) + ptr[i] = 0x55; + } else if (RAMEND > 4096 && RAMEND < 8192) { + /* 4K memory */ + ptr = (void *)RAMEND-4095; + for (i=0;i<4096;i++) + ptr[i] = 0x55; + } else { + /* Assume 8K memory */ + ptr = (void *)RAMEND-8191; + for (i=0;i<8192;i++) + ptr[i] = 0x55; + } +} +#endif + +#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 1) +int main(void) __attribute__((OS_main)); +#endif +int main(void) { +#if defined __AVR_ATmega644__ || defined __AVR_ATmega644P__ || defined __AVR_ATmega2561__ + asm volatile("in r24, %0\n" + "ori r24, 0x80\n" + "out %0, r24\n" + "out %0, r24\n" + : + : "I" (_SFR_IO_ADDR(MCUCR)) + : "r24" + ); +#elif defined __AVR_ATmega32__ + asm volatile ("in r24, %0\n" + "ori r24, 0x80\n" + "out %0, r24\n" + "out %0, r24\n" + : + : "I" (_SFR_IO_ADDR(MCUCSR)) + : "r24" + ); +#elif defined __AVR_ATmega128__ || defined __AVR_ATmega1281__ + /* Just assume that JTAG doesn't hurt us on the m128 */ +#else +# error Unknown chip! +#endif + +#ifdef CLOCK_PRESCALE + clock_prescale_set(CLOCK_PRESCALE); +#endif + set_pwr_led(0); + set_busy_led(1); + spi_none(); + snes_reset(1); + uart_init(); + sei(); + _delay_ms(100); + disk_init(); + snes_init(); +/* timer_init(); */ + uart_puts_P(PSTR("\nsd2snes " VERSION)); + uart_putcrlf(); + + file_init(); + FATFS fatfs; + f_mount(0,&fatfs); + uart_putc('W'); + fpga_init(); + fpga_pgm((uint8_t*)"/sd2snes/main.bit"); + _delay_ms(100); + set_pwr_led(1); + fpga_spi_init(); + uart_putc('!'); + _delay_ms(100); + +restart: + set_avr_ena(0); + snes_reset(1); + + *fs_path=0; + 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); + + while(0) { + SD_SPI_OFFLOAD=0; + set_avr_addr(0L); + sd_read(0, file_buf, 0L, 1); + uart_trace((void*)file_buf, 0, 0x200); +// sram_writeblock((void*)file_buf, 0, 0x200); +// sram_hexdump(0,0x200); + uart_putc('+'); + } +/* here be strange monsters */ + while(0){ +// uint16_t hurdur1 = 0, hurdur2 = 0; + spiTransferByte(0x00); + spiTransferByte(0x00); + spiTransferByte(0x00); + spiTransferByte(0x00); + spiTransferByte(0x00); + spiTransferByte(0x00); + spiTransferByte(0x00); + spiTransferByte(0x00); + spiTransferByte(0x00); + spiTransferByte(0x00); + spiTransferByte(0x00); + spiTransferByte(0x00); + spiTransferByte(0x00); + PORTB |= _BV(PB2); + DDRB |= _BV(PB2); + PORTB &= ~_BV(PB2); + DDRB &= ~_BV(PB7); // tristate SCK + PORTB |= _BV(PB2); + DDRB &= ~_BV(PB2); + while(!(PINB & _BV(PB2))) { + } + DDRB |= _BV(PB7); + _delay_ms(1); +// dprintf("hurdur1=%d hurdur2=%d\n", hurdur1, hurdur2); +} + if((mem_magic != 0x12345678) || (mem_dir_id != saved_dir_id)) { + uint16_t curr_dir_id = scan_dir(fs_path, 0, 0); // generate files footprint + dprintf("curr dir id = %x\n", curr_dir_id); + if((get_db_id(&saved_dir_id) != FR_OK) // no database? + || saved_dir_id != curr_dir_id) { // files changed? // XXX + dprintf("saved dir id = %x\n", saved_dir_id); + dprintf("rebuilding database..."); + _delay_ms(50); + curr_dir_id = scan_dir(fs_path, 1, 0); // then rebuild database + sram_writeblock(&curr_dir_id, SRAM_DB_ADDR, 2); + uint32_t endaddr, direndaddr; + sram_readblock(&endaddr, SRAM_DB_ADDR+4, 4); + sram_readblock(&direndaddr, SRAM_DB_ADDR+8, 4); + dprintf("%lx %lx\n", endaddr, direndaddr); + save_sram((uint8_t*)"/sd2snes/sd2snes.db", endaddr-SRAM_DB_ADDR, SRAM_DB_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("saved dir id = %x\n", saved_dir_id); + 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); +// uart_putc('['); +// load_sram((uint8_t*)"/test.srm", SRAM_SAVE_ADDR); +// 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); + } + + led_pwm(); + +// sram_hexdump(0, 0x200); + uart_putc('('); + load_rom((uint8_t*)"/sd2snes/menu.bin", SRAM_MENU_ADDR); + set_rom_mask(0x3fffff); // force mirroring off + set_avr_mapper(0x7); // menu mapper XXX + uart_putc(')'); + uart_putcrlf(); +// sram_hexdump(0x7ffff0, 0x10); +// sram_hexdump(0, 0x400); +// save_sram((uint8_t*)"/sd2snes/dump", 65536, 0); + + sram_writebyte(0, SRAM_CMD_ADDR); + + set_busy_led(0); + set_avr_ena(1); + + _delay_ms(100); + uart_puts_P(PSTR("SNES GO!\r\n")); + snes_reset(0); +// writetest(); +/* snes_reset(1); + set_avr_ena(0); + led_std(); + set_busy_led(1); + save_sram((uint8_t*)"/sd2snes/dump", 65536, SRAM_MENU_ADDR); + set_busy_led(0); + set_avr_ena(1); + snes_reset(0); */ + uint8_t cmd = 0; + + while(!sram_reliable()); + while(!cmd) { + cmd=menu_main_loop(); + switch(cmd) { + case 0x01: // SNES_CMD_LOADROM: + get_selected_name(file_lfn); + _delay_ms(100); +// snes_reset(1); + set_avr_ena(0); + dprintf("Selected name: %s\n", file_lfn); + load_rom(file_lfn, SRAM_ROM_ADDR); +// save_sram((uint8_t*)"/sd2snes/test.smc", romprops.romsize_bytes, 0); + if(romprops.ramsize_bytes) { + strcpy(strrchr((char*)file_lfn, (int)'.'), ".srm"); + dprintf("SRM file: %s\n", file_lfn); + load_sram(file_lfn, SRAM_SAVE_ADDR); + } else { + dprintf("No SRAM\n"); + } + set_avr_ena(1); + snes_reset(1); + _delay_ms(100); + snes_reset(0); + break; + default: + dprintf("unknown cmd: %d\n", cmd); + cmd=0; // unknown cmd: stay in loop + break; + } + + } + dprintf("cmd was %x, going to snes main loop\n", cmd); + led_std(); + cmd=0; + uint8_t snes_reset_prev=0, snes_reset_now=0, snes_reset_state=0; + uint16_t reset_count=0; + while(fpga_test() == FPGA_TEST_TOKEN) { + snes_reset_now=get_snes_reset(); + if(snes_reset_now) { + if(!snes_reset_prev) { + dprintf("RESET BUTTON DOWN\n"); + snes_reset_state=1; + // reset reset counter + reset_count=0; + } + } else { + if(snes_reset_prev) { + dprintf("RESET BUTTON UP\n"); + snes_reset_state=0; + } + } + if(snes_reset_state) { + _delay_ms(10); + reset_count++; + } else { + sram_reliable(); + snes_main_loop(); + } + if(reset_count>100) { + reset_count=0; + led_std(); + set_avr_ena(0); + snes_reset(1); + _delay_ms(100); + if(romprops.ramsize_bytes && fpga_test() == 0xa5) { + set_busy_led(1); + save_sram(file_lfn, romprops.ramsize_bytes, SRAM_SAVE_ADDR); + set_busy_led(0); + } + _delay_ms(1000); + set_busy_led(1); + goto restart; + } + snes_reset_prev = snes_reset_now; + } + // FPGA TEST FAIL. PANIC. + led_panic(); + +/* HERE BE LIONS */ +while(1) { + set_avr_addr(0x600000); + spi_fpga(); + spiTransferByte(0x81); // read w/ increment... hopefully + spiTransferByte(0x00); // 1 dummy read + uart_putcrlf(); + uint8_t buff[21]; + for(uint8_t cnt=0; cnt<21; cnt++) { + uint8_t data=spiTransferByte(0x00); + buff[cnt]=data; + } + for(uint8_t cnt=0; cnt<21; cnt++) { + uint8_t data = buff[cnt]; + _delay_ms(2); + if(data>=0x20 && data <= 0x7a) { + uart_putc(data); + } else { +// uart_putc('.'); + uart_putc("0123456789ABCDEF"[data>>4]); + uart_putc("0123456789ABCDEF"[data&15]); + uart_putc(' '); + } +// set_avr_bank(3); + } + spi_none(); +} + while(1); +} + diff --git a/src/memory.c b/mk1-src/memory.c similarity index 100% rename from src/memory.c rename to mk1-src/memory.c diff --git a/src/memory.h b/mk1-src/memory.h similarity index 100% rename from src/memory.h rename to mk1-src/memory.h diff --git a/src/sdcard.c b/mk1-src/sdcard.c similarity index 100% rename from src/sdcard.c rename to mk1-src/sdcard.c diff --git a/src/sdcard.h b/mk1-src/sdcard.h similarity index 100% rename from src/sdcard.h rename to mk1-src/sdcard.h diff --git a/src/smc.c b/mk1-src/smc.c similarity index 100% rename from src/smc.c rename to mk1-src/smc.c diff --git a/src/smc.h b/mk1-src/smc.h similarity index 100% rename from src/smc.h rename to mk1-src/smc.h diff --git a/src/snes.c b/mk1-src/snes.c similarity index 100% rename from src/snes.c rename to mk1-src/snes.c diff --git a/src/snes.h b/mk1-src/snes.h similarity index 100% rename from src/snes.h rename to mk1-src/snes.h diff --git a/src/spi.c b/mk1-src/spi.c similarity index 100% rename from src/spi.c rename to mk1-src/spi.c diff --git a/src/spi.h b/mk1-src/spi.h similarity index 100% rename from src/spi.h rename to mk1-src/spi.h diff --git a/src/src2doxy.pl b/mk1-src/src2doxy.pl similarity index 100% rename from src/src2doxy.pl rename to mk1-src/src2doxy.pl diff --git a/src/time.h b/mk1-src/time.h similarity index 100% rename from src/time.h rename to mk1-src/time.h diff --git a/src/timer.c b/mk1-src/timer.c similarity index 100% rename from src/timer.c rename to mk1-src/timer.c diff --git a/src/timer.h b/mk1-src/timer.h similarity index 100% rename from src/timer.h rename to mk1-src/timer.h diff --git a/src/uart.c b/mk1-src/uart.c similarity index 100% rename from src/uart.c rename to mk1-src/uart.c diff --git a/src/uart.h b/mk1-src/uart.h similarity index 100% rename from src/uart.h rename to mk1-src/uart.h diff --git a/src/ustring.h b/mk1-src/ustring.h similarity index 100% rename from src/ustring.h rename to mk1-src/ustring.h diff --git a/src/utils.c b/mk1-src/utils.c similarity index 100% rename from src/utils.c rename to mk1-src/utils.c diff --git a/src/utils.h b/mk1-src/utils.h similarity index 100% rename from src/utils.h rename to mk1-src/utils.h diff --git a/src/Makefile b/src/Makefile index 1aa2435..e274763 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,14 +1,5 @@ # Hey Emacs, this is a -*- makefile -*- -# Define version number -MAJOR = 0 -MINOR = 0 -PATCHLEVEL = 1 -FIX = - -# Forces bootloader version to 0, comment out for release -#PRERELEASE = - #---------------------------------------------------------------------------- # WinAVR Makefile Template written by Eric B. Weddington, Joerg Wunsch, et al. # @@ -25,7 +16,7 @@ FIX = # Carlos Lamas # # -# Extensively modified for sd2iec by Ingo Korb +# Extensively modified for sd2iec and later adapted for ARM by Ingo Korb # # To rebuild project do "make clean" then "make all". #---------------------------------------------------------------------------- @@ -50,62 +41,22 @@ endif # Include the configuration file include $(CONFIG) -# Set MCU name and length of binary for bootloader -# WARNING: Fuse settings not tested! -MCU := $(CONFIG_MCU) -ifeq ($(MCU),atmega128) - BINARY_LENGTH = 0x1f000 -# EFUSE = 0xff -# HFUSE = 0x91 -# LFUSE = 0xaf -else ifeq ($(MCU),atmega1281) - BINARY_LENGTH = 0x1f000 - BOOTLDRSIZE = 0x0800 - EFUSE = 0xff - HFUSE = 0xd2 - LFUSE = 0xfc -else ifeq ($(MCU),atmega2561) - BINARY_LENGTH = 0x3f000 - EFUSE = 0xfd - HFUSE = 0x93 - LFUSE = 0xef -else ifeq ($(MCU),atmega644) - BINARY_LENGTH = 0xf000 - EFUSE = 0xfd - HFUSE = 0x91 -# LFUSE = 0xef - LFUSE = 0xaf -else ifeq ($(MCU),atmega644p) - BINARY_LENGTH = 0xf000 - EFUSE = 0xfd - HFUSE = 0x91 - LFUSE = 0xef -else -.PHONY: nochip -nochip: - @echo '==============================================================' - @echo 'No known target chip specified.' - @echo - @echo 'Please edit the Makefile.' - @exit 1 -endif - # Directory for all generated files -OBJDIR := obj-$(CONFIG_MCU:atmega%=m%)$(CONFIGSUFFIX) +OBJDIR := obj$(CONFIGSUFFIX) # Output format. (can be srec, ihex, binary) -FORMAT = ihex +FORMAT = binary +# Linker script +LINKERSCRIPT = lpc1754.ld # Target file name (without extension). TARGET = $(OBJDIR)/sd2snes -# List C source files here. (C dependencies are automatically generated.) -SRC = main.c ff.c utils.c led.c diskio.c sdcard.c spi.c crc7.c snes.c fpga.c memory.c crc16.c fileops.c fpga_spi.c smc.c filetypes.c -ifeq ($(CONFIG_UART_DEBUG),y) - SRC += uart.c -endif +# List C source files here. (C dependencies are automatically generated.) +SRC = main.c + # List Assembler source files here. # Make them always end in a capital .S. Files ending in a lowercase .s @@ -114,19 +65,17 @@ endif # Even though the DOS/Win* filesystem matches both .s and .S the same, # it will preserve the spelling of the filenames, and gcc itself does # care about how the name is spelled on its command-line. -ASRC = +ASRC = startup.S + # Optimization level, can be [0, 1, 2, 3, s]. # 0 = turn off optimization. s = optimize for size. # (Note: 3 is not always the best optimization level. See avr-libc FAQ.) # Use s -mcall-prologues when you really need size... +#OPT = 2 OPT = s -#OPT = 3 -finline-functions # Debugging format. -# Native formats for AVR-GCC's -g are dwarf-2 [default] or stabs. -# AVR Studio 4.10 requires dwarf-2. -# AVR [Extended] COFF format requires stabs, plus an avr-objcopy run. DEBUG = dwarf-2 @@ -146,52 +95,33 @@ CSTANDARD = -std=gnu99 # Place -D or -U options here -CDEFS = -DF_CPU=$(CONFIG_MCU_FREQ)UL +CDEFS = #-DF_CPU=$(CONFIG_MCU_FREQ)UL -# Calculate bootloader version -ifdef PRERELEASE -BOOT_VERSION := 0 -else -BOOT_VERSION := 0x$(MAJOR)$(MINOR)$(PATCHLEVEL)$(FIX) -endif - -# Create a version number define -ifdef PATCHLEVEL -ifdef FIX -PROGRAMVERSION := $(MAJOR).$(MINOR).$(PATCHLEVEL).$(FIX) -else -PROGRAMVERSION := $(MAJOR).$(MINOR).$(PATCHLEVEL) -BOOT_VERSION := $(BOOT_VERSION)0 -endif -else -PROGRAMVERSION := $(MAJOR).$(MINOR) -BOOT_VERSION := $(BOOT_VERSION)00 -endif - -ifdef PRERELEASE -PROGRAMVERSION := $(PROGRAMVERSION)$(PRERELEASE) -endif - -LONGVERSION := -$(CONFIG_MCU:atmega%=m%)$(CONFIGSUFFIX) - -CDEFS += -DVERSION=\"$(PROGRAMVERSION)\" -DLONGVERSION=\"$(LONGVERSION)\" # Place -I options here CINCS = +# CPU-specific flags +ifndef CPUFLAGS + CPUFLAGS := -mthumb -mcpu=cortex-m3 +endif + +ifndef ARCH + ARCH := arm-none-eabi +endif + # Define programs and commands. # CC must be defined here to generate the correct CFLAGS SHELL = sh -CC = avr-gcc -OBJCOPY = avr-objcopy -OBJDUMP = avr-objdump -SIZE = avr-size -NM = avr-nm -AVRDUDE = avrdude +CC = $(ARCH)-gcc +OBJCOPY = $(ARCH)-objcopy +OBJDUMP = $(ARCH)-objdump +SIZE = $(ARCH)-size +NM = $(ARCH)-nm REMOVE = rm -f COPY = cp -WINSHELL = cmd +AWK = awk #---------------- Compiler Options ---------------- @@ -204,34 +134,14 @@ WINSHELL = cmd CFLAGS = -g$(DEBUG) CFLAGS += $(CDEFS) $(CINCS) CFLAGS += -O$(OPT) -CFLAGS += -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums +CFLAGS += $(CPUFLAGS) -nostartfiles +#CFLAGS += -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums CFLAGS += -Wall -Wstrict-prototypes -Werror -CFLAGS += -Wa,-adhlns=$(OBJDIR)/$(<:.c=.lst) +#CFLAGS += -Wa,-adhlns=$(OBJDIR)/$(<:.c=.lst) CFLAGS += -I$(OBJDIR) CFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS)) CFLAGS += $(CSTANDARD) CFLAGS += -ffunction-sections -fdata-sections -#CFLAGS += -mcall-prologues - -# these are needed for GCC 4.3.2, which is more aggressive at inlining -# gcc-4.2 knows one of those, but it tends to increase code size -ifeq ($(shell $(CC) --version|gawk -f gcctest.awk),YES) -CFLAGS += --param inline-call-cost=3 -CFLAGS += -fno-inline-small-functions -CFLAGS += -fno-move-loop-invariants -CFLAGS += -fno-split-wide-types - -# turn these on to keep the functions in the same order as in the source -# this is only useful if you're looking at disassembly -#CFLAGS += -fno-reorder-blocks -#CFLAGS += -fno-reorder-blocks-and-partition -#CFLAGS += -fno-reorder-functions -#CFLAGS += -fno-toplevel-reorder -endif - -ifeq ($(CONFIG_STACK_TRACKING),y) - CFLAGS += -finstrument-functions -endif #---------------- Assembler Options ---------------- @@ -241,50 +151,7 @@ endif # for use in COFF files, additional information about filenames # and function names needs to be present in the assembler source # files -- see avr-libc docs [FIXME: not yet described there] -ASFLAGS = -Wa,-adhlns=$(OBJDIR)/$(<:.S=.lst),-gstabs -I$(OBJDIR) - - -#---------------- Library Options ---------------- -# Minimalistic printf version -PRINTF_LIB_MIN = -Wl,-u,vfprintf -lprintf_min - -# Floating point printf version (requires MATH_LIB = -lm below) -PRINTF_LIB_FLOAT = -Wl,-u,vfprintf -lprintf_flt - -# If this is left blank, then it will use the Standard printf version. -PRINTF_LIB = -#PRINTF_LIB = $(PRINTF_LIB_MIN) -#PRINTF_LIB = $(PRINTF_LIB_FLOAT) - - -# Minimalistic scanf version -SCANF_LIB_MIN = -Wl,-u,vfscanf -lscanf_min - -# Floating point + %[ scanf version (requires MATH_LIB = -lm below) -SCANF_LIB_FLOAT = -Wl,-u,vfscanf -lscanf_flt - -# If this is left blank, then it will use the Standard scanf version. -SCANF_LIB = -#SCANF_LIB = $(SCANF_LIB_MIN) -#SCANF_LIB = $(SCANF_LIB_FLOAT) - - -MATH_LIB = -lm - - - -#---------------- External Memory Options ---------------- - -# 64 KB of external RAM, starting after internal RAM (ATmega128!), -# used for variables (.data/.bss) and heap (malloc()). -#EXTMEMOPTS = -Wl,-Tdata=0x801100,--defsym=__heap_end=0x80ffff - -# 64 KB of external RAM, starting after internal RAM (ATmega128!), -# only used for heap (malloc()). -#EXTMEMOPTS = -Wl,--defsym=__heap_start=0x801100,--defsym=__heap_end=0x80ffff - -EXTMEMOPTS = - +ASFLAGS = $(CPUFLAGS) -Wa,-adhlns=$(OBJDIR)/$(<:.S=.lst),-gstabs -I$(OBJDIR) #---------------- Linker Options ---------------- @@ -292,105 +159,13 @@ EXTMEMOPTS = # -Map: create map file # --cref: add cross reference to map file LDFLAGS = -Wl,-Map=$(TARGET).map,--cref -LDFLAGS += $(EXTMEMOPTS) -LDFLAGS += $(PRINTF_LIB) $(SCANF_LIB) $(MATH_LIB) +LDFLAGS += -T$(LINKERSCRIPT) LDFLAGS += -Wl,--gc-sections ifeq ($(CONFIG_LINKER_RELAX),y) LDFLAGS += -Wl,-O9,--relax endif - -#---------------- Programming Options (avrdude) ---------------- - -# Programming hardware: alf avr910 avrisp bascom bsd -# dt006 pavr picoweb pony-stk200 sp12 stk200 stk500 stk500v2 -# -# Type: avrdude -c ? -# to get a full listing. -# -AVRDUDE_PROGRAMMER = dragon_isp - -# com1 = serial port. Use lpt1 to connect to parallel port. -AVRDUDE_PORT = usb # programmer connected to serial device - -AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex -# AVRDUDE_WRITE_EEPROM = -U eeprom:w:$(TARGET).eep - -# Allow fuse overrides from the config file -ifdef CONFIG_EFUSE - EFUSE := CONFIG_EFUSE -endif -ifdef CONFIG_HFUSE - HFUSE := CONFIG_HFUSE -endif -ifdef CONFIG_LFUSE - LFUSE := CONFIG_LFUSE -endif - -# Calculate command line arguments for fuses -AVRDUDE_WRITE_FUSES := -ifdef EFUSE - AVRDUDE_WRITE_FUSES += -U efuse:w:$(EFUSE):m -endif -ifdef HFUSE - AVRDUDE_WRITE_FUSES += -U hfuse:w:$(HFUSE):m -endif -ifdef LFUSE - AVRDUDE_WRITE_FUSES += -U lfuse:w:$(LFUSE):m -endif - - -# Uncomment the following if you want avrdude's erase cycle counter. -# Note that this counter needs to be initialized first using -Yn, -# see avrdude manual. -AVRDUDE_ERASE_COUNTER = -y - -# Uncomment the following if you do /not/ wish a verification to be -# performed after programming the device. -#AVRDUDE_NO_VERIFY = -V - -# Increase verbosity level. Please use this when submitting bug -# reports about avrdude. See -# to submit bug reports. -#AVRDUDE_VERBOSE = -v -v - -AVRDUDE_FLAGS = -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER) -AVRDUDE_FLAGS += $(AVRDUDE_NO_VERIFY) -AVRDUDE_FLAGS += $(AVRDUDE_VERBOSE) -AVRDUDE_FLAGS += $(AVRDUDE_ERASE_COUNTER) - - - -#---------------- Debugging Options ---------------- - -# For simulavr only - target MCU frequency. -DEBUG_MFREQ = $(CONFIG_MCU_FREQ) - -# Set the DEBUG_UI to either gdb or insight. -# DEBUG_UI = gdb -DEBUG_UI = insight - -# Set the debugging back-end to either avarice, simulavr. -DEBUG_BACKEND = avarice -#DEBUG_BACKEND = simulavr - -# GDB Init Filename. -GDBINIT_FILE = __avr_gdbinit - -# When using avarice settings for the JTAG -JTAG_DEV = /dev/com1 - -# Debugging port used to communicate between GDB / avarice / simulavr. -DEBUG_PORT = 4242 - -# Debugging host used to communicate between GDB / avarice / simulavr, normally -# just set to localhost unless doing some sort of crazy debugging when -# avarice is running on a different computer. -DEBUG_HOST = localhost - - - #============================================================================ @@ -410,8 +185,8 @@ GENDEPFLAGS = -MMD -MP -MF .dep/$(@F).d # Combine all necessary flags and optional flags. # Add target processor to flags. -ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS) $(GENDEPFLAGS) -ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS) $(CDEFS) +ALL_CFLAGS = -I. $(CFLAGS) $(GENDEPFLAGS) +ALL_ASFLAGS = -I. -x assembler-with-cpp $(ASFLAGS) $(CDEFS) @@ -431,111 +206,38 @@ eep: $(TARGET).eep lss: $(TARGET).lss sym: $(TARGET).sym -# A little helper target for the maintainer =) -copy2card: - mount /mnt - cp $(TARGET).bin /mnt - umount /mnt - sync +# # A little helper target for the maintainer =) +# copy2card: +# cp $(TARGET).bin /mbed/hw_LPC1768.bin -# Doxygen output: -doxygen: - -rm -rf doxyinput - mkdir doxyinput - cp *.h *.c doxyinput - src2doxy.pl doxyinput/*.h doxyinput/*.c - doxygen doxygen.conf +program: bin + utils/lpcchksum $(TARGET).bin + openocd -f openocd-usb.cfg -f lpc1754.cfg -f flash.cfg + +debug: bin + openocd -f openocd-usb.cfg -f lpc1754.cfg # Display size of file. HEXSIZE = $(SIZE) --target=$(FORMAT) $(TARGET).hex ELFSIZE = $(SIZE) -A $(TARGET).elf -AVRMEM = avr-mem.sh $(TARGET).elf $(MCU) -# Program the device. -program: bin hex eep - $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) $(AVRDUDE_WRITE_EEPROM) - -# Set fuses of the device -fuses: $(CONFIG) - $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FUSES) - -# Generate avr-gdb config/init file which does the following: -# define the reset signal, load the target file, connect to target, and set -# a breakpoint at main(). -gdb-config: - @$(REMOVE) $(GDBINIT_FILE) - @echo define reset >> $(GDBINIT_FILE) - @echo SIGNAL SIGHUP >> $(GDBINIT_FILE) - @echo end >> $(GDBINIT_FILE) - @echo file $(TARGET).elf >> $(GDBINIT_FILE) - @echo target remote $(DEBUG_HOST):$(DEBUG_PORT) >> $(GDBINIT_FILE) -ifeq ($(DEBUG_BACKEND),simulavr) - @echo load >> $(GDBINIT_FILE) -endif - @echo break main >> $(GDBINIT_FILE) - -debug: gdb-config $(TARGET).elf -ifeq ($(DEBUG_BACKEND), avarice) - @echo Starting AVaRICE - Press enter when "waiting to connect" message displays. - @$(WINSHELL) /c start avarice --jtag $(JTAG_DEV) --erase --program --file \ - $(TARGET).elf $(DEBUG_HOST):$(DEBUG_PORT) - @$(WINSHELL) /c pause - -else - @$(WINSHELL) /c start simulavr --gdbserver --device $(MCU) --clock-freq \ - $(DEBUG_MFREQ) --port $(DEBUG_PORT) -endif - @$(WINSHELL) /c start avr-$(DEBUG_UI) --command=$(GDBINIT_FILE) - - - - -# Convert ELF to COFF for use in debugging / simulating in AVR Studio or VMLAB. -COFFCONVERT=$(OBJCOPY) --debugging \ ---change-section-address .data-0x800000 \ ---change-section-address .bss-0x800000 \ ---change-section-address .noinit-0x800000 \ ---change-section-address .eeprom-0x810000 - - -coff: $(TARGET).elf - $(COFFCONVERT) -O coff-avr $< $(TARGET).cof - - -extcoff: $(TARGET).elf - $(COFFCONVERT) -O coff-ext-avr $< $(TARGET).cof # Generate autoconf.h from config .PRECIOUS : $(OBJDIR)/autoconf.h $(OBJDIR)/autoconf.h: $(CONFIG) | $(OBJDIR) $(E) " CONF2H $(CONFIG)" - $(Q)gawk -f conf2h.awk $(CONFIG) > $(OBJDIR)/autoconf.h + $(Q)$(AWK) -f conf2h.awk $(CONFIG) > $(OBJDIR)/autoconf.h -# Create final output files (.hex, .eep) from ELF output file. -ifeq ($(CONFIG_BOOTLOADER),y) +# Create final output files from ELF output file. $(OBJDIR)/%.bin: $(OBJDIR)/%.elf $(E) " BIN $@" - $(Q)$(OBJCOPY) -O binary -R .eeprom $< $@ - $(E) " CRCGEN $@" - -$(Q)crcgen-new $@ $(BINARY_LENGTH) $(CONFIG_BOOT_DEVID) $(BOOT_VERSION) - $(E) " COPY $(CONFIG_HARDWARE_NAME)-firmware-$(PROGRAMVERSION).bin" - $(Q)$(COPY) $@ $(OBJDIR)/$(CONFIG_HARDWARE_NAME)-firmware-$(PROGRAMVERSION).bin -else -$(OBJDIR)/%.bin: $(OBJDIR)/%.elf - $(E) " BIN $@" - $(Q)$(OBJCOPY) -O binary -R .eeprom $< $@ -endif - + $(Q)$(OBJCOPY) -O binary $< $@ $(OBJDIR)/%.hex: $(OBJDIR)/%.elf $(E) " HEX $@" - $(Q)$(OBJCOPY) -O $(FORMAT) -R .eeprom $< $@ - -$(OBJDIR)/%.eep: $(OBJDIR)/%.elf - -$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \ - --change-section-lma .eeprom=0 -O $(FORMAT) $< $@ + $(Q)$(OBJCOPY) -O $(FORMAT) $< $@ # Create extended listing file from ELF output file. $(OBJDIR)/%.lss: $(OBJDIR)/%.elf @@ -548,7 +250,6 @@ $(OBJDIR)/%.sym: $(OBJDIR)/%.elf $(E)$(NM) -n $< > $@ - # Link: create ELF output file from object files. .SECONDARY : $(TARGET).elf .PRECIOUS : $(OBJ) @@ -589,8 +290,6 @@ clean_list : $(E) " CLEAN" $(Q)$(REMOVE) $(TARGET).hex $(Q)$(REMOVE) $(TARGET).bin - $(Q)$(REMOVE) $(TARGET).eep - $(Q)$(REMOVE) $(TARGET).cof $(Q)$(REMOVE) $(TARGET).elf $(Q)$(REMOVE) $(TARGET).map $(Q)$(REMOVE) $(TARGET).sym @@ -602,18 +301,11 @@ clean_list : $(Q)$(REMOVE) $(CSRC:.c=.s) $(Q)$(REMOVE) $(CSRC:.c=.d) $(Q)$(REMOVE) .dep/* - $(Q)$(REMOVE) -rf codedoc - $(Q)$(REMOVE) -rf doxyinput -$(Q)rmdir $(OBJDIR) # Include the dependency files. -include $(shell mkdir .dep 2>/dev/null) $(wildcard .dep/*) -# Manual dependency for the assembler module -# $(OBJDIR)/fastloader-ll.o: config.h $(OBJDIR)/autoconf.h - # Listing of phony targets. -.PHONY : all begin finish end sizebefore sizeafter gccversion \ -build elf hex eep lss sym coff extcoff \ -clean clean_list program debug gdb-config doxygen - +.PHONY : all begin finish end sizebefore sizeafter \ +build elf hex lss sym clean clean_list diff --git a/src/config b/src/config index 4655c16..8d3bc94 100644 --- a/src/config +++ b/src/config @@ -1,47 +1 @@ -# This may not look like it, but it's a -*- makefile -*- -# sd2snes - SD card based universal cartridge for the SNES -# Copyright (C) 2009-2010 Maximilian Rehkopf -# -# This file was adapted from sd2iec, written by Ingo Korb. -# Original disclaimer follows: -# -# sd2iec - SD/MMC to Commodore serial bus interface/controller -# Copyright (C) 2007-2009 Ingo Korb -# -# Inspiration and low-level SD/MMC access based on code from MMC2IEC -# by Lars Pontoppidan et al., see sdcard.c|h and config.h. -# -# FAT filesystem access based on code from ChaN, see tff.c|h. -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; version 2 of the License only. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# -# -# This file is included in the main sd2iec Makefile and also parsed -# into autoconf.h. - -CONFIG_MCU=atmega644 -CONFIG_LINKER_RELAX=n -CONFIG_MCU_FREQ=12288000 -CONFIG_BOOTLOADER=y -CONFIG_BOOT_DEVID=0x4e534453 -CONFIG_UART_DEBUG=y -CONFIG_UART_BAUDRATE=384000 -CONFIG_UART_BUF_SHIFT=7 -CONFIG_HARDWARE_NAME=sd2snes -CONFIG_SD_AUTO_RETRIES=10 -#CONFIG_SD_DATACRC=y -CONFIG_EEPROM_SIZE=512 -CONFIG_EEPROM_OFFSET=512 -CONFIG_MAX_PARTITIONS=1 -#CONFIG_DEADLOCK_ME_HARDER=y +# empty config file \ No newline at end of file diff --git a/src/main.c b/src/main.c index ed24028..b828f1e 100644 --- a/src/main.c +++ b/src/main.c @@ -1,400 +1,84 @@ -/* sd2snes - SD card based universal cartridge for the SNES - Copyright (C) 2009-2010 Maximilian Rehkopf - AVR firmware portion +/* The classic embedded version of "Hello World": A blinking LED */ +#include - Inspired by and based on code from sd2iec, written by Ingo Korb et al. - See sdcard.c|h, config.h. +#define BV(x) (1<<(x)) +#define BITBAND(addr,bit) (*((volatile unsigned long *)(((unsigned long)&(addr)-0x20000000)*32 + bit*4 + 0x22000000))) +#define PLL_MULT(x) ((x)&0x7fff) +#define PLL_PREDIV(x) (((x)<<16)&0xff0000) +#define CLKSRC_MAINOSC (1) +#define PLLE0 (1<<0) +#define PLLC0 (1<<1) +#define PLOCK0 (1<<26) +#define OSCEN (1<<5) +#define OSCSTAT (1<<6) +#define EMC0TOGGLE (3<<4) +#define MR0R (1<<1) +#define FLASH5C (0x403A) +#define PCTIM3 (1<<23) - FAT file system access based on code by ChaN, Jim Brain, Ingo Korb, - see ff.c|h. +#define PCLK_CCLK(x) (1<<(x)) +#define PCLK_CCLK4(x) (0) +#define PCLK_CCLK8(x) (3<<(x)) +#define PCLK_CCLK2(x) (2<<(x)) +#define PCLK_TIMER3 (14) - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; version 2 of the License only. +int i; - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. +int main(void) { + LPC_GPIO2->FIODIR = BV(0) | BV(1) | BV(2); + LPC_GPIO1->FIODIR = 0; + uint32_t p1; - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +/* setup PLL0 */ + LPC_SC->FLASHCFG=FLASH5C; + LPC_SC->PLL0CON &= ~PLLC0; + LPC_SC->PLL0FEED=0xaa; + LPC_SC->PLL0FEED=0x55; + LPC_SC->PLL0CON &= ~PLLE0; + LPC_SC->PLL0FEED=0xaa; + LPC_SC->PLL0FEED=0x55; - main.c: initialization and flow +/* PLL is disabled and disconnected. setup PCLK NOW as it cannot be changed + reliably with PLL0 connected. + see: + http://ics.nxp.com/support/documents/microcontrollers/pdf/errata.lpc1754.pdf */ + LPC_SC->PCLKSEL1=PCLK_CCLK(PCLK_TIMER3); + +/* continue with PLL0 setup */ + LPC_SC->SCS=OSCEN; + while(!(LPC_SC->SCS&OSCSTAT)); + LPC_SC->CLKSRCSEL=CLKSRC_MAINOSC; + LPC_SC->PLL0CFG=PLL_MULT(428)|PLL_PREDIV(18); + LPC_SC->PLL0FEED=0xaa; + LPC_SC->PLL0FEED=0x55; + LPC_SC->PLL0CON |= PLLE0; + LPC_SC->PLL0FEED=0xaa; + LPC_SC->PLL0FEED=0x55; + LPC_SC->CCLKCFG=5; + while(!(LPC_SC->PLL0STAT&PLOCK0)); + LPC_SC->PLL0CON |= PLLC0; + LPC_SC->PLL0FEED=0xaa; + LPC_SC->PLL0FEED=0x55; -#include -#include -#include -#include -#include -#include -#include -#include -#include "config.h" -#include "diskio.h" -#include "ff.h" -#include "led.h" -/* #include "timer.h" */ -#include "fpga.h" -#include "uart.h" -#include "ustring.h" -#include "utils.h" -#include "snes.h" -#include "fileops.h" -#include "memory.h" -#include "fpga_spi.h" -#include "spi.h" -#include "avrcompat.h" -#include "filetypes.h" -#include "sdcard.h" +/* setup timer (fpga clk) */ + LPC_SC->PCONP |= PCTIM3; /* enable power */ + LPC_TIM3->CTCR=0; + LPC_TIM3->EMR=EMC0TOGGLE; + LPC_PINCON->PINSEL0=(0x3<<20); + LPC_TIM3->MCR=MR0R; + LPC_TIM3->MR0=1; + LPC_TIM3->TCR=1; + -void writetest(void) { -// HERE BE LIONS, GET IN THE CAR - char teststring[58]; - while(1) { - sram_writeblock((void*)"Testtext of DOOM!!1! 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ", SRAM_SCRATCHPAD+0x20, 58); - sram_readblock((void*)teststring, SRAM_SCRATCHPAD+0x20, 58); - teststring[57]=0; - dprintf("%s\n", teststring); - } -// END OF LIONS -} - - -void memtest(void) { -/* HERE BE DRAGONS */ - uint32_t dbg_i; - for(dbg_i=0; dbg_i < 65536; dbg_i++) { - sram_writeshort((uint16_t)dbg_i&0xffff, dbg_i*2); - } - save_sram((uint8_t*)"/sd2snes/memtest", 0x20000, 0); - set_pwr_led(0); - while(1); -/* END OF DRAGONS */ -} - - -/* Make sure the watchdog is disabled as soon as possible */ -/* Copy this code to your bootloader if you use one and your */ -/* MCU doesn't disable the WDT after reset! */ -void get_mcusr(void) \ - __attribute__((naked)) \ - __attribute__((section(".init3"))); -void get_mcusr(void) -{ - MCUSR = 0; - wdt_disable(); -} - -#ifdef CONFIG_MEMPOISON -void poison_memory(void) \ - __attribute__((naked)) \ - __attribute__((section(".init1"))); -void poison_memory(void) { - register uint16_t i; - register uint8_t *ptr; - - asm("clr r1\n"); - /* There is no RAMSTARt variable =( */ - if (RAMEND > 2048 && RAMEND < 4096) { - /* 2K memory */ - ptr = (void *)RAMEND-2047; - for (i=0;i<2048;i++) - ptr[i] = 0x55; - } else if (RAMEND > 4096 && RAMEND < 8192) { - /* 4K memory */ - ptr = (void *)RAMEND-4095; - for (i=0;i<4096;i++) - ptr[i] = 0x55; - } else { - /* Assume 8K memory */ - ptr = (void *)RAMEND-8191; - for (i=0;i<8192;i++) - ptr[i] = 0x55; + while (1) { + p1 = LPC_GPIO1->FIOPIN; + BITBAND(LPC_GPIO2->FIOPIN, 0) = (p1 & BV(29))>>29; + BITBAND(LPC_GPIO2->FIOSET, 2) = 1; + for (i=0;i<100000;i++) + __NOP(); + BITBAND(LPC_GPIO2->FIOCLR, 2) = 1; + for (i=0;i<100000;i++) + __NOP(); } } -#endif - -#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 1) -int main(void) __attribute__((OS_main)); -#endif -int main(void) { -#if defined __AVR_ATmega644__ || defined __AVR_ATmega644P__ || defined __AVR_ATmega2561__ - asm volatile("in r24, %0\n" - "ori r24, 0x80\n" - "out %0, r24\n" - "out %0, r24\n" - : - : "I" (_SFR_IO_ADDR(MCUCR)) - : "r24" - ); -#elif defined __AVR_ATmega32__ - asm volatile ("in r24, %0\n" - "ori r24, 0x80\n" - "out %0, r24\n" - "out %0, r24\n" - : - : "I" (_SFR_IO_ADDR(MCUCSR)) - : "r24" - ); -#elif defined __AVR_ATmega128__ || defined __AVR_ATmega1281__ - /* Just assume that JTAG doesn't hurt us on the m128 */ -#else -# error Unknown chip! -#endif - -#ifdef CLOCK_PRESCALE - clock_prescale_set(CLOCK_PRESCALE); -#endif - set_pwr_led(0); - set_busy_led(1); - spi_none(); - snes_reset(1); - uart_init(); - sei(); - _delay_ms(100); - disk_init(); - snes_init(); -/* timer_init(); */ - uart_puts_P(PSTR("\nsd2snes " VERSION)); - uart_putcrlf(); - - file_init(); - FATFS fatfs; - f_mount(0,&fatfs); - uart_putc('W'); - fpga_init(); - fpga_pgm((uint8_t*)"/sd2snes/main.bit"); - _delay_ms(100); - set_pwr_led(1); - fpga_spi_init(); - uart_putc('!'); - _delay_ms(100); - -restart: - set_avr_ena(0); - snes_reset(1); - - *fs_path=0; - 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); - - while(0) { - SD_SPI_OFFLOAD=0; - set_avr_addr(0L); - sd_read(0, file_buf, 0L, 1); - uart_trace((void*)file_buf, 0, 0x200); -// sram_writeblock((void*)file_buf, 0, 0x200); -// sram_hexdump(0,0x200); - uart_putc('+'); - } -/* here be strange monsters */ - while(0){ -// uint16_t hurdur1 = 0, hurdur2 = 0; - spiTransferByte(0x00); - spiTransferByte(0x00); - spiTransferByte(0x00); - spiTransferByte(0x00); - spiTransferByte(0x00); - spiTransferByte(0x00); - spiTransferByte(0x00); - spiTransferByte(0x00); - spiTransferByte(0x00); - spiTransferByte(0x00); - spiTransferByte(0x00); - spiTransferByte(0x00); - spiTransferByte(0x00); - PORTB |= _BV(PB2); - DDRB |= _BV(PB2); - PORTB &= ~_BV(PB2); - DDRB &= ~_BV(PB7); // tristate SCK - PORTB |= _BV(PB2); - DDRB &= ~_BV(PB2); - while(!(PINB & _BV(PB2))) { - } - DDRB |= _BV(PB7); - _delay_ms(1); -// dprintf("hurdur1=%d hurdur2=%d\n", hurdur1, hurdur2); -} - if((mem_magic != 0x12345678) || (mem_dir_id != saved_dir_id)) { - uint16_t curr_dir_id = scan_dir(fs_path, 0, 0); // generate files footprint - dprintf("curr dir id = %x\n", curr_dir_id); - if((get_db_id(&saved_dir_id) != FR_OK) // no database? - || saved_dir_id != curr_dir_id) { // files changed? // XXX - dprintf("saved dir id = %x\n", saved_dir_id); - dprintf("rebuilding database..."); - _delay_ms(50); - curr_dir_id = scan_dir(fs_path, 1, 0); // then rebuild database - sram_writeblock(&curr_dir_id, SRAM_DB_ADDR, 2); - uint32_t endaddr, direndaddr; - sram_readblock(&endaddr, SRAM_DB_ADDR+4, 4); - sram_readblock(&direndaddr, SRAM_DB_ADDR+8, 4); - dprintf("%lx %lx\n", endaddr, direndaddr); - save_sram((uint8_t*)"/sd2snes/sd2snes.db", endaddr-SRAM_DB_ADDR, SRAM_DB_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("saved dir id = %x\n", saved_dir_id); - 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); -// uart_putc('['); -// load_sram((uint8_t*)"/test.srm", SRAM_SAVE_ADDR); -// 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); - } - - led_pwm(); - -// sram_hexdump(0, 0x200); - uart_putc('('); - load_rom((uint8_t*)"/sd2snes/menu.bin", SRAM_MENU_ADDR); - set_rom_mask(0x3fffff); // force mirroring off - set_avr_mapper(0x7); // menu mapper XXX - uart_putc(')'); - uart_putcrlf(); -// sram_hexdump(0x7ffff0, 0x10); -// sram_hexdump(0, 0x400); -// save_sram((uint8_t*)"/sd2snes/dump", 65536, 0); - - sram_writebyte(0, SRAM_CMD_ADDR); - - set_busy_led(0); - set_avr_ena(1); - - _delay_ms(100); - uart_puts_P(PSTR("SNES GO!\r\n")); - snes_reset(0); -// writetest(); -/* snes_reset(1); - set_avr_ena(0); - led_std(); - set_busy_led(1); - save_sram((uint8_t*)"/sd2snes/dump", 65536, SRAM_MENU_ADDR); - set_busy_led(0); - set_avr_ena(1); - snes_reset(0); */ - uint8_t cmd = 0; - - while(!sram_reliable()); - while(!cmd) { - cmd=menu_main_loop(); - switch(cmd) { - case 0x01: // SNES_CMD_LOADROM: - get_selected_name(file_lfn); - _delay_ms(100); -// snes_reset(1); - set_avr_ena(0); - dprintf("Selected name: %s\n", file_lfn); - load_rom(file_lfn, SRAM_ROM_ADDR); -// save_sram((uint8_t*)"/sd2snes/test.smc", romprops.romsize_bytes, 0); - if(romprops.ramsize_bytes) { - strcpy(strrchr((char*)file_lfn, (int)'.'), ".srm"); - dprintf("SRM file: %s\n", file_lfn); - load_sram(file_lfn, SRAM_SAVE_ADDR); - } else { - dprintf("No SRAM\n"); - } - set_avr_ena(1); - snes_reset(1); - _delay_ms(100); - snes_reset(0); - break; - default: - dprintf("unknown cmd: %d\n", cmd); - cmd=0; // unknown cmd: stay in loop - break; - } - - } - dprintf("cmd was %x, going to snes main loop\n", cmd); - led_std(); - cmd=0; - uint8_t snes_reset_prev=0, snes_reset_now=0, snes_reset_state=0; - uint16_t reset_count=0; - while(fpga_test() == FPGA_TEST_TOKEN) { - snes_reset_now=get_snes_reset(); - if(snes_reset_now) { - if(!snes_reset_prev) { - dprintf("RESET BUTTON DOWN\n"); - snes_reset_state=1; - // reset reset counter - reset_count=0; - } - } else { - if(snes_reset_prev) { - dprintf("RESET BUTTON UP\n"); - snes_reset_state=0; - } - } - if(snes_reset_state) { - _delay_ms(10); - reset_count++; - } else { - sram_reliable(); - snes_main_loop(); - } - if(reset_count>100) { - reset_count=0; - led_std(); - set_avr_ena(0); - snes_reset(1); - _delay_ms(100); - if(romprops.ramsize_bytes && fpga_test() == 0xa5) { - set_busy_led(1); - save_sram(file_lfn, romprops.ramsize_bytes, SRAM_SAVE_ADDR); - set_busy_led(0); - } - _delay_ms(1000); - set_busy_led(1); - goto restart; - } - snes_reset_prev = snes_reset_now; - } - // FPGA TEST FAIL. PANIC. - led_panic(); - -/* HERE BE LIONS */ -while(1) { - set_avr_addr(0x600000); - spi_fpga(); - spiTransferByte(0x81); // read w/ increment... hopefully - spiTransferByte(0x00); // 1 dummy read - uart_putcrlf(); - uint8_t buff[21]; - for(uint8_t cnt=0; cnt<21; cnt++) { - uint8_t data=spiTransferByte(0x00); - buff[cnt]=data; - } - for(uint8_t cnt=0; cnt<21; cnt++) { - uint8_t data = buff[cnt]; - _delay_ms(2); - if(data>=0x20 && data <= 0x7a) { - uart_putc(data); - } else { -// uart_putc('.'); - uart_putc("0123456789ABCDEF"[data>>4]); - uart_putc("0123456789ABCDEF"[data&15]); - uart_putc(' '); - } -// set_avr_bank(3); - } - spi_none(); -} - while(1); -} -