Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ea792090e3 |
9
.gitignore
vendored
9
.gitignore
vendored
@@ -27,12 +27,3 @@
|
|||||||
*.vfat
|
*.vfat
|
||||||
*.wla*
|
*.wla*
|
||||||
*.rcc
|
*.rcc
|
||||||
*.log
|
|
||||||
bootloader
|
|
||||||
snesuploader
|
|
||||||
tmtags
|
|
||||||
bsnes
|
|
||||||
web
|
|
||||||
ucon64.exe
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
8
README
8
README
@@ -1,8 +0,0 @@
|
|||||||
________ .__ __ ________ ____ ________
|
|
||||||
\_____ \ __ __|__| ____ | | __\______ \ _______ _/_ |/ _____/
|
|
||||||
/ / \ \| | \ |/ ___\| |/ / | | \_/ __ \ \/ /| / __ \
|
|
||||||
/ \_/. \ | / \ \___| < | ` \ ___/\ / | \ |__\ \
|
|
||||||
\_____\ \_/____/|__|\___ >__|_ \/_______ /\___ >\_/ |___|\_____ /
|
|
||||||
\__> \/ \/ \/ \/ \/
|
|
||||||
|
|
||||||
www.optixx.org
|
|
||||||
@@ -67,7 +67,7 @@ clean:
|
|||||||
|
|
||||||
.PHONY: all clean interactive-isp interactive-serial launch-bootloader
|
.PHONY: all clean interactive-isp interactive-serial launch-bootloader
|
||||||
|
|
||||||
flash: bootloader.hex
|
flash:
|
||||||
$(AVRDUDE) $(AVRDUDE_FLAGS) -c $(ISP_PROG) -U flash:w:$<
|
$(AVRDUDE) $(AVRDUDE_FLAGS) -c $(ISP_PROG) -U flash:w:$<
|
||||||
|
|
||||||
flash-eeprom-%: %.eep.hex
|
flash-eeprom-%: %.eep.hex
|
||||||
|
|||||||
@@ -286,7 +286,7 @@ usbMsgLen_t usbFunctionSetup(uchar data[8])
|
|||||||
boot_page_erase(flash_address.word);
|
boot_page_erase(flash_address.word);
|
||||||
sei();
|
sei();
|
||||||
}
|
}
|
||||||
uart_puts("\n\rWrite Flash");
|
uart_puts("\n\r");
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -406,10 +406,9 @@ void leave_bootloader(void)
|
|||||||
* disconnect usb
|
* disconnect usb
|
||||||
*/
|
*/
|
||||||
usbDeviceDisconnect();
|
usbDeviceDisconnect();
|
||||||
#if 0
|
|
||||||
for (uint8_t i = 0; i < 50; i++)
|
for (uint8_t i = 0; i < 50; i++)
|
||||||
_delay_ms(10); /* 0 means 0x10000, 38*1/f*0x10000 =~ 498ms */
|
_delay_ms(10); /* 0 means 0x10000, 38*1/f*0x10000 =~ 498ms */
|
||||||
#endif
|
|
||||||
/*
|
/*
|
||||||
* enable watchdog to soft-reset the uC for clean startup of new application
|
* enable watchdog to soft-reset the uC for clean startup of new application
|
||||||
*/
|
*/
|
||||||
@@ -422,13 +421,6 @@ void leave_bootloader(void)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void banner(){
|
|
||||||
uart_puts("\n\r");
|
|
||||||
uart_puts("\n\r");
|
|
||||||
uart_puts("\n\r");
|
|
||||||
uart_puts("Quickdev16 Bootloader v0.2\n\r");
|
|
||||||
uart_puts("www.optixx.org\n\r");
|
|
||||||
}
|
|
||||||
|
|
||||||
int __attribute__ ((noreturn, OS_main)) main(void)
|
int __attribute__ ((noreturn, OS_main)) main(void)
|
||||||
{
|
{
|
||||||
@@ -449,12 +441,12 @@ int __attribute__ ((noreturn, OS_main)) main(void)
|
|||||||
uint16_t delay = 0;
|
uint16_t delay = 0;
|
||||||
timeout = TIMEOUT;
|
timeout = TIMEOUT;
|
||||||
|
|
||||||
|
uart_puts("Snesram Bootloader v0.1\n\r");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* if power-on reset, quit bootloader via watchdog reset
|
* if power-on reset, quit bootloader via watchdog reset
|
||||||
*/
|
*/
|
||||||
if (reset & _BV(PORF)) {
|
if (reset & _BV(PORF)) {
|
||||||
banner();
|
|
||||||
uart_puts("Found power on reset\n\r");
|
uart_puts("Found power on reset\n\r");
|
||||||
MCUSR = 0;
|
MCUSR = 0;
|
||||||
leave_bootloader();
|
leave_bootloader();
|
||||||
@@ -466,11 +458,15 @@ int __attribute__ ((noreturn, OS_main)) main(void)
|
|||||||
uart_puts("Found watchdog reset\n\r");
|
uart_puts("Found watchdog reset\n\r");
|
||||||
MCUSR = 0;
|
MCUSR = 0;
|
||||||
wdt_disable();
|
wdt_disable();
|
||||||
uart_puts("Jump to 0x0000\n\r");
|
DLED_TGL;
|
||||||
|
_delay_ms(500);
|
||||||
|
DLED_TGL;
|
||||||
|
_delay_ms(500);
|
||||||
|
uart_puts("Jump to main\n\r");
|
||||||
jump_to_app();
|
jump_to_app();
|
||||||
}
|
}
|
||||||
|
|
||||||
banner();
|
|
||||||
uart_puts("Enter programming mode\n\r");
|
uart_puts("Enter programming mode\n\r");
|
||||||
/*
|
/*
|
||||||
* else: enter programming mode
|
* else: enter programming mode
|
||||||
|
|||||||
@@ -33,13 +33,13 @@ ifeq ($(DEBUG),1)
|
|||||||
OBJECTS = usbdrv/usbdrv.o usbdrv/usbdrvasm.o usbdrv/oddebug.o \
|
OBJECTS = usbdrv/usbdrv.o usbdrv/usbdrvasm.o usbdrv/oddebug.o \
|
||||||
main.o usb_bulk.o uart.o fifo.o sram.o crc.o debug.o \
|
main.o usb_bulk.o uart.o fifo.o sram.o crc.o debug.o \
|
||||||
dump.o timer.o watchdog.o rle.c loader.o info.o shared_memory.o \
|
dump.o timer.o watchdog.o rle.c loader.o info.o shared_memory.o \
|
||||||
irq.o command.o testing.o
|
command.o testing.o rtc.o mmc.o ff.o
|
||||||
else
|
else
|
||||||
LDFLAGS = -Wl,-u
|
LDFLAGS = -Wl,-u
|
||||||
CFLAGS = -Iusbdrv -I. -DDEBUG_LEVEL=0 -DNO_DEBUG -DNO_INFO
|
CFLAGS = -Iusbdrv -I. -DDEBUG_LEVEL=0 -DNO_DEBUG -DNO_INFO
|
||||||
OBJECTS = usbdrv/usbdrv.o usbdrv/usbdrvasm.o usbdrv/oddebug.o main.o usb_bulk.o \
|
OBJECTS = usbdrv/usbdrv.o usbdrv/usbdrvasm.o usbdrv/oddebug.o main.o usb_bulk.o \
|
||||||
uart.o fifo.o sram.o crc.o debug.o dump.o timer.o watchdog.o rle.c loader.o \
|
uart.o fifo.o sram.o crc.o debug.o dump.o timer.o watchdog.o rle.c loader.o \
|
||||||
info.o shared_memory.o command.o irq.o
|
info.o shared_memory.o command.o
|
||||||
endif
|
endif
|
||||||
|
|
||||||
COMPILE = avr-gcc -Wall -Os -DF_CPU=$(F_CPU) $(CFLAGS) -mmcu=$(DEVICE)
|
COMPILE = avr-gcc -Wall -Os -DF_CPU=$(F_CPU) $(CFLAGS) -mmcu=$(DEVICE)
|
||||||
@@ -62,8 +62,11 @@ help:
|
|||||||
@echo "make clean ..... to delete objects and hex file"
|
@echo "make clean ..... to delete objects and hex file"
|
||||||
|
|
||||||
hex: main.hex
|
hex: main.hex
|
||||||
|
@echo "==============================="
|
||||||
@echo "$(TARGET) compiled for: $(DEVICE)"
|
@echo "$(TARGET) compiled for: $(DEVICE)"
|
||||||
@./checksize $(TARGET).elf
|
@echo -n "size is: "
|
||||||
|
@$(SIZE) -A $(TARGET).hex | grep "\.sec1" | tr -s " " | cut -d" " -f2
|
||||||
|
@echo "==============================="
|
||||||
|
|
||||||
program: flash fuse
|
program: flash fuse
|
||||||
|
|
||||||
|
|||||||
6
avr/usbload/checksize
Executable file → Normal file
6
avr/usbload/checksize
Executable file → Normal file
@@ -5,11 +5,11 @@
|
|||||||
# Creation Date: 2004-12-29
|
# Creation Date: 2004-12-29
|
||||||
# Tabsize: 4
|
# Tabsize: 4
|
||||||
# Copyright: (c) 2005 OBJECTIVE DEVELOPMENT Software GmbH.
|
# Copyright: (c) 2005 OBJECTIVE DEVELOPMENT Software GmbH.
|
||||||
# Revision: $:Id: checksize 83 2006-01-05 22:20:53Z cs $
|
# Revision: $Id: checksize 83 2006-01-05 22:20:53Z cs $
|
||||||
|
|
||||||
error=0
|
error=0
|
||||||
codelimit=65536 # default value
|
codelimit=16384 # default value
|
||||||
datalimit=4064 # default value; leave 32 bytes for stack
|
datalimit=992 # default value; leave 32 bytes for stack
|
||||||
|
|
||||||
if [ $# -gt 1 ]; then
|
if [ $# -gt 1 ]; then
|
||||||
codelimit="$2"
|
codelimit="$2"
|
||||||
|
|||||||
@@ -19,7 +19,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <avr/io.h>
|
#include <avr/io.h>
|
||||||
#include <avr/interrupt.h>
|
|
||||||
#include <util/delay.h>
|
#include <util/delay.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
@@ -27,21 +26,18 @@
|
|||||||
#include "requests.h"
|
#include "requests.h"
|
||||||
#include "sram.h"
|
#include "sram.h"
|
||||||
#include "info.h"
|
#include "info.h"
|
||||||
#include "irq.h"
|
|
||||||
|
|
||||||
extern uint32_t req_bank_size;
|
extern uint32_t req_bank_size;
|
||||||
|
|
||||||
|
|
||||||
void send_reset()
|
void send_reset()
|
||||||
{
|
{
|
||||||
info_P(PSTR("Reset SNES\n"));
|
info("Reset Snes\n");
|
||||||
cli();
|
|
||||||
snes_reset_on();
|
snes_reset_on();
|
||||||
snes_reset_lo();
|
snes_reset_lo();
|
||||||
_delay_ms(2);
|
_delay_ms(2);
|
||||||
snes_reset_hi();
|
snes_reset_hi();
|
||||||
snes_reset_off();
|
snes_reset_off();
|
||||||
sei();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void send_irq()
|
void send_irq()
|
||||||
@@ -57,9 +53,9 @@ void set_rom_mode()
|
|||||||
{
|
{
|
||||||
if (req_bank_size == 0x8000) {
|
if (req_bank_size == 0x8000) {
|
||||||
snes_lorom();
|
snes_lorom();
|
||||||
info_P(PSTR("Set SNES lowrom \n"));
|
info("Set Snes lowrom \n");
|
||||||
} else {
|
} else {
|
||||||
snes_hirom();
|
snes_hirom();
|
||||||
info_P(PSTR("Set SNES hirom \n"));
|
info("Set Snes hirom \n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,8 +43,6 @@
|
|||||||
#define USB_CRC_CHECK 0x01
|
#define USB_CRC_CHECK 0x01
|
||||||
|
|
||||||
#define TRANSFER_BUFFER_SIZE 0x200
|
#define TRANSFER_BUFFER_SIZE 0x200
|
||||||
#define FORMAT_BUFFER_LEN 0x0FF
|
|
||||||
#define HW_VERSION "2.6"
|
|
||||||
#define SW_VERSION "1.0"
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -71,12 +71,10 @@ uint16_t crc_check_bulk_memory(uint32_t bottom_addr, uint32_t top_addr, uint32_t
|
|||||||
uint32_t addr = 0;
|
uint32_t addr = 0;
|
||||||
uint8_t req_bank = 0;
|
uint8_t req_bank = 0;
|
||||||
sram_bulk_read_start(bottom_addr);
|
sram_bulk_read_start(bottom_addr);
|
||||||
debug_P(DEBUG_CRC, PSTR("crc_check_bulk_memory: bottom_addr=0x%08lx top_addr=0x%08lx\n"),
|
|
||||||
bottom_addr,top_addr);
|
|
||||||
|
|
||||||
for (addr = bottom_addr; addr < top_addr; addr++) {
|
for (addr = bottom_addr; addr < top_addr; addr++) {
|
||||||
if (addr && addr % bank_size == 0) {
|
if (addr && addr % bank_size == 0) {
|
||||||
debug_P(DEBUG_CRC, PSTR("crc_check_bulk_memory: bank=0x%02x addr=0x%08lx crc=0x%04x\n"),
|
debug(DEBUG_CRC,"crc_check_bulk_memory: bank=0x%02x addr=0x%08lx crc=0x%04x\n",
|
||||||
req_bank,addr,crc);
|
req_bank,addr,crc);
|
||||||
req_bank++;
|
req_bank++;
|
||||||
crc = 0;
|
crc = 0;
|
||||||
@@ -85,7 +83,7 @@ uint16_t crc_check_bulk_memory(uint32_t bottom_addr, uint32_t top_addr, uint32_t
|
|||||||
sram_bulk_read_next();
|
sram_bulk_read_next();
|
||||||
}
|
}
|
||||||
if (addr % 0x8000 == 0)
|
if (addr % 0x8000 == 0)
|
||||||
debug_P(DEBUG_CRC, PSTR("crc_check_bulk_memory: bank=0x%02x addr=0x%08lx crc=0x%04x\n"),
|
debug(DEBUG_CRC,"crc_check_bulk_memory: bank=0x%02x addr=0x%08lx crc=0x%04x\n",
|
||||||
req_bank,addr,crc);
|
req_bank,addr,crc);
|
||||||
sram_bulk_read_end();
|
sram_bulk_read_end();
|
||||||
return crc;
|
return crc;
|
||||||
@@ -99,7 +97,7 @@ uint16_t crc_check_memory_range(uint32_t start_addr, uint32_t size,uint8_t *buff
|
|||||||
uint16_t crc = 0;
|
uint16_t crc = 0;
|
||||||
uint32_t addr;
|
uint32_t addr;
|
||||||
for (addr = start_addr; addr < start_addr + size; addr += TRANSFER_BUFFER_SIZE) {
|
for (addr = start_addr; addr < start_addr + size; addr += TRANSFER_BUFFER_SIZE) {
|
||||||
sram_bulk_copy_into_buffer(addr, buffer, TRANSFER_BUFFER_SIZE);
|
sram_bulk_read_buffer(addr, buffer, TRANSFER_BUFFER_SIZE);
|
||||||
crc = do_crc_update(crc, buffer, TRANSFER_BUFFER_SIZE);
|
crc = do_crc_update(crc, buffer, TRANSFER_BUFFER_SIZE);
|
||||||
}
|
}
|
||||||
return crc;
|
return crc;
|
||||||
|
|||||||
@@ -20,11 +20,11 @@
|
|||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <avr/pgmspace.h>
|
|
||||||
|
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "uart.h"
|
#include "uart.h"
|
||||||
#include "config.h"
|
|
||||||
|
|
||||||
|
|
||||||
extern FILE uart_stdout;
|
extern FILE uart_stdout;
|
||||||
|
|
||||||
@@ -46,23 +46,4 @@ void debug(int level, char* format, ...) {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef NO_INFO
|
|
||||||
uint8_t buffer_debug[FORMAT_BUFFER_LEN];
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(NO_DEBUG) && defined(__GNUC__)
|
|
||||||
#else
|
|
||||||
void debug_P(int level, PGM_P format, ...) {
|
|
||||||
#ifdef NO_DEBUG
|
|
||||||
|
|
||||||
#else
|
|
||||||
va_list args;
|
|
||||||
if (!(debug_level & level))
|
|
||||||
return;
|
|
||||||
strlcpy_P(buffer_debug,format,FORMAT_BUFFER_LEN);
|
|
||||||
va_start(args, format);
|
|
||||||
vprintf(buffer_debug, args);
|
|
||||||
va_end(args);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
@@ -26,7 +26,7 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <avr/pgmspace.h>
|
|
||||||
|
|
||||||
#if defined(NO_DEBUG) && defined(__GNUC__)
|
#if defined(NO_DEBUG) && defined(__GNUC__)
|
||||||
/* gcc's cpp has extensions; it allows for macros with a variable number of
|
/* gcc's cpp has extensions; it allows for macros with a variable number of
|
||||||
@@ -39,17 +39,5 @@ void debug(int level, char *format, ...);
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#if defined(NO_DEBUG) && defined(__GNUC__)
|
|
||||||
/* gcc's cpp has extensions; it allows for macros with a variable number of
|
|
||||||
arguments. We use this extension here to preprocess pmesg away. */
|
|
||||||
#define debug_P(level, format, args...) ((void)0)
|
|
||||||
#else
|
|
||||||
void debug_P(int level, PGM_P format, ...);
|
|
||||||
/* print a message, if it is considered significant enough.
|
|
||||||
Adapted from [K&R2], p. 174 */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* DEBUG_H */
|
#endif /* DEBUG_H */
|
||||||
|
|
||||||
|
|||||||
@@ -47,21 +47,21 @@ void dump_packet(uint32_t addr, uint32_t len, uint8_t * packet)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (clear) {
|
if (clear) {
|
||||||
info_P(PSTR("*\n"));
|
info("*\n");
|
||||||
clear = 0;
|
clear = 0;
|
||||||
}
|
}
|
||||||
info_P(PSTR("%08lx:"), addr + i);
|
info("%08lx:", addr + i);
|
||||||
for (j = 0; j < 16; j++) {
|
for (j = 0; j < 16; j++) {
|
||||||
info_P(PSTR(" %02x"), packet[i + j]);
|
info(" %02x", packet[i + j]);
|
||||||
}
|
}
|
||||||
info_P(PSTR(" |"));
|
info(" |");
|
||||||
for (j = 0; j < 16; j++) {
|
for (j = 0; j < 16; j++) {
|
||||||
if (packet[i + j] >= 33 && packet[i + j] <= 126)
|
if (packet[i + j] >= 33 && packet[i + j] <= 126)
|
||||||
info_P(PSTR("%c"), packet[i + j]);
|
info("%c", packet[i + j]);
|
||||||
else
|
else
|
||||||
info_P(PSTR("."));
|
info(".");
|
||||||
}
|
}
|
||||||
info_P(PSTR("|\n"));
|
info("|\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -72,11 +72,11 @@ void dump_memory(uint32_t bottom_addr, uint32_t top_addr)
|
|||||||
sram_bulk_read_start(bottom_addr);
|
sram_bulk_read_start(bottom_addr);
|
||||||
for ( addr = bottom_addr; addr < top_addr; addr++) {
|
for ( addr = bottom_addr; addr < top_addr; addr++) {
|
||||||
if (addr%0x10 == 0)
|
if (addr%0x10 == 0)
|
||||||
info_P(PSTR("\n%08lx:"), addr);
|
info("\n%08lx:", addr);
|
||||||
byte = sram_bulk_read();
|
byte = sram_bulk_read();
|
||||||
sram_bulk_read_next();
|
sram_bulk_read_next();
|
||||||
info_P(PSTR(" %02x"), byte);
|
info(" %02x", byte);
|
||||||
}
|
}
|
||||||
info_P(PSTR("\n"));
|
info("\n");
|
||||||
sram_bulk_read_end();
|
sram_bulk_read_end();
|
||||||
}
|
}
|
||||||
|
|||||||
547
avr/usbload/ff.h
Normal file
547
avr/usbload/ff.h
Normal file
@@ -0,0 +1,547 @@
|
|||||||
|
/*---------------------------------------------------------------------------/
|
||||||
|
/ FatFs - FAT file system module include file R0.07a (C)ChaN, 2009
|
||||||
|
/----------------------------------------------------------------------------/
|
||||||
|
/ FatFs module is an open source software to implement FAT file system to
|
||||||
|
/ small embedded systems. This is a free software and is opened for education,
|
||||||
|
/ research and commercial developments under license policy of following trems.
|
||||||
|
/
|
||||||
|
/ Copyright (C) 2009, ChaN, all right reserved.
|
||||||
|
/
|
||||||
|
/ * The FatFs module is a free software and there is NO WARRANTY.
|
||||||
|
/ * No restriction on use. You can use, modify and redistribute it for
|
||||||
|
/ personal, non-profit or commercial use UNDER YOUR RESPONSIBILITY.
|
||||||
|
/ * Redistributions of source code must retain the above copyright notice.
|
||||||
|
/----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "integer.h"
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------/
|
||||||
|
/ FatFs Configuration Options
|
||||||
|
/
|
||||||
|
/ CAUTION! Do not forget to make clean the project after any changes to
|
||||||
|
/ the configuration options.
|
||||||
|
/
|
||||||
|
/----------------------------------------------------------------------------*/
|
||||||
|
#ifndef _FATFS
|
||||||
|
#define _FATFS
|
||||||
|
|
||||||
|
#define _WORD_ACCESS 1
|
||||||
|
/* The _WORD_ACCESS option defines which access method is used to the word
|
||||||
|
/ data in the FAT structure.
|
||||||
|
/
|
||||||
|
/ 0: Byte-by-byte access. Always compatible with all platforms.
|
||||||
|
/ 1: Word access. Do not choose this unless following condition is met.
|
||||||
|
/
|
||||||
|
/ When the byte order on the memory is big-endian or address miss-aligned
|
||||||
|
/ word access results incorrect behavior, the _WORD_ACCESS must be set to 0.
|
||||||
|
/ If it is not the case, the value can also be set to 1 to improve the
|
||||||
|
/ performance and code efficiency. */
|
||||||
|
|
||||||
|
|
||||||
|
#define _FS_READONLY 0
|
||||||
|
/* Setting _FS_READONLY to 1 defines read only configuration. This removes
|
||||||
|
/ writing functions, f_write, f_sync, f_unlink, f_mkdir, f_chmod, f_rename,
|
||||||
|
/ f_truncate and useless f_getfree. */
|
||||||
|
|
||||||
|
|
||||||
|
#define _FS_MINIMIZE 0
|
||||||
|
/* The _FS_MINIMIZE option defines minimization level to remove some functions.
|
||||||
|
/
|
||||||
|
/ 0: Full function.
|
||||||
|
/ 1: f_stat, f_getfree, f_unlink, f_mkdir, f_chmod, f_truncate and f_rename
|
||||||
|
/ are removed.
|
||||||
|
/ 2: f_opendir and f_readdir are removed in addition to level 1.
|
||||||
|
/ 3: f_lseek is removed in addition to level 2. */
|
||||||
|
|
||||||
|
|
||||||
|
#define _FS_TINY 1
|
||||||
|
/* When _FS_TINY is set to 1, FatFs uses the sector buffer in the file system
|
||||||
|
/ object instead of the sector buffer in the individual file object for file
|
||||||
|
/ data transfer. This reduces memory consumption 512 bytes each file object. */
|
||||||
|
|
||||||
|
|
||||||
|
#define _USE_STRFUNC 0
|
||||||
|
/* To enable string functions, set _USE_STRFUNC to 1 or 2. */
|
||||||
|
|
||||||
|
|
||||||
|
#define _USE_MKFS 1
|
||||||
|
/* To enable f_mkfs function, set _USE_MKFS to 1 and set _FS_READONLY to 0 */
|
||||||
|
|
||||||
|
|
||||||
|
#define _USE_FORWARD 0
|
||||||
|
/* To enable f_forward function, set _USE_FORWARD to 1 and set _FS_TINY to 1. */
|
||||||
|
|
||||||
|
|
||||||
|
#define _DRIVES 2
|
||||||
|
/* Number of volumes (logical drives) to be used. */
|
||||||
|
|
||||||
|
|
||||||
|
#define _MAX_SS 512
|
||||||
|
/* Maximum sector size to be handled. (512/1024/2048/4096) */
|
||||||
|
/* 512 for memroy card and hard disk, 1024 for floppy disk, 2048 for MO disk */
|
||||||
|
|
||||||
|
|
||||||
|
#define _MULTI_PARTITION 0
|
||||||
|
/* When _MULTI_PARTITION is set to 0, each volume is bound to the same physical
|
||||||
|
/ drive number and can mount only first primaly partition. When it is set to 1,
|
||||||
|
/ each volume is tied to the partitions listed in Drives[]. */
|
||||||
|
|
||||||
|
|
||||||
|
#define _CODE_PAGE 437
|
||||||
|
/* The _CODE_PAGE specifies the OEM code page to be used on the target system.
|
||||||
|
/ When it is non LFN configuration, there is no difference between SBCS code
|
||||||
|
/ pages. When LFN is enabled, the code page must always be set correctly.
|
||||||
|
/ 437 - U.S.
|
||||||
|
/ 720 - Arabic
|
||||||
|
/ 737 - Greek
|
||||||
|
/ 775 - Baltic
|
||||||
|
/ 850 - Multilingual Latin 1
|
||||||
|
/ 852 - Latin 2
|
||||||
|
/ 855 - Cyrillic
|
||||||
|
/ 857 - Turkish
|
||||||
|
/ 858 - Multilingual Latin 1 + Euro
|
||||||
|
/ 862 - Hebrew
|
||||||
|
/ 866 - Russian
|
||||||
|
/ 874 - Thai
|
||||||
|
/ 932 - Japanese Shift-JIS (DBCS)
|
||||||
|
/ 936 - Simplified Chinese GBK (DBCS)
|
||||||
|
/ 949 - Korean (DBCS)
|
||||||
|
/ 950 - Traditional Chinese Big5 (DBCS)
|
||||||
|
/ 1258 - Vietnam
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#define _USE_LFN 0
|
||||||
|
#define _MAX_LFN 255 /* Maximum LFN length to handle (max:255) */
|
||||||
|
/* The _USE_LFN option switches the LFN support.
|
||||||
|
/
|
||||||
|
/ 0: Disable LFN.
|
||||||
|
/ 1: Enable LFN with static working buffer on the bss. NOT REENTRANT.
|
||||||
|
/ 2: Enable LFN with dynamic working buffer on the caller's STACK.
|
||||||
|
/
|
||||||
|
/ The working buffer occupies (_MAX_LFN + 1) * 2 bytes. When enable LFN,
|
||||||
|
/ a Unicode - OEM code conversion function ff_convert() must be added to
|
||||||
|
/ the project. */
|
||||||
|
|
||||||
|
|
||||||
|
#define _FS_REENTRANT 0
|
||||||
|
#define _TIMEOUT 1000 /* Timeout period in unit of time ticks */
|
||||||
|
#define _SYNC_t HANDLE /* Type of sync object used on the OS. */
|
||||||
|
/* e.g. HANDLE, OS_EVENT*, ID and etc.. */
|
||||||
|
/* To make the FatFs module re-entrant, set _FS_REENTRANT to 1 and add user
|
||||||
|
/ provided synchronization handlers, ff_req_grant, ff_rel_grant,
|
||||||
|
/ ff_del_syncobj and ff_cre_syncobj function to the project. */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* End of configuration options. Do not change followings without care. */
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Definitions corresponds to multiple sector size */
|
||||||
|
|
||||||
|
#if _MAX_SS == 512
|
||||||
|
#define SS(fs) 512
|
||||||
|
#else
|
||||||
|
#if _MAX_SS == 1024 || _MAX_SS == 2048 || _MAX_SS == 4096
|
||||||
|
#define SS(fs) ((fs)->s_size)
|
||||||
|
#else
|
||||||
|
#error Sector size must be 512, 1024, 2048 or 4096.
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* File system object structure */
|
||||||
|
|
||||||
|
typedef struct _FATFS {
|
||||||
|
BYTE fs_type; /* FAT sub type */
|
||||||
|
BYTE drive; /* Physical drive number */
|
||||||
|
BYTE csize; /* Number of sectors per cluster */
|
||||||
|
BYTE n_fats; /* Number of FAT copies */
|
||||||
|
BYTE wflag; /* win[] dirty flag (1:must be written back) */
|
||||||
|
BYTE pad1;
|
||||||
|
WORD id; /* File system mount ID */
|
||||||
|
WORD n_rootdir; /* Number of root directory entries (0 on FAT32) */
|
||||||
|
#if _FS_REENTRANT
|
||||||
|
_SYNC_t sobj; /* Identifier of sync object */
|
||||||
|
#endif
|
||||||
|
#if _MAX_SS != 512U
|
||||||
|
WORD s_size; /* Sector size */
|
||||||
|
#endif
|
||||||
|
#if !_FS_READONLY
|
||||||
|
BYTE fsi_flag; /* fsinfo dirty flag (1:must be written back) */
|
||||||
|
BYTE pad2;
|
||||||
|
DWORD last_clust; /* Last allocated cluster */
|
||||||
|
DWORD free_clust; /* Number of free clusters */
|
||||||
|
DWORD fsi_sector; /* fsinfo sector */
|
||||||
|
#endif
|
||||||
|
DWORD sects_fat; /* Sectors per fat */
|
||||||
|
DWORD max_clust; /* Maximum cluster# + 1. Number of clusters is max_clust - 2 */
|
||||||
|
DWORD fatbase; /* FAT start sector */
|
||||||
|
DWORD dirbase; /* Root directory start sector (Cluster# on FAT32) */
|
||||||
|
DWORD database; /* Data start sector */
|
||||||
|
DWORD winsect; /* Current sector appearing in the win[] */
|
||||||
|
BYTE win[_MAX_SS];/* Disk access window for Directory/FAT */
|
||||||
|
} FATFS;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Directory object structure */
|
||||||
|
|
||||||
|
typedef struct _DIR {
|
||||||
|
WORD id; /* Owner file system mount ID */
|
||||||
|
WORD index; /* Current index number */
|
||||||
|
FATFS* fs; /* Pointer to the owner file system object */
|
||||||
|
DWORD sclust; /* Table start cluster (0:Static table) */
|
||||||
|
DWORD clust; /* Current cluster */
|
||||||
|
DWORD sect; /* Current sector */
|
||||||
|
BYTE* dir; /* Pointer to the current SFN entry in the win[] */
|
||||||
|
BYTE* fn; /* Pointer to the SFN (in/out) {file[8],ext[3],status[1]} */
|
||||||
|
#if _USE_LFN
|
||||||
|
WCHAR* lfn; /* Pointer to the LFN working buffer */
|
||||||
|
WORD lfn_idx; /* Last matched LFN index (0xFFFF:No LFN) */
|
||||||
|
#endif
|
||||||
|
} DIR;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* File object structure */
|
||||||
|
|
||||||
|
typedef struct _FIL {
|
||||||
|
FATFS* fs; /* Pointer to the owner file system object */
|
||||||
|
WORD id; /* Owner file system mount ID */
|
||||||
|
BYTE flag; /* File status flags */
|
||||||
|
BYTE csect; /* Sector address in the cluster */
|
||||||
|
DWORD fptr; /* File R/W pointer */
|
||||||
|
DWORD fsize; /* File size */
|
||||||
|
DWORD org_clust; /* File start cluster */
|
||||||
|
DWORD curr_clust; /* Current cluster */
|
||||||
|
DWORD dsect; /* Current data sector */
|
||||||
|
#if !_FS_READONLY
|
||||||
|
DWORD dir_sect; /* Sector containing the directory entry */
|
||||||
|
BYTE* dir_ptr; /* Ponter to the directory entry in the window */
|
||||||
|
#endif
|
||||||
|
#if !_FS_TINY
|
||||||
|
BYTE buf[_MAX_SS];/* File R/W buffer */
|
||||||
|
#endif
|
||||||
|
} FIL;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* File status structure */
|
||||||
|
|
||||||
|
typedef struct _FILINFO {
|
||||||
|
DWORD fsize; /* File size */
|
||||||
|
WORD fdate; /* Last modified date */
|
||||||
|
WORD ftime; /* Last modified time */
|
||||||
|
BYTE fattrib; /* Attribute */
|
||||||
|
char fname[13]; /* Short file name (8.3 format) */
|
||||||
|
#if _USE_LFN
|
||||||
|
char *lfname; /* Pointer to the LFN buffer */
|
||||||
|
int lfsize; /* Size of LFN buffer [bytes] */
|
||||||
|
#endif
|
||||||
|
} FILINFO;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* DBCS code ranges */
|
||||||
|
|
||||||
|
#if _CODE_PAGE == 932 /* CP932 (Japanese Shift-JIS) */
|
||||||
|
#define _DF1S 0x81 /* DBC 1st byte range 1 start */
|
||||||
|
#define _DF1E 0x9F /* DBC 1st byte range 1 end */
|
||||||
|
#define _DF2S 0xE0 /* DBC 1st byte range 2 start */
|
||||||
|
#define _DF2E 0xFC /* DBC 1st byte range 2 end */
|
||||||
|
#define _DS1S 0x40 /* DBC 2nd byte range 1 start */
|
||||||
|
#define _DS1E 0x7E /* DBC 2nd byte range 1 end */
|
||||||
|
#define _DS2S 0x80 /* DBC 2nd byte range 2 start */
|
||||||
|
#define _DS2E 0xFC /* DBC 2nd byte range 2 end */
|
||||||
|
|
||||||
|
#elif _CODE_PAGE == 936 /* CP936 (Simplified Chinese GBK) */
|
||||||
|
#define _DF1S 0x81
|
||||||
|
#define _DF1E 0xFE
|
||||||
|
#define _DS1S 0x40
|
||||||
|
#define _DS1E 0x7E
|
||||||
|
#define _DS2S 0x80
|
||||||
|
#define _DS2E 0xFE
|
||||||
|
|
||||||
|
#elif _CODE_PAGE == 949 /* CP949 (Korean) */
|
||||||
|
#define _DF1S 0x81
|
||||||
|
#define _DF1E 0xFE
|
||||||
|
#define _DS1S 0x41
|
||||||
|
#define _DS1E 0x5A
|
||||||
|
#define _DS2S 0x61
|
||||||
|
#define _DS2E 0x7A
|
||||||
|
#define _DS3S 0x81
|
||||||
|
#define _DS3E 0xFE
|
||||||
|
|
||||||
|
#elif _CODE_PAGE == 950 /* CP950 (Traditional Chinese Big5) */
|
||||||
|
#define _DF1S 0x81
|
||||||
|
#define _DF1E 0xFE
|
||||||
|
#define _DS1S 0x40
|
||||||
|
#define _DS1E 0x7E
|
||||||
|
#define _DS2S 0xA1
|
||||||
|
#define _DS2E 0xFE
|
||||||
|
|
||||||
|
#else /* SBCS code pages */
|
||||||
|
#define _DF1S 0
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Character code support macros */
|
||||||
|
|
||||||
|
#define IsUpper(c) (((c)>='A')&&((c)<='Z'))
|
||||||
|
#define IsLower(c) (((c)>='a')&&((c)<='z'))
|
||||||
|
#define IsDigit(c) (((c)>='0')&&((c)<='9'))
|
||||||
|
|
||||||
|
#if _DF1S /* DBCS configuration */
|
||||||
|
|
||||||
|
#if _DF2S /* Two 1st byte areas */
|
||||||
|
#define IsDBCS1(c) (((BYTE)(c) >= _DF1S && (BYTE)(c) <= _DF1E) || ((BYTE)(c) >= _DF2S && (BYTE)(c) <= _DF2E))
|
||||||
|
#else /* One 1st byte area */
|
||||||
|
#define IsDBCS1(c) ((BYTE)(c) >= _DF1S && (BYTE)(c) <= _DF1E)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if _DS3S /* Three 2nd byte areas */
|
||||||
|
#define IsDBCS2(c) (((BYTE)(c) >= _DS1S && (BYTE)(c) <= _DS1E) || ((BYTE)(c) >= _DS2S && (BYTE)(c) <= _DS2E) || ((BYTE)(c) >= _DS3S && (BYTE)(c) <= _DS3E))
|
||||||
|
#else /* Two 2nd byte areas */
|
||||||
|
#define IsDBCS2(c) (((BYTE)(c) >= _DS1S && (BYTE)(c) <= _DS1E) || ((BYTE)(c) >= _DS2S && (BYTE)(c) <= _DS2E))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#else /* SBCS configuration */
|
||||||
|
|
||||||
|
#define IsDBCS1(c) 0
|
||||||
|
#define IsDBCS2(c) 0
|
||||||
|
|
||||||
|
#endif /* _DF1S */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Definitions corresponds to multi partition */
|
||||||
|
|
||||||
|
#if _MULTI_PARTITION /* Multiple partition configuration */
|
||||||
|
|
||||||
|
typedef struct _PARTITION {
|
||||||
|
BYTE pd; /* Physical drive# */
|
||||||
|
BYTE pt; /* Partition # (0-3) */
|
||||||
|
} PARTITION;
|
||||||
|
|
||||||
|
extern
|
||||||
|
const PARTITION Drives[]; /* Logical drive# to physical location conversion table */
|
||||||
|
#define LD2PD(drv) (Drives[drv].pd) /* Get physical drive# */
|
||||||
|
#define LD2PT(drv) (Drives[drv].pt) /* Get partition# */
|
||||||
|
|
||||||
|
#else /* Single partition configuration */
|
||||||
|
|
||||||
|
#define LD2PD(drv) (drv) /* Physical drive# is equal to the logical drive# */
|
||||||
|
#define LD2PT(drv) 0 /* Always mounts the 1st partition */
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* File function return code (FRESULT) */
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
FR_OK = 0, /* 0 */
|
||||||
|
FR_DISK_ERR, /* 1 */
|
||||||
|
FR_INT_ERR, /* 2 */
|
||||||
|
FR_NOT_READY, /* 3 */
|
||||||
|
FR_NO_FILE, /* 4 */
|
||||||
|
FR_NO_PATH, /* 5 */
|
||||||
|
FR_INVALID_NAME, /* 6 */
|
||||||
|
FR_DENIED, /* 7 */
|
||||||
|
FR_EXIST, /* 8 */
|
||||||
|
FR_INVALID_OBJECT, /* 9 */
|
||||||
|
FR_WRITE_PROTECTED, /* 10 */
|
||||||
|
FR_INVALID_DRIVE, /* 11 */
|
||||||
|
FR_NOT_ENABLED, /* 12 */
|
||||||
|
FR_NO_FILESYSTEM, /* 13 */
|
||||||
|
FR_MKFS_ABORTED, /* 14 */
|
||||||
|
FR_TIMEOUT /* 15 */
|
||||||
|
} FRESULT;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------*/
|
||||||
|
/* FatFs module application interface */
|
||||||
|
|
||||||
|
FRESULT f_mount (BYTE, FATFS*); /* Mount/Unmount a logical drive */
|
||||||
|
FRESULT f_open (FIL*, const char*, BYTE); /* Open or create a file */
|
||||||
|
FRESULT f_read (FIL*, void*, UINT, UINT*); /* Read data from a file */
|
||||||
|
FRESULT f_write (FIL*, const void*, UINT, UINT*); /* Write data to a file */
|
||||||
|
FRESULT f_lseek (FIL*, DWORD); /* Move file pointer of a file object */
|
||||||
|
FRESULT f_close (FIL*); /* Close an open file object */
|
||||||
|
FRESULT f_opendir (DIR*, const char*); /* Open an existing directory */
|
||||||
|
FRESULT f_readdir (DIR*, FILINFO*); /* Read a directory item */
|
||||||
|
FRESULT f_stat (const char*, FILINFO*); /* Get file status */
|
||||||
|
FRESULT f_getfree (const char*, DWORD*, FATFS**); /* Get number of free clusters on the drive */
|
||||||
|
FRESULT f_truncate (FIL*); /* Truncate file */
|
||||||
|
FRESULT f_sync (FIL*); /* Flush cached data of a writing file */
|
||||||
|
FRESULT f_unlink (const char*); /* Delete an existing file or directory */
|
||||||
|
FRESULT f_mkdir (const char*); /* Create a new directory */
|
||||||
|
FRESULT f_chmod (const char*, BYTE, BYTE); /* Change attriburte of the file/dir */
|
||||||
|
FRESULT f_utime (const char*, const FILINFO*); /* Change timestamp of the file/dir */
|
||||||
|
FRESULT f_rename (const char*, const char*); /* Rename/Move a file or directory */
|
||||||
|
FRESULT f_forward (FIL*, UINT(*)(const BYTE*,UINT), UINT, UINT*); /* Forward data to the stream */
|
||||||
|
FRESULT f_mkfs (BYTE, BYTE, WORD); /* Create a file system on the drive */
|
||||||
|
|
||||||
|
#if _USE_STRFUNC
|
||||||
|
int f_putc (int, FIL*); /* Put a character to the file */
|
||||||
|
int f_puts (const char*, FIL*); /* Put a string to the file */
|
||||||
|
int f_printf (FIL*, const char*, ...); /* Put a formatted string to the file */
|
||||||
|
char* f_gets (char*, int, FIL*); /* Get a string from the file */
|
||||||
|
#define f_eof(fp) (((fp)->fptr == (fp)->fsize) ? 1 : 0)
|
||||||
|
#define f_error(fp) (((fp)->flag & FA__ERROR) ? 1 : 0)
|
||||||
|
#ifndef EOF
|
||||||
|
#define EOF -1
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------*/
|
||||||
|
/* User defined functions */
|
||||||
|
|
||||||
|
/* Real time clock */
|
||||||
|
#if !_FS_READONLY
|
||||||
|
DWORD get_fattime (void); /* 31-25: Year(0-127 org.1980), 24-21: Month(1-12), 20-16: Day(1-31) */
|
||||||
|
/* 15-11: Hour(0-23), 10-5: Minute(0-59), 4-0: Second(0-29 *2) */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Unicode - OEM code conversion */
|
||||||
|
#if _USE_LFN
|
||||||
|
WCHAR ff_convert (WCHAR, UINT);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Sync functions */
|
||||||
|
#if _FS_REENTRANT
|
||||||
|
BOOL ff_cre_syncobj(BYTE, _SYNC_t*);
|
||||||
|
BOOL ff_del_syncobj(_SYNC_t);
|
||||||
|
BOOL ff_req_grant(_SYNC_t);
|
||||||
|
void ff_rel_grant(_SYNC_t);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------*/
|
||||||
|
/* Flags and offset address */
|
||||||
|
|
||||||
|
|
||||||
|
/* File access control and file status flags (FIL.flag) */
|
||||||
|
|
||||||
|
#define FA_READ 0x01
|
||||||
|
#define FA_OPEN_EXISTING 0x00
|
||||||
|
#if _FS_READONLY == 0
|
||||||
|
#define FA_WRITE 0x02
|
||||||
|
#define FA_CREATE_NEW 0x04
|
||||||
|
#define FA_CREATE_ALWAYS 0x08
|
||||||
|
#define FA_OPEN_ALWAYS 0x10
|
||||||
|
#define FA__WRITTEN 0x20
|
||||||
|
#define FA__DIRTY 0x40
|
||||||
|
#endif
|
||||||
|
#define FA__ERROR 0x80
|
||||||
|
|
||||||
|
|
||||||
|
/* FAT sub type (FATFS.fs_type) */
|
||||||
|
|
||||||
|
#define FS_FAT12 1
|
||||||
|
#define FS_FAT16 2
|
||||||
|
#define FS_FAT32 3
|
||||||
|
|
||||||
|
|
||||||
|
/* File attribute bits for directory entry */
|
||||||
|
|
||||||
|
#define AM_RDO 0x01 /* Read only */
|
||||||
|
#define AM_HID 0x02 /* Hidden */
|
||||||
|
#define AM_SYS 0x04 /* System */
|
||||||
|
#define AM_VOL 0x08 /* Volume label */
|
||||||
|
#define AM_LFN 0x0F /* LFN entry */
|
||||||
|
#define AM_DIR 0x10 /* Directory */
|
||||||
|
#define AM_ARC 0x20 /* Archive */
|
||||||
|
#define AM_MASK 0x3F /* Mask of defined bits */
|
||||||
|
|
||||||
|
|
||||||
|
/* FatFs refers the members in the FAT structures with byte offset instead
|
||||||
|
/ of structure member because there are incompatibility of the packing option
|
||||||
|
/ between various compilers. */
|
||||||
|
|
||||||
|
#define BS_jmpBoot 0
|
||||||
|
#define BS_OEMName 3
|
||||||
|
#define BPB_BytsPerSec 11
|
||||||
|
#define BPB_SecPerClus 13
|
||||||
|
#define BPB_RsvdSecCnt 14
|
||||||
|
#define BPB_NumFATs 16
|
||||||
|
#define BPB_RootEntCnt 17
|
||||||
|
#define BPB_TotSec16 19
|
||||||
|
#define BPB_Media 21
|
||||||
|
#define BPB_FATSz16 22
|
||||||
|
#define BPB_SecPerTrk 24
|
||||||
|
#define BPB_NumHeads 26
|
||||||
|
#define BPB_HiddSec 28
|
||||||
|
#define BPB_TotSec32 32
|
||||||
|
#define BS_55AA 510
|
||||||
|
|
||||||
|
#define BS_DrvNum 36
|
||||||
|
#define BS_BootSig 38
|
||||||
|
#define BS_VolID 39
|
||||||
|
#define BS_VolLab 43
|
||||||
|
#define BS_FilSysType 54
|
||||||
|
|
||||||
|
#define BPB_FATSz32 36
|
||||||
|
#define BPB_ExtFlags 40
|
||||||
|
#define BPB_FSVer 42
|
||||||
|
#define BPB_RootClus 44
|
||||||
|
#define BPB_FSInfo 48
|
||||||
|
#define BPB_BkBootSec 50
|
||||||
|
#define BS_DrvNum32 64
|
||||||
|
#define BS_BootSig32 66
|
||||||
|
#define BS_VolID32 67
|
||||||
|
#define BS_VolLab32 71
|
||||||
|
#define BS_FilSysType32 82
|
||||||
|
|
||||||
|
#define FSI_LeadSig 0
|
||||||
|
#define FSI_StrucSig 484
|
||||||
|
#define FSI_Free_Count 488
|
||||||
|
#define FSI_Nxt_Free 492
|
||||||
|
|
||||||
|
#define MBR_Table 446
|
||||||
|
|
||||||
|
#define DIR_Name 0
|
||||||
|
#define DIR_Attr 11
|
||||||
|
#define DIR_NTres 12
|
||||||
|
#define DIR_CrtTime 14
|
||||||
|
#define DIR_CrtDate 16
|
||||||
|
#define DIR_FstClusHI 20
|
||||||
|
#define DIR_WrtTime 22
|
||||||
|
#define DIR_WrtDate 24
|
||||||
|
#define DIR_FstClusLO 26
|
||||||
|
#define DIR_FileSize 28
|
||||||
|
#define LDIR_Ord 0
|
||||||
|
#define LDIR_Attr 11
|
||||||
|
#define LDIR_Type 12
|
||||||
|
#define LDIR_Chksum 13
|
||||||
|
#define LDIR_FstClusLO 26
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*--------------------------------*/
|
||||||
|
/* Multi-byte word access macros */
|
||||||
|
|
||||||
|
#if _WORD_ACCESS == 1 /* Enable word access to the FAT structure */
|
||||||
|
#define LD_WORD(ptr) (WORD)(*(WORD*)(BYTE*)(ptr))
|
||||||
|
#define LD_DWORD(ptr) (DWORD)(*(DWORD*)(BYTE*)(ptr))
|
||||||
|
#define ST_WORD(ptr,val) *(WORD*)(BYTE*)(ptr)=(WORD)(val)
|
||||||
|
#define ST_DWORD(ptr,val) *(DWORD*)(BYTE*)(ptr)=(DWORD)(val)
|
||||||
|
#else /* Use byte-by-byte access to the FAT structure */
|
||||||
|
#define LD_WORD(ptr) (WORD)(((WORD)*(BYTE*)((ptr)+1)<<8)|(WORD)*(BYTE*)(ptr))
|
||||||
|
#define LD_DWORD(ptr) (DWORD)(((DWORD)*(BYTE*)((ptr)+3)<<24)|((DWORD)*(BYTE*)((ptr)+2)<<16)|((WORD)*(BYTE*)((ptr)+1)<<8)|*(BYTE*)(ptr))
|
||||||
|
#define ST_WORD(ptr,val) *(BYTE*)(ptr)=(BYTE)(val); *(BYTE*)((ptr)+1)=(BYTE)((WORD)(val)>>8)
|
||||||
|
#define ST_DWORD(ptr,val) *(BYTE*)(ptr)=(BYTE)(val); *(BYTE*)((ptr)+1)=(BYTE)((WORD)(val)>>8); *(BYTE*)((ptr)+2)=(BYTE)((DWORD)(val)>>16); *(BYTE*)((ptr)+3)=(BYTE)((DWORD)(val)>>24)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* _FATFS */
|
||||||
@@ -20,12 +20,9 @@
|
|||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <avr/pgmspace.h>
|
|
||||||
|
|
||||||
#include "info.h"
|
#include "info.h"
|
||||||
#include "uart.h"
|
#include "uart.h"
|
||||||
#include "config.h"
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -49,26 +46,4 @@ void info(char* format, ...) {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#ifndef NO_INFO
|
|
||||||
uint8_t buffer_info[FORMAT_BUFFER_LEN];
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(NO_INFO) && defined(__GNUC__)
|
|
||||||
|
|
||||||
#define info(format, args...) ((void)0)
|
|
||||||
|
|
||||||
#else
|
|
||||||
void info_P(PGM_P format, ...) {
|
|
||||||
#ifdef NO_INFO
|
|
||||||
|
|
||||||
#else
|
|
||||||
strlcpy_P(buffer_info,format,FORMAT_BUFFER_LEN);
|
|
||||||
va_list args;
|
|
||||||
va_start(args, format);
|
|
||||||
vprintf(buffer_info, args);
|
|
||||||
va_end(args);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|||||||
@@ -26,7 +26,7 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <avr/pgmspace.h>
|
|
||||||
|
|
||||||
#if defined(NO_INFO) && defined(__GNUC__)
|
#if defined(NO_INFO) && defined(__GNUC__)
|
||||||
/* gcc's cpp has extensions; it allows for macros with a variable number of
|
/* gcc's cpp has extensions; it allows for macros with a variable number of
|
||||||
@@ -39,15 +39,4 @@ void info(char *format, ...);
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#if defined(NO_INFO) && defined(__GNUC__)
|
|
||||||
/* gcc's cpp has extensions; it allows for macros with a variable number of
|
|
||||||
arguments. We use this extension here to preprocess pmesg away. */
|
|
||||||
#define info_P(format, args...) ((void)0)
|
|
||||||
#else
|
|
||||||
void info_P(PGM_P format, ...);
|
|
||||||
/* print a message, if it is considered significant enough.
|
|
||||||
Adapted from [K&R2], p. 174 */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,72 +0,0 @@
|
|||||||
/*
|
|
||||||
* =====================================================================================
|
|
||||||
*
|
|
||||||
* ________ .__ __ ________ ____ ________
|
|
||||||
* \_____ \ __ __|__| ____ | | __\______ \ _______ _/_ |/ _____/
|
|
||||||
* / / \ \| | \ |/ ___\| |/ / | | \_/ __ \ \/ /| / __ \
|
|
||||||
* / \_/. \ | / \ \___| < | ` \ ___/\ / | \ |__\ \
|
|
||||||
* \_____\ \_/____/|__|\___ >__|_ \/_______ /\___ >\_/ |___|\_____ /
|
|
||||||
* \__> \/ \/ \/ \/ \/
|
|
||||||
*
|
|
||||||
* www.optixx.org
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* Version: 1.0
|
|
||||||
* Created: 07/21/2009 03:32:16 PM
|
|
||||||
* Author: david@optixx.org
|
|
||||||
*
|
|
||||||
* =====================================================================================
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <avr/io.h>
|
|
||||||
#include <avr/interrupt.h> /* for sei() */
|
|
||||||
#include <avr/wdt.h>
|
|
||||||
|
|
||||||
|
|
||||||
#include "usbdrv.h"
|
|
||||||
#include "oddebug.h" /* This is also an example for using debug
|
|
||||||
* macros */
|
|
||||||
#include "debug.h"
|
|
||||||
#include "info.h"
|
|
||||||
#include "sram.h"
|
|
||||||
|
|
||||||
|
|
||||||
void (*jump_to_app) (void) = 0x0000;
|
|
||||||
|
|
||||||
void irq_init(){
|
|
||||||
cli();
|
|
||||||
PCMSK3 |=(1<<PCINT27);
|
|
||||||
PCICR |= (1<<PCIE3);
|
|
||||||
sei();
|
|
||||||
}
|
|
||||||
|
|
||||||
void irq_stop(){
|
|
||||||
cli();
|
|
||||||
PCMSK3 &=~(1<<PCINT27);
|
|
||||||
sei();
|
|
||||||
}
|
|
||||||
|
|
||||||
void leave_application(void)
|
|
||||||
{
|
|
||||||
cli();
|
|
||||||
usbDeviceDisconnect();
|
|
||||||
wdt_enable(WDTO_15MS);
|
|
||||||
while (1);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ISR (SIG_PIN_CHANGE3)
|
|
||||||
{
|
|
||||||
if (snes_reset_test()){
|
|
||||||
info_P(PSTR("Catch SNES reset button\n"));
|
|
||||||
info_P(PSTR("Set watchdog...\n"));
|
|
||||||
leave_application();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
/*
|
|
||||||
* =====================================================================================
|
|
||||||
*
|
|
||||||
* ________ .__ __ ________ ____ ________
|
|
||||||
* \_____ \ __ __|__| ____ | | __\______ \ _______ _/_ |/ _____/
|
|
||||||
* / / \ \| | \ |/ ___\| |/ / | | \_/ __ \ \/ /| / __ \
|
|
||||||
* / \_/. \ | / \ \___| < | ` \ ___/\ / | \ |__\ \
|
|
||||||
* \_____\ \_/____/|__|\___ >__|_ \/_______ /\___ >\_/ |___|\_____ /
|
|
||||||
* \__> \/ \/ \/ \/ \/
|
|
||||||
*
|
|
||||||
* www.optixx.org
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* Version: 1.0
|
|
||||||
* Created: 07/21/2009 03:32:16 PM
|
|
||||||
* Author: david@optixx.org
|
|
||||||
*
|
|
||||||
* =====================================================================================
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef __IRQ_H__
|
|
||||||
#define __IRQ_H__
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -6,6 +6,4 @@
|
|||||||
#define ROM_HUFFMAN_SIZE 0
|
#define ROM_HUFFMAN_SIZE 0
|
||||||
#define ROM_RLE_SIZE 31091
|
#define ROM_RLE_SIZE 31091
|
||||||
|
|
||||||
void irq_init();
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -51,7 +51,7 @@
|
|||||||
extern const char _rom[] PROGMEM;
|
extern const char _rom[] PROGMEM;
|
||||||
extern FILE uart_stdout;
|
extern FILE uart_stdout;
|
||||||
|
|
||||||
uint8_t debug_level = (DEBUG | DEBUG_USB | DEBUG_CRC | DEBUG_SHM);
|
uint8_t debug_level = (DEBUG | DEBUG_USB | DEBUG_CRC);
|
||||||
|
|
||||||
uint8_t read_buffer[TRANSFER_BUFFER_SIZE];
|
uint8_t read_buffer[TRANSFER_BUFFER_SIZE];
|
||||||
uint32_t req_addr = 0;
|
uint32_t req_addr = 0;
|
||||||
@@ -84,7 +84,7 @@ usbMsgLen_t usbFunctionSetup(uchar data[8])
|
|||||||
|
|
||||||
req_bank = 0;
|
req_bank = 0;
|
||||||
rx_remaining = 0;
|
rx_remaining = 0;
|
||||||
debug_P(DEBUG_USB, PSTR("USB_BULK_UPLOAD_INIT: %i %i\n"), rq->wValue.word,
|
debug(DEBUG_USB, "USB_BULK_UPLOAD_INIT: %i %i\n", rq->wValue.word,
|
||||||
rq->wIndex.word);
|
rq->wIndex.word);
|
||||||
req_bank_size = (uint32_t) (1L << rq->wValue.word);
|
req_bank_size = (uint32_t) (1L << rq->wValue.word);
|
||||||
req_bank_cnt = rq->wIndex.word;
|
req_bank_cnt = rq->wIndex.word;
|
||||||
@@ -92,8 +92,8 @@ usbMsgLen_t usbFunctionSetup(uchar data[8])
|
|||||||
req_percent = 0;
|
req_percent = 0;
|
||||||
req_percent_last = 0;
|
req_percent_last = 0;
|
||||||
sync_errors = 0;
|
sync_errors = 0;
|
||||||
debug_P(DEBUG_USB,
|
debug(DEBUG_USB,
|
||||||
PSTR("USB_BULK_UPLOAD_INIT: bank_size=0x%08lx bank_cnt=0x%x end_addr=0x%08lx\n"),
|
"USB_BULK_UPLOAD_INIT: bank_size=0x%08lx bank_cnt=0x%x end_addr=0x%08lx\n",
|
||||||
req_bank_size, req_bank_cnt, req_addr_end);
|
req_bank_size, req_bank_cnt, req_addr_end);
|
||||||
|
|
||||||
shared_memory_write(SHARED_MEM_TX_CMD_BANK_COUNT, req_bank_cnt);
|
shared_memory_write(SHARED_MEM_TX_CMD_BANK_COUNT, req_bank_cnt);
|
||||||
@@ -114,12 +114,12 @@ usbMsgLen_t usbFunctionSetup(uchar data[8])
|
|||||||
|
|
||||||
if (req_addr && req_addr % req_bank_size == 0) {
|
if (req_addr && req_addr % req_bank_size == 0) {
|
||||||
#ifdef FLT_DEBUG
|
#ifdef FLT_DEBUG
|
||||||
debug_P(DEBUG_USB,
|
debug(DEBUG_USB,
|
||||||
PSTR("USB_BULK_UPLOAD_ADDR: req_bank=0x%02x addr=0x%08lx time=%.4f\n"),
|
"USB_BULK_UPLOAD_ADDR: req_bank=0x%02x addr=0x%08lx time=%.4f\n",
|
||||||
req_bank, req_addr, timer_stop());
|
req_bank, req_addr, timer_stop());
|
||||||
#else
|
#else
|
||||||
debug_P(DEBUG_USB,
|
debug(DEBUG_USB,
|
||||||
PSTR("USB_BULK_UPLOAD_ADDR: req_bank=0x%02x addr=0x%08lx time=%i\n"),
|
"USB_BULK_UPLOAD_ADDR: req_bank=0x%02x addr=0x%08lx time=%i\n",
|
||||||
req_bank, req_addr, timer_stop_int());
|
req_bank, req_addr, timer_stop_int());
|
||||||
#endif
|
#endif
|
||||||
req_bank++;
|
req_bank++;
|
||||||
@@ -145,8 +145,8 @@ usbMsgLen_t usbFunctionSetup(uchar data[8])
|
|||||||
|
|
||||||
req_percent = (uint32_t)( 100 * req_addr ) / req_addr_end;
|
req_percent = (uint32_t)( 100 * req_addr ) / req_addr_end;
|
||||||
if (req_percent!=req_percent_last){
|
if (req_percent!=req_percent_last){
|
||||||
//debug_P(DEBUG_USB,
|
debug(DEBUG_USB,
|
||||||
// PSTR("USB_BULK_UPLOAD_ADDR: precent=%i\n", req_percent);
|
"USB_BULK_UPLOAD_ADDR: precent=%i\n", req_percent);
|
||||||
shared_memory_write(SHARED_MEM_TX_CMD_UPLOAD_PROGESS, req_percent);
|
shared_memory_write(SHARED_MEM_TX_CMD_UPLOAD_PROGESS, req_percent);
|
||||||
sram_bulk_write_start(req_addr);
|
sram_bulk_write_start(req_addr);
|
||||||
}
|
}
|
||||||
@@ -154,8 +154,8 @@ usbMsgLen_t usbFunctionSetup(uchar data[8])
|
|||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
if (req_addr && (req_addr % 0x1000) == 0) {
|
if (req_addr && (req_addr % 0x1000) == 0) {
|
||||||
debug_P(DEBUG_USB,
|
debug(DEBUG_USB,
|
||||||
PSTR("USB_BULK_UPLOAD_NEXT: bank=0x%02x addr=0x%08lx crc=%04x\n",
|
"USB_BULK_UPLOAD_NEXT: bank=0x%02x addr=0x%08lx crc=%04x\n",
|
||||||
req_bank, req_addr, crc_check_bulk_memory(req_addr - 0x1000,
|
req_bank, req_addr, crc_check_bulk_memory(req_addr - 0x1000,
|
||||||
req_addr,
|
req_addr,
|
||||||
req_bank_size));
|
req_bank_size));
|
||||||
@@ -163,24 +163,14 @@ usbMsgLen_t usbFunctionSetup(uchar data[8])
|
|||||||
}
|
}
|
||||||
sram_bulk_write_start(req_addr);
|
sram_bulk_write_start(req_addr);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if SHM_SCRATCHPAD
|
|
||||||
if (!shared_memory_scratchpad_region_save_helper(req_addr)){
|
|
||||||
debug_P(DEBUG_USB,
|
|
||||||
PSTR("USB_BULK_UPLOAD_NEXT: scratchpad_region_save_helper was dirty\n"));
|
|
||||||
sram_bulk_write_start(req_addr);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
if (req_addr && (req_addr % req_bank_size) == 0) {
|
if (req_addr && (req_addr % req_bank_size) == 0) {
|
||||||
#ifdef FLT_DEBUG
|
#ifdef FLT_DEBUG
|
||||||
debug_P(DEBUG_USB,
|
debug(DEBUG_USB,
|
||||||
PSTR("USB_BULK_UPLOAD_NEXT: req_bank=0x%02x addr=0x%08lx time=%.4f\n"),
|
"USB_BULK_UPLOAD_NEXT: req_bank=0x%02x addr=0x%08lx time=%.4f\n",
|
||||||
req_bank, req_addr, timer_stop());
|
req_bank, req_addr, timer_stop());
|
||||||
#else
|
#else
|
||||||
debug_P(DEBUG_USB,
|
debug(DEBUG_USB,
|
||||||
PSTR("USB_BULK_UPLOAD_NEXT: req_bank=0x%02x addr=0x%08lx time=%i\n"),
|
"USB_BULK_UPLOAD_NEXT: req_bank=0x%02x addr=0x%08lx time=%i\n",
|
||||||
req_bank, req_addr, timer_stop_int());
|
req_bank, req_addr, timer_stop_int());
|
||||||
#endif
|
#endif
|
||||||
req_bank++;
|
req_bank++;
|
||||||
@@ -195,11 +185,11 @@ usbMsgLen_t usbFunctionSetup(uchar data[8])
|
|||||||
*/
|
*/
|
||||||
} else if (rq->bRequest == USB_BULK_UPLOAD_END) {
|
} else if (rq->bRequest == USB_BULK_UPLOAD_END) {
|
||||||
if (req_state != REQ_STATUS_BULK_UPLOAD) {
|
if (req_state != REQ_STATUS_BULK_UPLOAD) {
|
||||||
debug_P(DEBUG_USB,
|
debug(DEBUG_USB,
|
||||||
PSTR("USB_BULK_UPLOAD_END: ERROR state is not REQ_STATUS_BULK_UPLOAD\n"));
|
"USB_BULK_UPLOAD_END: ERROR state is not REQ_STATUS_BULK_UPLOAD\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
debug_P(DEBUG_USB, PSTR("USB_BULK_UPLOAD_END:\n"));
|
debug(DEBUG_USB, "USB_BULK_UPLOAD_END:\n");
|
||||||
req_state = REQ_STATUS_IDLE;
|
req_state = REQ_STATUS_IDLE;
|
||||||
sram_bulk_write_end();
|
sram_bulk_write_end();
|
||||||
shared_memory_write(SHARED_MEM_TX_CMD_UPLOAD_END, 0);
|
shared_memory_write(SHARED_MEM_TX_CMD_UPLOAD_END, 0);
|
||||||
@@ -212,7 +202,7 @@ usbMsgLen_t usbFunctionSetup(uchar data[8])
|
|||||||
req_addr = rq->wValue.word;
|
req_addr = rq->wValue.word;
|
||||||
req_addr = req_addr << 16;
|
req_addr = req_addr << 16;
|
||||||
req_addr = req_addr | rq->wIndex.word;
|
req_addr = req_addr | rq->wIndex.word;
|
||||||
debug_P(DEBUG_USB, PSTR("USB_CRC: addr=0x%08lx \n"), req_addr);
|
debug(DEBUG_USB, "USB_CRC: addr=0x%08lx \n", req_addr);
|
||||||
crc_check_bulk_memory(0x000000, req_addr, req_bank_size);
|
crc_check_bulk_memory(0x000000, req_addr, req_bank_size);
|
||||||
ret_len = 0;
|
ret_len = 0;
|
||||||
/*
|
/*
|
||||||
@@ -220,20 +210,20 @@ usbMsgLen_t usbFunctionSetup(uchar data[8])
|
|||||||
*/
|
*/
|
||||||
} else if (rq->bRequest == USB_MODE_SNES) {
|
} else if (rq->bRequest == USB_MODE_SNES) {
|
||||||
req_state = REQ_STATUS_SNES;
|
req_state = REQ_STATUS_SNES;
|
||||||
debug_P(DEBUG_USB, PSTR("USB_MODE_SNES:\n"));
|
debug(DEBUG_USB, "USB_MODE_SNES:\n");
|
||||||
ret_len = 0;
|
ret_len = 0;
|
||||||
/*
|
/*
|
||||||
* -------------------------------------------------------------------------
|
* -------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
} else if (rq->bRequest == USB_MODE_AVR) {
|
} else if (rq->bRequest == USB_MODE_AVR) {
|
||||||
req_state = REQ_STATUS_AVR;
|
req_state = REQ_STATUS_AVR;
|
||||||
debug_P(DEBUG_USB, PSTR("USB_MODE_AVR:\n"));
|
debug(DEBUG_USB, "USB_MODE_AVR:\n");
|
||||||
ret_len = 0;
|
ret_len = 0;
|
||||||
/*
|
/*
|
||||||
* -------------------------------------------------------------------------
|
* -------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
} else if (rq->bRequest == USB_AVR_RESET) {
|
} else if (rq->bRequest == USB_AVR_RESET) {
|
||||||
debug_P(DEBUG_USB, PSTR("USB_AVR_RESET:\n"));
|
debug(DEBUG_USB, "USB_AVR_RESET:\n");
|
||||||
soft_reset();
|
soft_reset();
|
||||||
ret_len = 0;
|
ret_len = 0;
|
||||||
/*
|
/*
|
||||||
@@ -245,12 +235,12 @@ usbMsgLen_t usbFunctionSetup(uchar data[8])
|
|||||||
req_addr = rq->wValue.word;
|
req_addr = rq->wValue.word;
|
||||||
req_addr = req_addr << 16;
|
req_addr = req_addr << 16;
|
||||||
req_addr = req_addr | rq->wIndex.word;
|
req_addr = req_addr | rq->wIndex.word;
|
||||||
debug_P(DEBUG_USB, PSTR("USB_CRC_ADDR: addr=0x%lx size=%i\n"), req_addr,
|
debug(DEBUG_USB, "USB_CRC_ADDR: addr=0x%lx size=%i\n", req_addr,
|
||||||
rq->wLength.word);
|
rq->wLength.word);
|
||||||
req_size = rq->wLength.word;
|
req_size = rq->wLength.word;
|
||||||
req_size = req_size << 2;
|
req_size = req_size << 2;
|
||||||
tx_remaining = 2;
|
tx_remaining = 2;
|
||||||
debug_P(DEBUG_USB, PSTR("USB_CRC_ADDR: addr=0x%lx size=%li\n"), req_addr,
|
debug(DEBUG_USB, "USB_CRC_ADDR: addr=0x%lx size=%li\n", req_addr,
|
||||||
req_size);
|
req_size);
|
||||||
|
|
||||||
crc = crc_check_memory_range(req_addr, req_size, read_buffer);
|
crc = crc_check_memory_range(req_addr, req_size, read_buffer);
|
||||||
@@ -273,114 +263,117 @@ usbMsgLen_t usbFunctionSetup(uchar data[8])
|
|||||||
void usb_connect()
|
void usb_connect()
|
||||||
{
|
{
|
||||||
uint8_t i = 0;
|
uint8_t i = 0;
|
||||||
info_P(PSTR("USB init\n"));
|
info("USB init\n");
|
||||||
usbDeviceDisconnect(); /* enforce re-enumeration, do this while */
|
usbDeviceDisconnect(); /* enforce re-enumeration, do this while */
|
||||||
cli();
|
cli();
|
||||||
info_P(PSTR("USB disconnect\n"));
|
info("USB disconnect\n");
|
||||||
i = 10;
|
i = 10;
|
||||||
while (--i) { /* fake USB disconnect for > 250 ms */
|
while (--i) { /* fake USB disconnect for > 250 ms */
|
||||||
led_on();
|
led_on();
|
||||||
_delay_ms(15);
|
|
||||||
led_off();
|
|
||||||
_delay_ms(35);
|
_delay_ms(35);
|
||||||
|
led_off();
|
||||||
|
_delay_ms(65);
|
||||||
}
|
}
|
||||||
led_on();
|
led_on();
|
||||||
usbDeviceConnect();
|
usbDeviceConnect();
|
||||||
info_P(PSTR("USB connect\n"));
|
info("USB connect\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void boot_startup_rom()
|
void boot_startup_rom()
|
||||||
{
|
{
|
||||||
info_P(PSTR("Boot startup rom\n"));
|
|
||||||
info_P(PSTR("Activate AVR bus\n"));
|
|
||||||
|
info("Activate AVR bus\n");
|
||||||
avr_bus_active();
|
avr_bus_active();
|
||||||
info_P(PSTR("IRQ off\n"));
|
|
||||||
|
info("IRQ off\n");
|
||||||
snes_irq_lo();
|
snes_irq_lo();
|
||||||
snes_irq_off();
|
snes_irq_off();
|
||||||
|
|
||||||
snes_lorom();
|
snes_lorom();
|
||||||
|
info("Set Snes lowrom \n");
|
||||||
|
|
||||||
rle_decode(&_rom, ROM_BUFFER_SIZE, 0x000000);
|
rle_decode(&_rom, ROM_BUFFER_SIZE, 0x000000);
|
||||||
info_P(PSTR("\n"));
|
|
||||||
#if 1
|
|
||||||
dump_memory(0x10000 - 0x100, 0x10000);
|
dump_memory(0x10000 - 0x100, 0x10000);
|
||||||
#endif
|
|
||||||
|
snes_reset_hi();
|
||||||
|
snes_reset_off();
|
||||||
|
snes_irq_lo();
|
||||||
|
snes_irq_off();
|
||||||
|
info("IRQ off\n");
|
||||||
snes_hirom();
|
snes_hirom();
|
||||||
snes_wr_disable();
|
snes_wr_disable();
|
||||||
|
info("Disable snes WR\n");
|
||||||
snes_bus_active();
|
snes_bus_active();
|
||||||
info_P(PSTR("Activate SNES bus\n"));
|
info("Activate Snes bus\n");
|
||||||
|
_delay_ms(100);
|
||||||
|
info("Reset Snes\n");
|
||||||
send_reset();
|
send_reset();
|
||||||
_delay_ms(50);
|
_delay_ms(100);
|
||||||
send_reset();
|
#if 0
|
||||||
_delay_ms(50);
|
uint8_t i = 0;
|
||||||
|
i = 20;
|
||||||
|
info("Wait");
|
||||||
|
while (--i) {
|
||||||
|
_delay_ms(500);
|
||||||
|
info(".");
|
||||||
|
}
|
||||||
|
info("\n");
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void banner(){
|
|
||||||
uint8_t i;
|
|
||||||
for (i=0;i<40;i++)
|
|
||||||
info_P(PSTR("\n"));
|
|
||||||
info_P(PSTR(" ________ .__ __ ________ ____ ________\n"));
|
|
||||||
info_P(PSTR(" \\_____ \\ __ __|__| ____ | | __\\______ \\ _______ _/_ |/ _____/\n"));
|
|
||||||
info_P(PSTR(" / / \\ \\| | \\ |/ ___\\| |/ / | | \\_/ __ \\ \\/ /| / __ \\ \n"));
|
|
||||||
info_P(PSTR(" / \\_/. \\ | / \\ \\___| < | ` \\ ___/\\ / | \\ |__\\ \\ \n"));
|
|
||||||
info_P(PSTR(" \\_____\\ \\_/____/|__|\\___ >__|_ \\/_______ /\\___ >\\_/ |___|\\_____ / \n"));
|
|
||||||
info_P(PSTR(" \\__> \\/ \\/ \\/ \\/ \\/ \n"));
|
|
||||||
info_P(PSTR("\n"));
|
|
||||||
info_P(PSTR(" www.optixx.org\n"));
|
|
||||||
info_P(PSTR("\n"));
|
|
||||||
info_P(PSTR("System Hw: %s Sw: %s\n"),HW_VERSION,SW_VERSION);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void globals_init(){
|
|
||||||
req_addr = 0;
|
|
||||||
req_addr_end = 0;
|
|
||||||
req_state = REQ_STATUS_IDLE;
|
|
||||||
rx_remaining = 0;
|
|
||||||
tx_remaining = 0;
|
|
||||||
sync_errors = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
|
|
||||||
uart_init();
|
uart_init();
|
||||||
stdout = &uart_stdout;
|
stdout = &uart_stdout;
|
||||||
banner();
|
|
||||||
|
info("Sytem start\n");
|
||||||
system_init();
|
system_init();
|
||||||
snes_reset_hi();
|
|
||||||
snes_reset_off();
|
#if 0
|
||||||
irq_init();
|
test_read_write();
|
||||||
|
test_bulk_read_write();
|
||||||
|
test_crc();
|
||||||
|
while (1);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
info("Boot startup rom\n");
|
||||||
boot_startup_rom();
|
boot_startup_rom();
|
||||||
globals_init();
|
|
||||||
usbInit();
|
usbInit();
|
||||||
usb_connect();
|
usb_connect();
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
avr_bus_active();
|
avr_bus_active();
|
||||||
info_P(PSTR("Activate AVR bus\n"));
|
info("Activate AVR bus\n");
|
||||||
|
info("IRQ off\n");
|
||||||
|
snes_irq_lo();
|
||||||
|
snes_irq_off();
|
||||||
|
info("Set Snes lowrom\n");
|
||||||
snes_lorom();
|
snes_lorom();
|
||||||
info_P(PSTR("Disable SNES WR\n"));
|
info("Disable snes WR\n");
|
||||||
snes_wr_disable();
|
snes_wr_disable();
|
||||||
sei();
|
sei();
|
||||||
info_P(PSTR("USB poll\n"));
|
info("USB poll\n");
|
||||||
while (req_state != REQ_STATUS_SNES) {
|
while (req_state != REQ_STATUS_SNES) {
|
||||||
usbPoll();
|
usbPoll();
|
||||||
}
|
}
|
||||||
shared_memory_write(SHARED_MEM_TX_CMD_TERMINATE, 0);
|
shared_memory_write(SHARED_MEM_TX_CMD_TERMINATE, 0);
|
||||||
|
info("USB poll done\n");
|
||||||
#if SHM_SCRATCHPAD
|
|
||||||
shared_memory_scratchpad_region_tx_restore();
|
|
||||||
shared_memory_scratchpad_region_rx_restore();
|
|
||||||
#endif
|
|
||||||
info_P(PSTR("USB poll done\n"));
|
|
||||||
set_rom_mode();
|
set_rom_mode();
|
||||||
snes_wr_disable();
|
snes_wr_disable();
|
||||||
info_P(PSTR("Disable SNES WR\n"));
|
info("Disable snes WR\n");
|
||||||
snes_bus_active();
|
snes_bus_active();
|
||||||
info_P(PSTR("Activate SNES bus\n"));
|
info("Activate Snes bus\n");
|
||||||
irq_stop();
|
_delay_ms(100);
|
||||||
|
info("Reset Snes\n");
|
||||||
send_reset();
|
send_reset();
|
||||||
info_P(PSTR("Poll USB\n"));
|
|
||||||
while ((req_state != REQ_STATUS_AVR)) {
|
info("Poll\n");
|
||||||
|
while (req_state != REQ_STATUS_AVR) {
|
||||||
usbPoll();
|
usbPoll();
|
||||||
|
|
||||||
#ifdef DO_IRQ
|
#ifdef DO_IRQ
|
||||||
@@ -390,7 +383,7 @@ int main(void)
|
|||||||
while (--i) {
|
while (--i) {
|
||||||
_delay_ms(100);
|
_delay_ms(100);
|
||||||
}
|
}
|
||||||
info_P(PSTR("Send IRQ %i\n"), ++irq_count);
|
info("Send IRQ %i\n", ++irq_count);
|
||||||
send_irq();
|
send_irq();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -401,24 +394,24 @@ int main(void)
|
|||||||
i = 5;
|
i = 5;
|
||||||
while (--i) {
|
while (--i) {
|
||||||
_delay_ms(500);
|
_delay_ms(500);
|
||||||
info_P(PSTR("Wait to switch to snes mode %i\n"), i);
|
info("Wait to switch to snes mode %i\n", i);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (req_bank_size == 0x8000) {
|
if (req_bank_size == 0x8000) {
|
||||||
snes_lorom();
|
snes_lorom();
|
||||||
|
info("Set Snes lowrom \n");
|
||||||
} else {
|
} else {
|
||||||
snes_hirom();
|
snes_hirom();
|
||||||
|
info("Set Snes hirom \n");
|
||||||
}
|
}
|
||||||
snes_wr_disable();
|
snes_wr_disable();
|
||||||
info_P(PSTR("Disable SNES WR\n"));
|
info("Disable snes WR\n");
|
||||||
snes_bus_active();
|
snes_bus_active();
|
||||||
info_P(PSTR("Activate SNES bus\n"));
|
info("Activate Snes bus\n");
|
||||||
info_P(PSTR("Read 0x3000=%c\n"), c);
|
info("Read 0x3000=%c\n", c);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
irq_init();
|
|
||||||
boot_startup_rom();
|
|
||||||
globals_init();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,9 +22,9 @@
|
|||||||
#include <avr/io.h>
|
#include <avr/io.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <avr/pgmspace.h> /* required by usbdrv.h */
|
#include <avr/pgmspace.h>
|
||||||
#include <util/delay.h> /* for _delay_ms() */
|
#include <util/delay.h>
|
||||||
#include <avr/interrupt.h> /* for sei() */
|
#include <avr/interrupt.h>
|
||||||
|
|
||||||
#include "sram.h"
|
#include "sram.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
@@ -36,7 +36,7 @@ uint8_t rle_decode(PGM_VOID_P in_addr, int32_t in_len, uint32_t out_addr)
|
|||||||
{
|
{
|
||||||
uint8_t in_byte, in_repeat, last_byte;
|
uint8_t in_byte, in_repeat, last_byte;
|
||||||
uint32_t out_len, out_len_left;
|
uint32_t out_len, out_len_left;
|
||||||
info_P(PSTR("RLE decode len=%li addr=0x%08lx\n"), in_len, out_addr);
|
info("RLE decode len=%li addr=0x%08lx\n", in_len, out_addr);
|
||||||
last_byte = 0;
|
last_byte = 0;
|
||||||
|
|
||||||
out_len_left = out_len;
|
out_len_left = out_len;
|
||||||
@@ -63,7 +63,7 @@ uint8_t rle_decode(PGM_VOID_P in_addr, int32_t in_len, uint32_t out_addr)
|
|||||||
if (in_byte == RUNCHAR) {
|
if (in_byte == RUNCHAR) {
|
||||||
INBYTE(in_repeat);
|
INBYTE(in_repeat);
|
||||||
if (in_repeat != 0) {
|
if (in_repeat != 0) {
|
||||||
info_P(PSTR("Orphaned RLE code at start\n"));
|
info("Orphaned RLE code at start\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
OUTBYTE(RUNCHAR);
|
OUTBYTE(RUNCHAR);
|
||||||
@@ -74,7 +74,7 @@ uint8_t rle_decode(PGM_VOID_P in_addr, int32_t in_len, uint32_t out_addr)
|
|||||||
while (in_len > 0) {
|
while (in_len > 0) {
|
||||||
INBYTE(in_byte);
|
INBYTE(in_byte);
|
||||||
if (in_len % 1024 == 0)
|
if (in_len % 1024 == 0)
|
||||||
info_P(PSTR("."));
|
info(".");
|
||||||
if (in_byte == RUNCHAR) {
|
if (in_byte == RUNCHAR) {
|
||||||
INBYTE(in_repeat);
|
INBYTE(in_repeat);
|
||||||
if (in_repeat == 0) {
|
if (in_repeat == 0) {
|
||||||
|
|||||||
44
avr/usbload/rtc.c
Normal file
44
avr/usbload/rtc.c
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
/* RTC controls */
|
||||||
|
|
||||||
|
#include <avr/io.h>
|
||||||
|
#include "rtc.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
BOOL rtc_gettime (RTC *rtc)
|
||||||
|
{
|
||||||
|
BYTE buf[8];
|
||||||
|
|
||||||
|
|
||||||
|
rtc->sec = (buf[0] & 0x0F) + ((buf[0] >> 4) & 7) * 10;
|
||||||
|
rtc->min = (buf[1] & 0x0F) + (buf[1] >> 4) * 10;
|
||||||
|
rtc->hour = (buf[2] & 0x0F) + ((buf[2] >> 4) & 3) * 10;
|
||||||
|
rtc->wday = (buf[2] & 0x07);
|
||||||
|
rtc->mday = (buf[4] & 0x0F) + ((buf[4] >> 4) & 3) * 10;
|
||||||
|
rtc->month = (buf[5] & 0x0F) + ((buf[5] >> 4) & 1) * 10;
|
||||||
|
rtc->year = 2000 + (buf[6] & 0x0F) + (buf[6] >> 4) * 10;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
BOOL rtc_settime (const RTC *rtc)
|
||||||
|
{
|
||||||
|
|
||||||
|
BYTE buf[8];
|
||||||
|
|
||||||
|
|
||||||
|
buf[0] = rtc->sec / 10 * 16 + rtc->sec % 10;
|
||||||
|
buf[1] = rtc->min / 10 * 16 + rtc->min % 10;
|
||||||
|
buf[2] = rtc->hour / 10 * 16 + rtc->hour % 10;
|
||||||
|
buf[3] = rtc->wday & 7;
|
||||||
|
buf[4] = rtc->mday / 10 * 16 + rtc->mday % 10;
|
||||||
|
buf[5] = rtc->month / 10 * 16 + rtc->month % 10;
|
||||||
|
buf[6] = (rtc->year - 2000) / 10 * 16 + (rtc->year - 2000) % 10;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
15
avr/usbload/rtc.h
Normal file
15
avr/usbload/rtc.h
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
#include "integer.h"
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
WORD year; /* 2000..2099 */
|
||||||
|
BYTE month; /* 1..12 */
|
||||||
|
BYTE mday; /* 1.. 31 */
|
||||||
|
BYTE wday; /* 1..7 */
|
||||||
|
BYTE hour; /* 0..23 */
|
||||||
|
BYTE min; /* 0..59 */
|
||||||
|
BYTE sec; /* 0..59 */
|
||||||
|
} RTC;
|
||||||
|
|
||||||
|
BOOL rtc_gettime (RTC*); /* Get time */
|
||||||
|
BOOL rtc_settime (const RTC*); /* Set time */
|
||||||
|
|
||||||
@@ -29,7 +29,6 @@
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "sram.h"
|
#include "sram.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "dump.h"
|
|
||||||
#include "info.h"
|
#include "info.h"
|
||||||
|
|
||||||
uint8_t irq_addr_lo;
|
uint8_t irq_addr_lo;
|
||||||
@@ -39,117 +38,6 @@ uint8_t scratchpad_state;
|
|||||||
uint8_t scratchpad_cmd;
|
uint8_t scratchpad_cmd;
|
||||||
uint8_t scratchpad_payload;
|
uint8_t scratchpad_payload;
|
||||||
|
|
||||||
uint8_t scratchpad_region_rx[SHARED_MEM_RX_LOC_SIZE];
|
|
||||||
uint8_t scratchpad_region_tx[SHARED_MEM_TX_LOC_SIZE];
|
|
||||||
|
|
||||||
uint8_t scratchpad_locked_rx = 1;
|
|
||||||
uint8_t scratchpad_locked_tx = 1;
|
|
||||||
|
|
||||||
|
|
||||||
uint8_t shared_memory_scratchpad_region_save_helper(uint32_t addr){
|
|
||||||
|
|
||||||
if(addr > (SHARED_MEM_TX_LOC_STATE + SHARED_MEM_TX_LOC_SIZE) && scratchpad_locked_tx){
|
|
||||||
debug_P(DEBUG_SHM, PSTR("shared_memory_scratchpad_region_save_helper: open tx addr=0x%06lx\n"),addr);
|
|
||||||
shared_memory_scratchpad_region_tx_save();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if(addr > (SHARED_MEM_RX_LOC_STATE + SHARED_MEM_RX_LOC_SIZE) && scratchpad_locked_rx){
|
|
||||||
debug_P(DEBUG_SHM, PSTR("shared_memory_scratchpad_region_save_helper: open rx addr=0x%06lx\n"),addr);
|
|
||||||
shared_memory_scratchpad_region_rx_save();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void shared_memory_scratchpad_region_tx_save()
|
|
||||||
{
|
|
||||||
#if 0
|
|
||||||
uint16_t crc;
|
|
||||||
crc = crc_check_bulk_memory((uint32_t)SHARED_MEM_TX_LOC_STATE,
|
|
||||||
(uint32_t)(SHARED_MEM_TX_LOC_STATE + SHARED_MEM_TX_LOC_SIZE), 0x8000);
|
|
||||||
debug_P(DEBUG_SHM, PSTR("shared_memory_scratchpad_region_tx_save: crc=%x\n"),crc);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
debug_P(DEBUG_SHM, PSTR("shared_memory_scratchpad_region_tx_save: unlock\n"));
|
|
||||||
sram_bulk_copy_into_buffer((uint32_t)SHARED_MEM_TX_LOC_STATE,scratchpad_region_tx,
|
|
||||||
(uint32_t)SHARED_MEM_TX_LOC_SIZE);
|
|
||||||
scratchpad_locked_tx = 0;
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
dump_packet(SHARED_MEM_TX_LOC_STATE, SHARED_MEM_TX_LOC_SIZE, scratchpad_region_tx);
|
|
||||||
dump_memory(SHARED_MEM_TX_LOC_STATE, SHARED_MEM_TX_LOC_STATE + SHARED_MEM_TX_LOC_SIZE);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void shared_memory_scratchpad_region_rx_save()
|
|
||||||
{
|
|
||||||
#if 0
|
|
||||||
uint16_t crc;
|
|
||||||
crc = crc_check_bulk_memory((uint32_t)SHARED_MEM_RX_LOC_STATE,
|
|
||||||
(uint32_t)(SHARED_MEM_RX_LOC_STATE + SHARED_MEM_RX_LOC_SIZE), 0x8000);
|
|
||||||
debug_P(DEBUG_SHM, PSTR("shared_memory_scratchpad_region_tx_save: crc=%x\n"),crc);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
debug_P(DEBUG_SHM, PSTR("shared_memory_scratchpad_region_rx_save: unlock\n"));
|
|
||||||
sram_bulk_copy_into_buffer((uint32_t)SHARED_MEM_RX_LOC_STATE,scratchpad_region_rx,
|
|
||||||
(uint32_t)SHARED_MEM_RX_LOC_SIZE);
|
|
||||||
scratchpad_locked_rx = 0;
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
dump_packet(SHARED_MEM_RX_LOC_STATE, SHARED_MEM_RX_LOC_SIZE, scratchpad_region_tx);
|
|
||||||
dump_memory(SHARED_MEM_RX_LOC_STATE, SHARED_MEM_RX_LOC_STATE + SHARED_MEM_RX_LOC_SIZE);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void shared_memory_scratchpad_region_tx_restore()
|
|
||||||
{
|
|
||||||
if (scratchpad_locked_tx)
|
|
||||||
return;
|
|
||||||
|
|
||||||
debug_P(DEBUG_SHM, PSTR("shared_memory_scratchpad_region_tx_restore: lock\n"));
|
|
||||||
sram_bulk_copy_from_buffer((uint32_t)SHARED_MEM_TX_LOC_STATE,scratchpad_region_tx,
|
|
||||||
(uint32_t)SHARED_MEM_TX_LOC_SIZE);
|
|
||||||
scratchpad_locked_tx = 1;
|
|
||||||
#if 0
|
|
||||||
dump_packet(SHARED_MEM_TX_LOC_STATE, SHARED_MEM_TX_LOC_SIZE, scratchpad_region_tx);
|
|
||||||
dump_memory(SHARED_MEM_TX_LOC_STATE, SHARED_MEM_TX_LOC_STATE + SHARED_MEM_TX_LOC_SIZE);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
uint16_t crc;
|
|
||||||
crc = crc_check_bulk_memory((uint32_t)SHARED_MEM_TX_LOC_STATE,
|
|
||||||
(uint32_t)(SHARED_MEM_TX_LOC_STATE + SHARED_MEM_TX_LOC_SIZE), 0x8000);
|
|
||||||
debug_P(DEBUG_SHM, PSTR("shared_memory_scratchpad_region_tx_restore: crc=%x\n"),crc);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void shared_memory_scratchpad_region_rx_restore()
|
|
||||||
{
|
|
||||||
if (scratchpad_locked_rx)
|
|
||||||
return;
|
|
||||||
debug_P(DEBUG_SHM, PSTR("shared_memory_scratchpad_region_tx_save: lock\n"));
|
|
||||||
sram_bulk_copy_from_buffer((uint32_t)SHARED_MEM_RX_LOC_STATE,scratchpad_region_rx,
|
|
||||||
(uint32_t)SHARED_MEM_RX_LOC_SIZE);
|
|
||||||
scratchpad_locked_rx = 1;
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
dump_packet(SHARED_MEM_RX_LOC_STATE, SHARED_MEM_TX_LOC_SIZE, scratchpad_region_rx);
|
|
||||||
dump_memory(SHARED_MEM_RX_LOC_STATE, SHARED_MEM_TX_LOC_STATE + SHARED_MEM_RX_LOC_SIZE);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if 1
|
|
||||||
uint16_t crc;
|
|
||||||
crc = crc_check_bulk_memory((uint32_t)SHARED_MEM_RX_LOC_STATE,
|
|
||||||
(uint32_t)(SHARED_MEM_RX_LOC_STATE + SHARED_MEM_RX_LOC_SIZE), 0x8000);
|
|
||||||
debug_P(DEBUG_SHM, PSTR("shared_memory_scratchpad_region_rx_restore: crc=%x\n"),crc);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void shared_memory_scratchpad_tx_save()
|
void shared_memory_scratchpad_tx_save()
|
||||||
{
|
{
|
||||||
scratchpad_state = sram_read(SHARED_MEM_TX_LOC_STATE);
|
scratchpad_state = sram_read(SHARED_MEM_TX_LOC_STATE);
|
||||||
@@ -182,13 +70,9 @@ void shared_memory_irq_restore()
|
|||||||
void shared_memory_write(uint8_t cmd, uint8_t value)
|
void shared_memory_write(uint8_t cmd, uint8_t value)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (scratchpad_locked_tx)
|
debug(DEBUG_SHM,"shared_memory_write: 0x%04x=0x%02x 0x%04x=0x%02x \n",
|
||||||
debug_P(DEBUG_SHM, PSTR("shared_memory_write: locked_tx\n"));
|
|
||||||
|
|
||||||
debug_P(DEBUG_SHM, PSTR("shared_memory_write: 0x%04x=0x%02x 0x%04x=0x%02x \n"),
|
|
||||||
SHARED_MEM_TX_LOC_CMD, cmd, SHARED_MEM_TX_LOC_PAYLOAD, value);
|
SHARED_MEM_TX_LOC_CMD, cmd, SHARED_MEM_TX_LOC_PAYLOAD, value);
|
||||||
|
|
||||||
sram_bulk_addr_save();
|
|
||||||
shared_memory_scratchpad_tx_save();
|
shared_memory_scratchpad_tx_save();
|
||||||
shared_memory_irq_hook();
|
shared_memory_irq_hook();
|
||||||
|
|
||||||
@@ -197,7 +81,6 @@ void shared_memory_write(uint8_t cmd, uint8_t value)
|
|||||||
sram_write(SHARED_MEM_TX_LOC_PAYLOAD, value);
|
sram_write(SHARED_MEM_TX_LOC_PAYLOAD, value);
|
||||||
|
|
||||||
snes_hirom();
|
snes_hirom();
|
||||||
snes_wr_disable();
|
|
||||||
snes_bus_active();
|
snes_bus_active();
|
||||||
|
|
||||||
#if SHARED_MEM_SWITCH_IRQ
|
#if SHARED_MEM_SWITCH_IRQ
|
||||||
@@ -211,14 +94,10 @@ void shared_memory_write(uint8_t cmd, uint8_t value)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
avr_bus_active();
|
avr_bus_active();
|
||||||
snes_irq_lo();
|
|
||||||
snes_irq_off();
|
|
||||||
snes_lorom();
|
snes_lorom();
|
||||||
snes_wr_disable();
|
|
||||||
|
|
||||||
shared_memory_scratchpad_tx_restore();
|
shared_memory_scratchpad_tx_restore();
|
||||||
shared_memory_irq_restore();
|
shared_memory_irq_restore();
|
||||||
//sram_bulk_addr_restore();
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -239,27 +118,20 @@ void shared_memory_yield()
|
|||||||
int shared_memory_read(uint8_t *cmd, uint8_t *len,uint8_t *buffer)
|
int shared_memory_read(uint8_t *cmd, uint8_t *len,uint8_t *buffer)
|
||||||
{
|
{
|
||||||
uint8_t state;
|
uint8_t state;
|
||||||
|
|
||||||
if (scratchpad_locked_rx)
|
|
||||||
debug_P(DEBUG_SHM, PSTR("shared_memory_write: locked_tx\n"));
|
|
||||||
|
|
||||||
|
|
||||||
state = sram_read(SHARED_MEM_RX_LOC_STATE);
|
state = sram_read(SHARED_MEM_RX_LOC_STATE);
|
||||||
if (state != SHARED_MEM_RX_AVR_ACK){
|
if (state != SHARED_MEM_RX_AVR_ACK){
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
sram_bulk_addr_save();
|
|
||||||
|
|
||||||
*cmd = sram_read(SHARED_MEM_RX_LOC_CMD);
|
*cmd = sram_read(SHARED_MEM_RX_LOC_CMD);
|
||||||
*len = sram_read(SHARED_MEM_RX_LOC_LEN);
|
*len = sram_read(SHARED_MEM_RX_LOC_LEN);
|
||||||
debug_P(DEBUG_SHM, PSTR("shared_memory_read: 0x%04x=0x%02x 0x%04x=0x%02x \n"),
|
debug(DEBUG_SHM,"shared_memory_read: 0x%04x=0x%02x 0x%04x=0x%02x \n",
|
||||||
SHARED_MEM_RX_LOC_CMD, *cmd, SHARED_MEM_RX_LOC_LEN, *len);
|
SHARED_MEM_RX_LOC_CMD, *cmd, SHARED_MEM_RX_LOC_LEN, *len);
|
||||||
|
|
||||||
sram_bulk_copy_into_buffer(SHARED_MEM_RX_LOC_PAYLOAD,buffer, *len);
|
sram_bulk_read_buffer(SHARED_MEM_RX_LOC_PAYLOAD,buffer, *len);
|
||||||
sram_write(SHARED_MEM_RX_LOC_STATE, SHARED_MEM_RX_AVR_RTS);
|
sram_write(SHARED_MEM_RX_LOC_STATE, SHARED_MEM_RX_AVR_RTS);
|
||||||
|
|
||||||
snes_hirom();
|
snes_hirom();
|
||||||
snes_wr_disable();
|
|
||||||
snes_bus_active();
|
snes_bus_active();
|
||||||
|
|
||||||
#if SHARED_MEM_SWITCH_IRQ
|
#if SHARED_MEM_SWITCH_IRQ
|
||||||
@@ -274,7 +146,5 @@ int shared_memory_read(uint8_t *cmd, uint8_t *len,uint8_t *buffer)
|
|||||||
|
|
||||||
avr_bus_active();
|
avr_bus_active();
|
||||||
snes_lorom();
|
snes_lorom();
|
||||||
snes_wr_disable();
|
|
||||||
sram_bulk_addr_restore();
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,7 +37,6 @@
|
|||||||
#define SHARED_MEM_TX_CMD_TERMINATE 0x06
|
#define SHARED_MEM_TX_CMD_TERMINATE 0x06
|
||||||
|
|
||||||
#define SHARED_MEM_TX_LOC_STATE 0x000000
|
#define SHARED_MEM_TX_LOC_STATE 0x000000
|
||||||
#define SHARED_MEM_TX_LOC_SIZE 0x000040
|
|
||||||
#define SHARED_MEM_TX_LOC_CMD 0x000001
|
#define SHARED_MEM_TX_LOC_CMD 0x000001
|
||||||
#define SHARED_MEM_TX_LOC_PAYLOAD 0x000002
|
#define SHARED_MEM_TX_LOC_PAYLOAD 0x000002
|
||||||
|
|
||||||
@@ -48,7 +47,6 @@
|
|||||||
#define SHARED_MEM_RX_CMD_FILESEL 0x01
|
#define SHARED_MEM_RX_CMD_FILESEL 0x01
|
||||||
|
|
||||||
#define SHARED_MEM_RX_LOC_STATE 0x001000
|
#define SHARED_MEM_RX_LOC_STATE 0x001000
|
||||||
#define SHARED_MEM_RX_LOC_SIZE 0x000040
|
|
||||||
#define SHARED_MEM_RX_LOC_CMD 0x001001
|
#define SHARED_MEM_RX_LOC_CMD 0x001001
|
||||||
#define SHARED_MEM_RX_LOC_LEN 0x001002
|
#define SHARED_MEM_RX_LOC_LEN 0x001002
|
||||||
#define SHARED_MEM_RX_LOC_PAYLOAD 0x001003
|
#define SHARED_MEM_RX_LOC_PAYLOAD 0x001003
|
||||||
@@ -56,17 +54,9 @@
|
|||||||
#define SHARED_IRQ_LOC_LO 0x00fffe
|
#define SHARED_IRQ_LOC_LO 0x00fffe
|
||||||
#define SHARED_IRQ_LOC_HI 0x00ffff
|
#define SHARED_IRQ_LOC_HI 0x00ffff
|
||||||
|
|
||||||
/* Use COP IRQ LOC for hooked IRQ handler */
|
#define SHARED_IRQ_HANDLER_LO 0x00
|
||||||
#define SHARED_IRQ_HANDLER_LO 0x0ffe4
|
#define SHARED_IRQ_HANDLER_HI 0x10
|
||||||
#define SHARED_IRQ_HANDLER_HI 0x0ffe5
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
uint8_t shared_memory_scratchpad_region_save_helper(uint32_t addr);
|
|
||||||
void shared_memory_scratchpad_region_tx_save();
|
|
||||||
void shared_memory_scratchpad_region_tx_restore();
|
|
||||||
void shared_memory_scratchpad_region_rx_save();
|
|
||||||
void shared_memory_scratchpad_region_rx_restore();
|
|
||||||
void shared_memory_write(uint8_t cmd, uint8_t value);
|
void shared_memory_write(uint8_t cmd, uint8_t value);
|
||||||
int shared_memory_read(uint8_t *cmd, uint8_t *len,uint8_t *buffer);
|
int shared_memory_read(uint8_t *cmd, uint8_t *len,uint8_t *buffer);
|
||||||
|
|
||||||
|
|||||||
@@ -31,9 +31,6 @@
|
|||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "info.h"
|
#include "info.h"
|
||||||
|
|
||||||
uint32_t addr_current = 0;
|
|
||||||
uint32_t addr_stash = 0;
|
|
||||||
|
|
||||||
void system_init(void)
|
void system_init(void)
|
||||||
{
|
{
|
||||||
/*-------------------------------------------------*/
|
/*-------------------------------------------------*/
|
||||||
@@ -47,17 +44,18 @@ void system_init(void)
|
|||||||
| (1 << AVR_ADDR_SCK_PIN)
|
| (1 << AVR_ADDR_SCK_PIN)
|
||||||
| (1 << AVR_ADDR_SER_PIN)
|
| (1 << AVR_ADDR_SER_PIN)
|
||||||
| (1 << AVR_ADDR_LOAD_PIN)
|
| (1 << AVR_ADDR_LOAD_PIN)
|
||||||
| (1 << AVR_ADDR_UP_PIN));
|
| (1 << AVR_ADDR_DOWN_PIN)
|
||||||
|
| (1 << AVR_ADDR_UP_PIN));
|
||||||
|
|
||||||
DDRC &= ~ ((1 << SNES_WR_PIN)
|
DDRC &= ~ (1 << SNES_WR_PIN);
|
||||||
| (1 << AVR_BTLDR_EN_PIN));
|
|
||||||
|
|
||||||
PORTC &= ~((1 << AVR_ADDR_LATCH_PIN)
|
PORTC &= ~((1 << AVR_ADDR_LATCH_PIN)
|
||||||
| (1 << AVR_ADDR_SCK_PIN)
|
| (1 << AVR_ADDR_SCK_PIN)
|
||||||
| (1 << SNES_WR_PIN));
|
| (1 << SNES_WR_PIN));
|
||||||
|
|
||||||
|
|
||||||
PORTC |= ( (1 << AVR_ADDR_UP_PIN)
|
PORTC |= ( (1 << AVR_ADDR_DOWN_PIN)
|
||||||
|
| (1 << AVR_ADDR_UP_PIN)
|
||||||
| (1 << AVR_ADDR_LOAD_PIN));
|
| (1 << AVR_ADDR_LOAD_PIN));
|
||||||
|
|
||||||
//| (1 << SNES_WR_PIN));
|
//| (1 << SNES_WR_PIN));
|
||||||
@@ -91,22 +89,23 @@ void system_init(void)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void sreg_set(uint32_t addr)
|
void sreg_set(uint32_t addr)
|
||||||
{
|
{
|
||||||
uint8_t i = 24;
|
uint8_t i = 24;
|
||||||
debug_P(DEBUG_SREG, PSTR("sreg_set: addr=0x%08lx"),addr);
|
debug(DEBUG_SREG,"sreg_set: addr=0x%08lx",addr);
|
||||||
while(i--) {
|
while(i--) {
|
||||||
if ((addr & ( 1L << i))){
|
if ((addr & ( 1L << i))){
|
||||||
debug_P(DEBUG_SREG, PSTR("1"));
|
debug(DEBUG_SREG,"1");
|
||||||
AVR_ADDR_SER_PORT |= ( 1 << AVR_ADDR_SER_PIN);
|
AVR_ADDR_SER_PORT |= ( 1 << AVR_ADDR_SER_PIN);
|
||||||
} else {
|
} else {
|
||||||
AVR_ADDR_SER_PORT &= ~( 1 << AVR_ADDR_SER_PIN);
|
AVR_ADDR_SER_PORT &= ~( 1 << AVR_ADDR_SER_PIN);
|
||||||
debug_P(DEBUG_SREG, PSTR("0"));
|
debug(DEBUG_SREG,"0");
|
||||||
}
|
}
|
||||||
AVR_ADDR_SCK_PORT |= (1 << AVR_ADDR_SCK_PIN);
|
AVR_ADDR_SCK_PORT |= (1 << AVR_ADDR_SCK_PIN);
|
||||||
AVR_ADDR_SCK_PORT &= ~(1 << AVR_ADDR_SCK_PIN);
|
AVR_ADDR_SCK_PORT &= ~(1 << AVR_ADDR_SCK_PIN);
|
||||||
}
|
}
|
||||||
debug_P(DEBUG_SREG, PSTR("\n"));
|
debug(DEBUG_SREG,"\n");
|
||||||
AVR_ADDR_LATCH_PORT |= (1 << AVR_ADDR_LATCH_PIN);
|
AVR_ADDR_LATCH_PORT |= (1 << AVR_ADDR_LATCH_PIN);
|
||||||
AVR_ADDR_LATCH_PORT &= ~(1 << AVR_ADDR_LATCH_PIN);
|
AVR_ADDR_LATCH_PORT &= ~(1 << AVR_ADDR_LATCH_PIN);
|
||||||
|
|
||||||
@@ -114,23 +113,11 @@ void sreg_set(uint32_t addr)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void sram_bulk_addr_save()
|
|
||||||
{
|
|
||||||
addr_stash = addr_current;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void sram_bulk_addr_restore()
|
|
||||||
{
|
|
||||||
sreg_set(addr_stash);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void sram_bulk_read_start(uint32_t addr)
|
void sram_bulk_read_start(uint32_t addr)
|
||||||
{
|
{
|
||||||
debug_P(DEBUG_SRAM, PSTR("sram_bulk_read_start: addr=0x%08lx\n\r"), addr);
|
debug(DEBUG_SRAM,"sram_bulk_read_start: addr=0x%08lx\n\r", addr);
|
||||||
|
|
||||||
addr_current = addr;
|
|
||||||
|
|
||||||
avr_data_in();
|
avr_data_in();
|
||||||
|
|
||||||
AVR_CS_PORT &= ~(1 << AVR_CS_PIN);
|
AVR_CS_PORT &= ~(1 << AVR_CS_PIN);
|
||||||
@@ -151,7 +138,6 @@ void sram_bulk_read_start(uint32_t addr)
|
|||||||
|
|
||||||
inline void sram_bulk_read_next(void)
|
inline void sram_bulk_read_next(void)
|
||||||
{
|
{
|
||||||
addr_current++;
|
|
||||||
AVR_RD_PORT |= (1 << AVR_RD_PIN);
|
AVR_RD_PORT |= (1 << AVR_RD_PIN);
|
||||||
counter_up();
|
counter_up();
|
||||||
AVR_RD_PORT &= ~(1 << AVR_RD_PIN);
|
AVR_RD_PORT &= ~(1 << AVR_RD_PIN);
|
||||||
@@ -173,7 +159,7 @@ inline uint8_t sram_bulk_read(void)
|
|||||||
|
|
||||||
void sram_bulk_read_end(void)
|
void sram_bulk_read_end(void)
|
||||||
{
|
{
|
||||||
debug_P(DEBUG_SRAM, PSTR("sram_bulk_read_end:\n"));
|
debug(DEBUG_SRAM,"sram_bulk_read_end:\n");
|
||||||
|
|
||||||
AVR_RD_PORT |= (1 << AVR_RD_PIN);
|
AVR_RD_PORT |= (1 << AVR_RD_PIN);
|
||||||
AVR_CS_PORT |= (1 << AVR_CS_PIN);
|
AVR_CS_PORT |= (1 << AVR_CS_PIN);
|
||||||
@@ -183,7 +169,7 @@ void sram_bulk_read_end(void)
|
|||||||
uint8_t sram_read(uint32_t addr)
|
uint8_t sram_read(uint32_t addr)
|
||||||
{
|
{
|
||||||
uint8_t byte;
|
uint8_t byte;
|
||||||
debug_P(DEBUG_SRAM_RAW, PSTR("sram_read: addr=0x%08lx\n\r"), addr);
|
debug(DEBUG_SRAM_RAW,"sram_read: addr=0x%08lx\n\r", addr);
|
||||||
|
|
||||||
avr_data_in();
|
avr_data_in();
|
||||||
|
|
||||||
@@ -215,7 +201,7 @@ uint8_t sram_read(uint32_t addr)
|
|||||||
|
|
||||||
void sram_bulk_write_start(uint32_t addr)
|
void sram_bulk_write_start(uint32_t addr)
|
||||||
{
|
{
|
||||||
debug_P(DEBUG_SRAM, PSTR("sram_bulk_write_start: addr=0x%08lx\n\r"), addr);
|
debug(DEBUG_SRAM,"sram_bulk_write_start: addr=0x%08lx\n\r", addr);
|
||||||
|
|
||||||
avr_data_out();
|
avr_data_out();
|
||||||
|
|
||||||
@@ -243,7 +229,7 @@ inline void sram_bulk_write( uint8_t data)
|
|||||||
|
|
||||||
void sram_bulk_write_end(void)
|
void sram_bulk_write_end(void)
|
||||||
{
|
{
|
||||||
debug_P(DEBUG_SRAM, PSTR("sram_bulk_write_end:"));
|
debug(DEBUG_SRAM,"sram_bulk_write_end:");
|
||||||
AVR_WR_PORT |= (1 << AVR_WR_PIN);
|
AVR_WR_PORT |= (1 << AVR_WR_PIN);
|
||||||
AVR_CS_PORT |= (1 << AVR_CS_PIN);
|
AVR_CS_PORT |= (1 << AVR_CS_PIN);
|
||||||
avr_data_in();
|
avr_data_in();
|
||||||
@@ -252,7 +238,7 @@ void sram_bulk_write_end(void)
|
|||||||
|
|
||||||
void sram_write(uint32_t addr, uint8_t data)
|
void sram_write(uint32_t addr, uint8_t data)
|
||||||
{
|
{
|
||||||
debug_P(DEBUG_SRAM_RAW, PSTR("sram_write: addr=0x%08lx data=%x\n\r"), addr, data);
|
debug(DEBUG_SRAM_RAW,"sram_write: addr=0x%08lx data=%x\n\r", addr, data);
|
||||||
|
|
||||||
avr_data_out();
|
avr_data_out();
|
||||||
|
|
||||||
@@ -281,13 +267,12 @@ void sram_write(uint32_t addr, uint8_t data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void sram_bulk_copy_from_buffer(uint32_t addr, uint8_t * src, uint32_t len)
|
void sram_bulk_copy(uint32_t addr, uint8_t * src, uint32_t len)
|
||||||
{
|
{
|
||||||
|
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
uint8_t *ptr = src;
|
uint8_t *ptr = src;
|
||||||
debug_P(DEBUG_SRAM, PSTR("sram_bulk_copy_from_buffer: addr=0x%08lx src=0x%p len=%li\n\r"),
|
debug(DEBUG_SRAM,"sram_copy: addr=0x%08lx src=0x%p len=%li\n\r", addr,src,len);
|
||||||
addr, src, len);
|
|
||||||
sram_bulk_write_start(addr);
|
sram_bulk_write_start(addr);
|
||||||
for (i = addr; i < (addr + len); i++){
|
for (i = addr; i < (addr + len); i++){
|
||||||
sram_bulk_write(*ptr++);
|
sram_bulk_write(*ptr++);
|
||||||
@@ -296,13 +281,12 @@ void sram_bulk_copy_from_buffer(uint32_t addr, uint8_t * src, uint32_t len)
|
|||||||
sram_bulk_write_end();
|
sram_bulk_write_end();
|
||||||
}
|
}
|
||||||
|
|
||||||
void sram_bulk_copy_into_buffer(uint32_t addr, uint8_t * dst, uint32_t len)
|
void sram_bulk_read_buffer(uint32_t addr, uint8_t * dst, uint32_t len)
|
||||||
{
|
{
|
||||||
|
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
uint8_t *ptr = dst;
|
uint8_t *ptr = dst;
|
||||||
debug_P(DEBUG_SRAM, PSTR("sram_bulk_copy_into_buffer: addr=0x%08lx dst=0x%p len=%li\n\r"),
|
debug(DEBUG_SRAM,"sram_bulk_read_buffer: addr=0x%08lx dst=0x%p len=%li\n\r", addr,dst,len);
|
||||||
addr, dst, len);
|
|
||||||
sram_bulk_read_start(addr);
|
sram_bulk_read_start(addr);
|
||||||
for (i = addr; i < (addr + len); i++) {
|
for (i = addr; i < (addr + len); i++) {
|
||||||
*ptr = sram_bulk_read();
|
*ptr = sram_bulk_read();
|
||||||
@@ -314,11 +298,11 @@ void sram_bulk_copy_into_buffer(uint32_t addr, uint8_t * dst, uint32_t len)
|
|||||||
|
|
||||||
void sram_bulk_set(uint32_t addr, uint32_t len,uint8_t value){
|
void sram_bulk_set(uint32_t addr, uint32_t len,uint8_t value){
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
debug_P(DEBUG_SRAM, PSTR("sram_bulk_set: addr=0x%08lx len=%li\n\r"), addr,len);
|
debug(DEBUG_SRAM,"sram_bulk_set: addr=0x%08lx len=%li\n\r", addr,len);
|
||||||
sram_bulk_write_start(addr);
|
sram_bulk_write_start(addr);
|
||||||
for (i = addr; i < (addr + len); i++) {
|
for (i = addr; i < (addr + len); i++) {
|
||||||
if (0 == i % 0xfff)
|
if (0 == i % 0xfff)
|
||||||
debug_P(DEBUG_SRAM, PSTR("sram_bulk_set: addr=0x%08lx\n\r"), i);
|
debug(DEBUG_SRAM,"sram_bulk_set: addr=0x%08lx\n\r", i);
|
||||||
sram_bulk_write(value);
|
sram_bulk_write(value);
|
||||||
sram_bulk_write_next();
|
sram_bulk_write_next();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,6 +40,14 @@
|
|||||||
|
|
||||||
#define avr_data_out() (AVR_DATA_DIR = 0xff)
|
#define avr_data_out() (AVR_DATA_DIR = 0xff)
|
||||||
|
|
||||||
|
#define LED_PORT PORTC
|
||||||
|
#define LED_DIR DDRC
|
||||||
|
#define LED_PIN PC7
|
||||||
|
|
||||||
|
#define led_on() ((LED_PORT &=~ (1 << LED_PIN)),\
|
||||||
|
(LED_DIR &=~ (1 << LED_PIN)))
|
||||||
|
#define led_off() ((LED_PORT &=~ (1 << LED_PIN)),\
|
||||||
|
(LED_DIR |= (1 << LED_PIN)))
|
||||||
|
|
||||||
/* ---------------------------- PORT B ---------------------------- */
|
/* ---------------------------- PORT B ---------------------------- */
|
||||||
|
|
||||||
@@ -77,6 +85,17 @@
|
|||||||
#define snes_irq_off() (SNES_IRQ_DIR &= ~(1 << SNES_IRQ_PIN))
|
#define snes_irq_off() (SNES_IRQ_DIR &= ~(1 << SNES_IRQ_PIN))
|
||||||
#define snes_irq_lo() (SNES_IRQ_PORT &= ~(1 << SNES_IRQ_PIN))
|
#define snes_irq_lo() (SNES_IRQ_PORT &= ~(1 << SNES_IRQ_PIN))
|
||||||
|
|
||||||
|
#define SNES_RESET_PORT PORTB
|
||||||
|
#define SNES_RESET_DIR DDRB
|
||||||
|
#define SNES_RESET_PIN PB4
|
||||||
|
|
||||||
|
|
||||||
|
#define snes_reset_on() (SNES_RESET_DIR |= (1 << SNES_RESET_PIN))
|
||||||
|
#define snes_reset_hi() (SNES_RESET_PORT |= (1 << SNES_RESET_PIN))
|
||||||
|
|
||||||
|
#define snes_reset_off() (SNES_RESET_DIR &= ~(1 << SNES_RESET_PIN))
|
||||||
|
#define snes_reset_lo() (SNES_RESET_PORT &= ~(1 << SNES_RESET_PIN))
|
||||||
|
|
||||||
|
|
||||||
/* ---------------------------- PORT C ---------------------------- */
|
/* ---------------------------- PORT C ---------------------------- */
|
||||||
|
|
||||||
@@ -110,12 +129,12 @@
|
|||||||
#define counter_load() ((AVR_ADDR_LOAD_PORT &= ~(1 << AVR_ADDR_LOAD_PIN)),\
|
#define counter_load() ((AVR_ADDR_LOAD_PORT &= ~(1 << AVR_ADDR_LOAD_PIN)),\
|
||||||
(AVR_ADDR_LOAD_PORT |= (1 << AVR_ADDR_LOAD_PIN)))
|
(AVR_ADDR_LOAD_PORT |= (1 << AVR_ADDR_LOAD_PIN)))
|
||||||
|
|
||||||
#define AVR_BTLDR_EN_PORT PORTC
|
#define AVR_ADDR_DOWN_PORT PORTC
|
||||||
#define AVR_BTLDR_EN_DIR DDRC
|
#define AVR_ADDR_DOWN_DIR DDRC
|
||||||
#define AVR_BTLDR_EN_PIN PC1
|
#define AVR_ADDR_DOWN_PIN PC1
|
||||||
|
|
||||||
#define btldr_down() ((AVR_BTLDR_EN_PORT &= ~(1 << AVR_BTLDR_EN_PIN)),\
|
#define counter_down() ((AVR_ADDR_DOWN_PORT &= ~(1 << AVR_ADDR_DOWN_PIN)),\
|
||||||
(AVR_BTLDR_EN_PORT |= (1 << AVR_BTLDR_EN_PIN)))
|
(AVR_ADDR_DOWN_PORT |= (1 << AVR_ADDR_DOWN_PIN)))
|
||||||
|
|
||||||
#define AVR_ADDR_UP_PORT PORTC
|
#define AVR_ADDR_UP_PORT PORTC
|
||||||
#define AVR_ADDR_UP_DIR DDRC
|
#define AVR_ADDR_UP_DIR DDRC
|
||||||
@@ -128,16 +147,6 @@
|
|||||||
#define SNES_WR_DIR DDRC
|
#define SNES_WR_DIR DDRC
|
||||||
#define SNES_WR_PIN PC3
|
#define SNES_WR_PIN PC3
|
||||||
|
|
||||||
#define LED_PORT PORTC
|
|
||||||
#define LED_DIR DDRC
|
|
||||||
#define LED_PIN PC7
|
|
||||||
|
|
||||||
#define led_on() ((LED_PORT &=~ (1 << LED_PIN)),\
|
|
||||||
(LED_DIR &=~ (1 << LED_PIN)))
|
|
||||||
#define led_off() ((LED_PORT &=~ (1 << LED_PIN)),\
|
|
||||||
(LED_DIR |= (1 << LED_PIN)))
|
|
||||||
|
|
||||||
|
|
||||||
/* ---------------------------- PORT D ---------------------------- */
|
/* ---------------------------- PORT D ---------------------------- */
|
||||||
|
|
||||||
#define AVR_SNES_PORT PORTD
|
#define AVR_SNES_PORT PORTD
|
||||||
@@ -168,27 +177,6 @@
|
|||||||
|
|
||||||
#define snes_wr_enable() (SNES_WR_EN_PORT |= (1 << SNES_WR_EN_PIN))
|
#define snes_wr_enable() (SNES_WR_EN_PORT |= (1 << SNES_WR_EN_PIN))
|
||||||
|
|
||||||
#define SNES_RESET_PORT PORTD
|
|
||||||
#define SNES_RESET_DIR DDRD
|
|
||||||
#define SNES_RESET_PIN PD3
|
|
||||||
#define SNES_RESET_INP PIND
|
|
||||||
|
|
||||||
#define snes_reset_on() (SNES_RESET_DIR |= (1 << SNES_RESET_PIN))
|
|
||||||
#define snes_reset_hi() (SNES_RESET_PORT |= (1 << SNES_RESET_PIN))
|
|
||||||
|
|
||||||
#define snes_reset_off() (SNES_RESET_DIR &= ~(1 << SNES_RESET_PIN))
|
|
||||||
#define snes_reset_lo() (SNES_RESET_PORT &= ~(1 << SNES_RESET_PIN))
|
|
||||||
|
|
||||||
#define snes_reset_test() ((SNES_RESET_INP & (1 << SNES_RESET_PIN)) == 0)
|
|
||||||
|
|
||||||
#define MMC_PORT PORTB
|
|
||||||
#define MMC_DIR DDRB
|
|
||||||
|
|
||||||
#define MMC_MISO_PIN PB6
|
|
||||||
#define MMC_MOSI_PIN PB5
|
|
||||||
#define MMC_SCK_PIN PB7
|
|
||||||
#define MMC_CS_PIN PB4
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -209,14 +197,8 @@ inline void sram_bulk_write_next(void);
|
|||||||
inline void sram_bulk_write_end(void);
|
inline void sram_bulk_write_end(void);
|
||||||
void sram_bulk_write(uint8_t data);
|
void sram_bulk_write(uint8_t data);
|
||||||
|
|
||||||
void sram_bulk_copy_from_buffer(uint32_t addr, uint8_t * src, uint32_t len);
|
void sram_bulk_copy(uint32_t addr, uint8_t * src, uint32_t len);
|
||||||
void sram_bulk_copy_into_buffer(uint32_t addr, uint8_t * dst, uint32_t len);
|
void sram_bulk_read_buffer(uint32_t addr, uint8_t * dst, uint32_t len);
|
||||||
|
|
||||||
void sram_bulk_set(uint32_t addr, uint32_t len,uint8_t value);
|
void sram_bulk_set(uint32_t addr, uint32_t len,uint8_t value);
|
||||||
|
|
||||||
inline void sram_bulk_addr_save();
|
|
||||||
inline void sram_bulk_addr_restore();
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
428
avr/usbload/tags
428
avr/usbload/tags
@@ -1,428 +0,0 @@
|
|||||||
!_TAG_FILE_FORMAT 2 /extended format; --format=1 will not append ;" to lines/
|
|
||||||
!_TAG_FILE_SORTED 1 /0=unsorted, 1=sorted, 2=foldcase/
|
|
||||||
!_TAG_PROGRAM_AUTHOR Darren Hiebert /dhiebert@users.sourceforge.net/
|
|
||||||
!_TAG_PROGRAM_NAME Exuberant Ctags //
|
|
||||||
!_TAG_PROGRAM_URL http://ctags.sourceforge.net /official site/
|
|
||||||
!_TAG_PROGRAM_VERSION 5.7 //
|
|
||||||
AVR_ADDR_DIR sram.h 103;" d
|
|
||||||
AVR_ADDR_DOWN_DIR sram.h 133;" d
|
|
||||||
AVR_ADDR_DOWN_PIN sram.h 134;" d
|
|
||||||
AVR_ADDR_DOWN_PORT sram.h 132;" d
|
|
||||||
AVR_ADDR_LATCH_DIR sram.h 105;" d
|
|
||||||
AVR_ADDR_LATCH_PIN sram.h 106;" d
|
|
||||||
AVR_ADDR_LATCH_PORT sram.h 104;" d
|
|
||||||
AVR_ADDR_LOAD_DIR sram.h 126;" d
|
|
||||||
AVR_ADDR_LOAD_PIN sram.h 127;" d
|
|
||||||
AVR_ADDR_LOAD_PORT sram.h 125;" d
|
|
||||||
AVR_ADDR_PORT sram.h 102;" d
|
|
||||||
AVR_ADDR_SCK_DIR sram.h 112;" d
|
|
||||||
AVR_ADDR_SCK_PIN sram.h 113;" d
|
|
||||||
AVR_ADDR_SCK_PORT sram.h 111;" d
|
|
||||||
AVR_ADDR_SER_DIR sram.h 119;" d
|
|
||||||
AVR_ADDR_SER_PIN sram.h 120;" d
|
|
||||||
AVR_ADDR_SER_PORT sram.h 118;" d
|
|
||||||
AVR_ADDR_UP_DIR sram.h 140;" d
|
|
||||||
AVR_ADDR_UP_PIN sram.h 141;" d
|
|
||||||
AVR_ADDR_UP_PORT sram.h 139;" d
|
|
||||||
AVR_CS_DIR sram.h 71;" d
|
|
||||||
AVR_CS_PIN sram.h 72;" d
|
|
||||||
AVR_CS_PORT sram.h 70;" d
|
|
||||||
AVR_DATA_DIR sram.h 35;" d
|
|
||||||
AVR_DATA_PIN sram.h 36;" d
|
|
||||||
AVR_DATA_PORT sram.h 34;" d
|
|
||||||
AVR_DIR sram.h 55;" d
|
|
||||||
AVR_PORT sram.h 54;" d
|
|
||||||
AVR_RD_DIR sram.h 57;" d
|
|
||||||
AVR_RD_PIN sram.h 58;" d
|
|
||||||
AVR_RD_PORT sram.h 56;" d
|
|
||||||
AVR_SNES_DIR sram.h 153;" d
|
|
||||||
AVR_SNES_PORT sram.h 152;" d
|
|
||||||
AVR_SNES_SW_DIR sram.h 155;" d
|
|
||||||
AVR_SNES_SW_PIN sram.h 156;" d
|
|
||||||
AVR_SNES_SW_PORT sram.h 154;" d
|
|
||||||
AVR_WR_DIR sram.h 64;" d
|
|
||||||
AVR_WR_PIN sram.h 65;" d
|
|
||||||
AVR_WR_PORT sram.h 63;" d
|
|
||||||
CR uart.h 25;" d
|
|
||||||
DEBOUNCE timer.c 44;" d file:
|
|
||||||
DEBUG config.h 25;" d
|
|
||||||
DEBUG_CRC config.h 31;" d
|
|
||||||
DEBUG_SHM config.h 32;" d
|
|
||||||
DEBUG_SRAM config.h 28;" d
|
|
||||||
DEBUG_SRAM_RAW config.h 29;" d
|
|
||||||
DEBUG_SREG config.h 30;" d
|
|
||||||
DEBUG_USB config.h 26;" d
|
|
||||||
DEBUG_USB_TRANS config.h 27;" d
|
|
||||||
FILE_MKDIR config.h 48;" d
|
|
||||||
FILE_RM config.h 49;" d
|
|
||||||
FILE_WRITE config.h 47;" d
|
|
||||||
Fat fat.h /^ extern struct Fat{ \/\/ fat daten (1.cluster, root-dir, dir usw.)$/;" s
|
|
||||||
File fat.h /^ extern struct File{ \/\/ datei infos$/;" s
|
|
||||||
HI_LOROM_SW_DIR sram.h 166;" d
|
|
||||||
HI_LOROM_SW_PIN sram.h 167;" d
|
|
||||||
HI_LOROM_SW_PORT sram.h 165;" d
|
|
||||||
INBYTE rle.c 44;" d file:
|
|
||||||
ISR timer.c /^ISR (SIG_OUTPUT_COMPARE1A)$/;" f
|
|
||||||
ISR uart.c /^ISR(USART0_RX_vect)$/;" f
|
|
||||||
LED_DIR sram.h 44;" d
|
|
||||||
LED_PIN sram.h 45;" d
|
|
||||||
LED_PORT sram.h 43;" d
|
|
||||||
MAX_CLUSTERS_IN_ROW fat.h 11;" d
|
|
||||||
MMC_CLK mmc.h 21;" d
|
|
||||||
MMC_CS mmc.h 18;" d
|
|
||||||
MMC_DI mmc.h 20;" d
|
|
||||||
MMC_DO mmc.h 19;" d
|
|
||||||
MMC_READ mmc.h 15;" d
|
|
||||||
MMC_READ mmc.h 24;" d
|
|
||||||
MMC_REG mmc.h 16;" d
|
|
||||||
MMC_REG mmc.h 25;" d
|
|
||||||
MMC_WRITE mmc.h 14;" d
|
|
||||||
MMC_WRITE mmc.h 23;" d
|
|
||||||
OCR1A timer.c 34;" d file:
|
|
||||||
OUTBYTE rle.c 54;" d file:
|
|
||||||
OVER_WRITE fat.h 10;" d
|
|
||||||
PROGMEM loader.c /^const char _rom[ROM_BUFFER_SIZE] PROGMEM = {$/;" v
|
|
||||||
REQ_STATUS_AVR config.h 40;" d
|
|
||||||
REQ_STATUS_BULK_NEXT config.h 37;" d
|
|
||||||
REQ_STATUS_BULK_UPLOAD config.h 36;" d
|
|
||||||
REQ_STATUS_CRC config.h 38;" d
|
|
||||||
REQ_STATUS_IDLE config.h 34;" d
|
|
||||||
REQ_STATUS_SNES config.h 39;" d
|
|
||||||
REQ_STATUS_UPLOAD config.h 35;" d
|
|
||||||
ROM_BUFFER_SIZE loader.h 5;" d
|
|
||||||
ROM_HUFFMAN_SIZE loader.h 6;" d
|
|
||||||
ROM_RLE_SIZE loader.h 7;" d
|
|
||||||
RUNCHAR rle.c 33;" d file:
|
|
||||||
SHARED_IRQ_HANDLER_HI shared_memory.h 59;" d
|
|
||||||
SHARED_IRQ_HANDLER_LO shared_memory.h 58;" d
|
|
||||||
SHARED_IRQ_LOC_HI shared_memory.h 55;" d
|
|
||||||
SHARED_IRQ_LOC_LO shared_memory.h 54;" d
|
|
||||||
SHARED_MEM_RX_AVR_ACK shared_memory.h 43;" d
|
|
||||||
SHARED_MEM_RX_AVR_RTS shared_memory.h 44;" d
|
|
||||||
SHARED_MEM_RX_CMD_FILESEL shared_memory.h 47;" d
|
|
||||||
SHARED_MEM_RX_CMD_PRINFT shared_memory.h 46;" d
|
|
||||||
SHARED_MEM_RX_LOC_CMD shared_memory.h 50;" d
|
|
||||||
SHARED_MEM_RX_LOC_LEN shared_memory.h 51;" d
|
|
||||||
SHARED_MEM_RX_LOC_PAYLOAD shared_memory.h 52;" d
|
|
||||||
SHARED_MEM_RX_LOC_STATE shared_memory.h 49;" d
|
|
||||||
SHARED_MEM_SWITCH_DELAY shared_memory.h 26;" d
|
|
||||||
SHARED_MEM_SWITCH_IRQ shared_memory.h 25;" d
|
|
||||||
SHARED_MEM_TX_CMD_BANK_COUNT shared_memory.h 31;" d
|
|
||||||
SHARED_MEM_TX_CMD_BANK_CURRENT shared_memory.h 32;" d
|
|
||||||
SHARED_MEM_TX_CMD_TERMINATE shared_memory.h 37;" d
|
|
||||||
SHARED_MEM_TX_CMD_UPLOAD_END shared_memory.h 35;" d
|
|
||||||
SHARED_MEM_TX_CMD_UPLOAD_PROGESS shared_memory.h 36;" d
|
|
||||||
SHARED_MEM_TX_CMD_UPLOAD_START shared_memory.h 34;" d
|
|
||||||
SHARED_MEM_TX_LOC_CMD shared_memory.h 40;" d
|
|
||||||
SHARED_MEM_TX_LOC_PAYLOAD shared_memory.h 41;" d
|
|
||||||
SHARED_MEM_TX_LOC_STATE shared_memory.h 39;" d
|
|
||||||
SHARED_MEM_TX_SNES_ACK shared_memory.h 28;" d
|
|
||||||
SHARED_MEM_TX_SNES_RTS shared_memory.h 29;" d
|
|
||||||
SMALL_FILE_SYSTEM config.h 50;" d
|
|
||||||
SMALL_FILE_SYSTEM fat.h 8;" d
|
|
||||||
SNES_IRQ_DIR sram.h 78;" d
|
|
||||||
SNES_IRQ_PIN sram.h 79;" d
|
|
||||||
SNES_IRQ_PORT sram.h 77;" d
|
|
||||||
SNES_RESET_DIR sram.h 89;" d
|
|
||||||
SNES_RESET_PIN sram.h 90;" d
|
|
||||||
SNES_RESET_PORT sram.h 88;" d
|
|
||||||
SNES_WR_DIR sram.h 147;" d
|
|
||||||
SNES_WR_EN_DIR sram.h 173;" d
|
|
||||||
SNES_WR_EN_PIN sram.h 174;" d
|
|
||||||
SNES_WR_EN_PORT sram.h 172;" d
|
|
||||||
SNES_WR_PIN sram.h 148;" d
|
|
||||||
SNES_WR_PORT sram.h 146;" d
|
|
||||||
SPI_Mode mmc.h 12;" d
|
|
||||||
TRANSFER_BUFFER_SIZE config.h 45;" d
|
|
||||||
USB_AVR_RESET requests.h 40;" d
|
|
||||||
USB_BULK_UPLOAD_ADDR requests.h 35;" d
|
|
||||||
USB_BULK_UPLOAD_END requests.h 37;" d
|
|
||||||
USB_BULK_UPLOAD_INIT requests.h 34;" d
|
|
||||||
USB_BULK_UPLOAD_NEXT requests.h 36;" d
|
|
||||||
USB_CFG_CHECK_CRC usbconfig.h 72;" d
|
|
||||||
USB_CFG_CHECK_DATA_TOGGLING usbconfig.h 211;" d
|
|
||||||
USB_CFG_CLOCK_KHZ usbconfig.h 65;" d
|
|
||||||
USB_CFG_DESCR_PROPS_CONFIGURATION usbconfig.h 346;" d
|
|
||||||
USB_CFG_DESCR_PROPS_DEVICE usbconfig.h 345;" d
|
|
||||||
USB_CFG_DESCR_PROPS_HID usbconfig.h 352;" d
|
|
||||||
USB_CFG_DESCR_PROPS_HID_REPORT usbconfig.h 353;" d
|
|
||||||
USB_CFG_DESCR_PROPS_STRINGS usbconfig.h 347;" d
|
|
||||||
USB_CFG_DESCR_PROPS_STRING_0 usbconfig.h 348;" d
|
|
||||||
USB_CFG_DESCR_PROPS_STRING_PRODUCT usbconfig.h 350;" d
|
|
||||||
USB_CFG_DESCR_PROPS_STRING_SERIAL_NUMBER usbconfig.h 351;" d
|
|
||||||
USB_CFG_DESCR_PROPS_STRING_VENDOR usbconfig.h 349;" d
|
|
||||||
USB_CFG_DESCR_PROPS_UNKNOWN usbconfig.h 354;" d
|
|
||||||
USB_CFG_DEVICE_CLASS usbconfig.h 266;" d
|
|
||||||
USB_CFG_DEVICE_ID usbconfig.h 231;" d
|
|
||||||
USB_CFG_DEVICE_NAME usbconfig.h 251;" d
|
|
||||||
USB_CFG_DEVICE_NAME_LEN usbconfig.h 252;" d
|
|
||||||
USB_CFG_DEVICE_SUBCLASS usbconfig.h 267;" d
|
|
||||||
USB_CFG_DEVICE_VERSION usbconfig.h 238;" d
|
|
||||||
USB_CFG_DMINUS_BIT usbconfig.h 52;" d
|
|
||||||
USB_CFG_DPLUS_BIT usbconfig.h 56;" d
|
|
||||||
USB_CFG_EP3_NUMBER usbconfig.h 106;" d
|
|
||||||
USB_CFG_HAVE_FLOWCONTROL usbconfig.h 161;" d
|
|
||||||
USB_CFG_HAVE_INTRIN_ENDPOINT usbconfig.h 95;" d
|
|
||||||
USB_CFG_HAVE_INTRIN_ENDPOINT3 usbconfig.h 100;" d
|
|
||||||
USB_CFG_HAVE_MEASURE_FRAME_LENGTH usbconfig.h 219;" d
|
|
||||||
USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH usbconfig.h 279;" d
|
|
||||||
USB_CFG_IMPLEMENT_FN_READ usbconfig.h 149;" d
|
|
||||||
USB_CFG_IMPLEMENT_FN_WRITE usbconfig.h 144;" d
|
|
||||||
USB_CFG_IMPLEMENT_FN_WRITEOUT usbconfig.h 155;" d
|
|
||||||
USB_CFG_IMPLEMENT_HALT usbconfig.h 116;" d
|
|
||||||
USB_CFG_INTERFACE_CLASS usbconfig.h 271;" d
|
|
||||||
USB_CFG_INTERFACE_PROTOCOL usbconfig.h 273;" d
|
|
||||||
USB_CFG_INTERFACE_SUBCLASS usbconfig.h 272;" d
|
|
||||||
USB_CFG_INTR_POLL_INTERVAL usbconfig.h 130;" d
|
|
||||||
USB_CFG_IOPORTNAME usbconfig.h 48;" d
|
|
||||||
USB_CFG_IS_SELF_POWERED usbconfig.h 135;" d
|
|
||||||
USB_CFG_LONG_TRANSFERS usbconfig.h 166;" d
|
|
||||||
USB_CFG_MAX_BUS_POWER usbconfig.h 139;" d
|
|
||||||
USB_CFG_SUPPRESS_INTR_CODE usbconfig.h 122;" d
|
|
||||||
USB_CFG_VENDOR_ID usbconfig.h 226;" d
|
|
||||||
USB_CFG_VENDOR_NAME usbconfig.h 241;" d
|
|
||||||
USB_CFG_VENDOR_NAME_LEN usbconfig.h 242;" d
|
|
||||||
USB_COUNT_SOF usbconfig.h 187;" d
|
|
||||||
USB_CRC requests.h 31;" d
|
|
||||||
USB_CRC_ADDR requests.h 32;" d
|
|
||||||
USB_CRC_CHECK config.h 43;" d
|
|
||||||
USB_DOWNLOAD_ADDR requests.h 29;" d
|
|
||||||
USB_DOWNLOAD_INIT requests.h 28;" d
|
|
||||||
USB_MAX_TRANS config.h 42;" d
|
|
||||||
USB_MODE_AVR requests.h 39;" d
|
|
||||||
USB_MODE_SNES requests.h 38;" d
|
|
||||||
USB_UPLOAD_ADDR requests.h 26;" d
|
|
||||||
USB_UPLOAD_INIT requests.h 25;" d
|
|
||||||
WGM12 timer.c 38;" d file:
|
|
||||||
WRITE fat.h 9;" d
|
|
||||||
XTAL timer.c 42;" d file:
|
|
||||||
_FAT_H fat.h 4;" d
|
|
||||||
_FILE_H file.h 6;" d
|
|
||||||
_HARDWARE_H hardware.h 7;" d
|
|
||||||
_MMC_H mmc.h 9;" d
|
|
||||||
__COMMAND_H__ command.h 23;" d
|
|
||||||
__CONFIH_H__ config.h 22;" d
|
|
||||||
__CRC_H__ crc.h 23;" d
|
|
||||||
__DEBUG_H__ debug.h 24;" d
|
|
||||||
__DUMP_H__ dump.h 23;" d
|
|
||||||
__FIFO_H__ fifo.h 21;" d
|
|
||||||
__FIFO_H__ loader.h 3;" d
|
|
||||||
__INFO_H__ info.h 24;" d
|
|
||||||
__REQUESTS_H__ requests.h 23;" d
|
|
||||||
__RLE_H__ rle.h 22;" d
|
|
||||||
__SHARED_MEMORY_H__ shared_memory.h 22;" d
|
|
||||||
__SRAM_H__ sram.h 24;" d
|
|
||||||
__TESTING_H__ testing.h 23;" d
|
|
||||||
__TIMER_H__ timer.h 22;" d
|
|
||||||
__UART_H__ uart.h 23;" d
|
|
||||||
__USB_BULK_H__ usb_bulk.h 23;" d
|
|
||||||
__WATCHDOG_H__ watchdog.h 27;" d
|
|
||||||
__usbconfig_h_included__ usbconfig.h 34;" d
|
|
||||||
_inline_fifo_get fifo.h /^static inline uint8_t _inline_fifo_get(fifo_t * f)$/;" f
|
|
||||||
_inline_fifo_put fifo.h /^static inline uint8_t _inline_fifo_put(fifo_t * f, const uint8_t data)$/;" f
|
|
||||||
adc_int uart.c /^ uint8_t adc_int:1;$/;" m struct:__anon2 file:
|
|
||||||
addr main.c /^uint32_t addr;$/;" v
|
|
||||||
addr_current sram.c /^uint32_t addr_current = 0;$/;" v
|
|
||||||
addr_stash sram.c /^uint32_t addr_stash = 0;$/;" v
|
|
||||||
attrib fat.h /^ unsigned char attrib; \/\/ 11,1 datei Attribut: 8=value name, 32=datei, 16=Verzeichniss, 15=linux kleingeschrieben eintrag$/;" m struct:File
|
|
||||||
avr_addr_latch_hi sram.h 108;" d
|
|
||||||
avr_addr_latch_lo sram.h 109;" d
|
|
||||||
avr_addr_sck_hi sram.h 115;" d
|
|
||||||
avr_addr_sck_lo sram.h 116;" d
|
|
||||||
avr_addr_ser_hi sram.h 122;" d
|
|
||||||
avr_addr_ser_lo sram.h 123;" d
|
|
||||||
avr_bus_active sram.h 158;" d
|
|
||||||
avr_cs_hi sram.h 74;" d
|
|
||||||
avr_cs_lo sram.h 75;" d
|
|
||||||
avr_data_in sram.h 38;" d
|
|
||||||
avr_data_out sram.h 41;" d
|
|
||||||
avr_rd_hi sram.h 60;" d
|
|
||||||
avr_rd_lo sram.h 61;" d
|
|
||||||
avr_wr_hi sram.h 67;" d
|
|
||||||
avr_wr_lo sram.h 68;" d
|
|
||||||
boot_startup_rom main.c /^void boot_startup_rom()$/;" f
|
|
||||||
bufferDirty fat.h /^ unsigned char bufferDirty; \/\/ puffer wurde beschrieben, sector muss geschrieben werden bevor er neu geladen wird$/;" m struct:Fat
|
|
||||||
cntOfBytes fat.h /^ unsigned int cntOfBytes; \/\/ -nicht direkt aus dem dateisystem- zäht geschriebene bytes eines sektors$/;" m struct:File
|
|
||||||
count fifo.h /^ uint8_t volatile count; \/\/ # Zeichen im Puffer$/;" m struct:__anon1
|
|
||||||
counter_down sram.h 136;" d
|
|
||||||
counter_load sram.h 129;" d
|
|
||||||
counter_up sram.h 143;" d
|
|
||||||
crc main.c /^uint16_t crc = 0;$/;" v
|
|
||||||
crc_check_bulk_memory crc.c /^uint16_t crc_check_bulk_memory(uint32_t bottom_addr, uint32_t top_addr, uint32_t bank_size)$/;" f
|
|
||||||
crc_check_memory_range crc.c /^uint16_t crc_check_memory_range(uint32_t start_addr, uint32_t size,uint8_t *buffer)$/;" f
|
|
||||||
crc_xmodem_update crc.c /^uint16_t crc_xmodem_update(uint16_t crc, uint8_t data)$/;" f
|
|
||||||
currentSectorNr fat.h /^ unsigned long int currentSectorNr;\/\/ aktuell geladener Sektor (in sector) \/\/beschleunigt wenn z.b 2* 512 byte puffer vorhanden, oder bei fat operationen im gleichen sektor$/;" m struct:Fat
|
|
||||||
dataDirSec fat.h /^ unsigned long int dataDirSec; \/\/ Sektor nr data area $/;" m struct:Fat
|
|
||||||
data_buffer main.c /^uint8_t data_buffer[4];$/;" v
|
|
||||||
debug debug.c /^void debug(int level, char* format, ...) {$/;" f
|
|
||||||
debug debug.h 34;" d
|
|
||||||
debug_level main.c /^uint8_t debug_level = (DEBUG | DEBUG_USB | DEBUG_CRC);$/;" v
|
|
||||||
dir fat.h /^ unsigned long int dir; \/\/ Direktory zeiger rootDir=='0' sonst(1.Cluster des dir; start auf root)$/;" m struct:Fat
|
|
||||||
do_crc crc.c /^uint16_t do_crc(uint8_t * data, uint16_t size)$/;" f
|
|
||||||
do_crc_update crc.c /^uint16_t do_crc_update(uint16_t crc, uint8_t * data, uint16_t size)$/;" f
|
|
||||||
dump_memory dump.c /^void dump_memory(uint32_t bottom_addr, uint32_t top_addr)$/;" f
|
|
||||||
dump_packet dump.c /^void dump_packet(uint32_t addr, uint32_t len, uint8_t * packet)$/;" f
|
|
||||||
endSectors fat.h /^ unsigned long int endSectors; $/;" m struct:Fat
|
|
||||||
fat fat.c /^struct Fat fat; \/\/ wichtige daten\/variablen der fat$/;" v typeref:struct:Fat
|
|
||||||
fatSec fat.h /^ unsigned long int fatSec; \/\/ Sektor nr fat area$/;" m struct:Fat
|
|
||||||
fatType fat.h /^ unsigned char fatType; \/\/ fat16 oder fat32 (16 oder 32)$/;" m struct:Fat
|
|
||||||
fat_cd fat.c /^unsigned char fat_cd(char name[]){$/;" f
|
|
||||||
fat_clustToSec fat.c /^unsigned long int fat_clustToSec(unsigned long int clust){$/;" f
|
|
||||||
fat_delClusterChain fat.c /^void fat_delClusterChain(unsigned long int startCluster){$/;" f
|
|
||||||
fat_getFatChainClustersInRow fat.c /^void fat_getFatChainClustersInRow(unsigned long int offsetCluster){$/;" f
|
|
||||||
fat_getFreeClustersInRow fat.c /^void fat_getFreeClustersInRow(unsigned long int offsetCluster){$/;" f
|
|
||||||
fat_getFreeRowOfCluster fat.c /^unsigned char fat_getFreeRowOfCluster(unsigned long secStart){$/;" f
|
|
||||||
fat_getFreeRowOfDir fat.c /^void fat_getFreeRowOfDir(unsigned long int dir){$/;" f
|
|
||||||
fat_getNextCluster fat.c /^unsigned long int fat_getNextCluster(unsigned long int oneCluster){ $/;" f
|
|
||||||
fat_initfat fat.c /^unsigned char fat_initfat(void){ $/;" f
|
|
||||||
fat_loadFatData fat.c /^unsigned char fat_loadFatData(unsigned long int sec){$/;" f
|
|
||||||
fat_loadFileDataFromCluster fat.c /^unsigned char fat_loadFileDataFromCluster(unsigned long int sec , char name[]){$/;" f
|
|
||||||
fat_loadFileDataFromDir fat.c /^unsigned char fat_loadFileDataFromDir(char name[]){ $/;" f
|
|
||||||
fat_loadRowOfSector fat.c /^unsigned char fat_loadRowOfSector(unsigned int row){$/;" f
|
|
||||||
fat_loadSector fat.c /^unsigned char fat_loadSector(unsigned long int sec){$/;" f
|
|
||||||
fat_makeFileEntry fat.c /^void fat_makeFileEntry(char name[],unsigned char attrib,unsigned long int length){$/;" f
|
|
||||||
fat_makeRowDataEntry fat.c /^void fat_makeRowDataEntry(unsigned int row,char name[],unsigned char attrib,unsigned long int cluster,unsigned long int length){$/;" f
|
|
||||||
fat_secToClust fat.c /^unsigned long int fat_secToClust(unsigned long int sec){$/;" f
|
|
||||||
fat_setCluster fat.c /^void fat_setCluster(unsigned long int cluster, unsigned long int content){ $/;" f
|
|
||||||
fat_setClusterChain fat.c /^void fat_setClusterChain(unsigned long int startCluster,unsigned int endCluster){$/;" f
|
|
||||||
fat_str fat.c /^char * fat_str(char *str){$/;" f
|
|
||||||
fat_writeSector fat.c /^unsigned char fat_writeSector(unsigned long int sec){ $/;" f
|
|
||||||
ffcd file.c /^unsigned char ffcd(char name[]){ $/;" f
|
|
||||||
ffcdLower file.c /^unsigned char ffcdLower(void){$/;" f
|
|
||||||
ffclose file.c /^unsigned char ffclose(void){$/;" f
|
|
||||||
ffls file.c /^void ffls(void){$/;" f
|
|
||||||
ffmkdir file.c /^void ffmkdir(char name[]){$/;" f
|
|
||||||
ffopen file.c /^unsigned char ffopen(char name[]){ $/;" f
|
|
||||||
ffread file.c /^inline unsigned char ffread(void){ $/;" f
|
|
||||||
ffrm file.c /^unsigned char ffrm(char name[]){ $/;" f
|
|
||||||
ffseek file.c /^void ffseek(unsigned long int offset){ $/;" f
|
|
||||||
ffwrite file.c /^inline void ffwrite(unsigned char c){$/;" f
|
|
||||||
ffwrites file.c /^inline void ffwrites(const char *s ){$/;" f
|
|
||||||
fifo_get_nowait fifo.c /^int fifo_get_nowait(fifo_t * f)$/;" f
|
|
||||||
fifo_get_wait fifo.c /^uint8_t fifo_get_wait(fifo_t * f)$/;" f
|
|
||||||
fifo_init fifo.c /^void fifo_init(fifo_t * f, uint8_t * buffer, const uint8_t size)$/;" f
|
|
||||||
fifo_put fifo.c /^uint8_t fifo_put(fifo_t * f, const uint8_t data)$/;" f
|
|
||||||
fifo_t fifo.h /^} fifo_t;$/;" t typeref:struct:__anon1
|
|
||||||
file fat.c /^struct File file; \/\/ wichtige dateibezogene daten\/variablen$/;" v typeref:struct:File
|
|
||||||
fileUpdate file.c /^void fileUpdate(void){$/;" f
|
|
||||||
firstCluster fat.h /^ unsigned long int firstCluster; \/\/ 20,2 \/26,2 datei 1.cluster hi,low(möglicherweise der einzige) (4-byte)$/;" m struct:File
|
|
||||||
info info.c /^void info(char* format, ...) {$/;" f
|
|
||||||
info info.c 34;" d file:
|
|
||||||
info info.h 34;" d
|
|
||||||
intflags uart.c /^} intflags;$/;" v typeref:struct:__anon2
|
|
||||||
irq_addr_hi shared_memory.c /^uint8_t irq_addr_hi;$/;" v
|
|
||||||
irq_addr_lo shared_memory.c /^uint8_t irq_addr_lo;$/;" v
|
|
||||||
lastCluster fat.h /^ unsigned long int lastCluster; \/\/ -nicht direkt aus dem dateisystem- letzter cluster der ersten kette$/;" m struct:File
|
|
||||||
led_off sram.h 49;" d
|
|
||||||
led_on sram.h 47;" d
|
|
||||||
length fat.h /^ unsigned long int length; \/\/ 28,4 datei Länge (4-byte)$/;" m struct:File
|
|
||||||
lsRowsOfClust file.c /^void lsRowsOfClust (unsigned long int start_sec){$/;" f
|
|
||||||
main main.c /^int main(void)$/;" f
|
|
||||||
mmc_disable mmc.h 38;" d
|
|
||||||
mmc_enable mmc.h 40;" d
|
|
||||||
mmc_init mmc.c /^uint8_t mmc_init()$/;" f
|
|
||||||
mmc_read_block mmc.c /^void mmc_read_block(uint8_t * cmd, uint8_t * Buffer, uint16_t Bytes)$/;" f
|
|
||||||
mmc_read_byte mmc.c /^uint8_t mmc_read_byte(void)$/;" f
|
|
||||||
mmc_read_cid mmc.c /^uint8_t mmc_read_cid(uint8_t * Buffer)$/;" f
|
|
||||||
mmc_read_csd mmc.c /^uint8_t mmc_read_csd(uint8_t * Buffer)$/;" f
|
|
||||||
mmc_read_sector mmc.c /^uint8_t mmc_read_sector(uint32_t addr, uint8_t * Buffer)$/;" f
|
|
||||||
mmc_write_byte mmc.c /^void mmc_write_byte(uint8_t Byte)$/;" f
|
|
||||||
mmc_write_command mmc.c /^uint8_t mmc_write_command(uint8_t * cmd)$/;" f
|
|
||||||
mmc_write_sector mmc.c /^uint8_t mmc_write_sector(uint32_t addr, uint8_t * Buffer)$/;" f
|
|
||||||
name fat.h /^ unsigned char name[13]; \/\/ 0,10 datei Name.ext (8.3 = max 11)(MUSS unsigned char weil E5)$/;" m struct:File
|
|
||||||
nop mmc.h 42;" d
|
|
||||||
pread fifo.h /^ uint8_t *pread; \/\/ Lesezeiger$/;" m struct:__anon1
|
|
||||||
prescaler timer.c /^uint16_t prescaler;$/;" v
|
|
||||||
pwrite fifo.h /^ uint8_t *pwrite; \/\/ Schreibzeiger$/;" m struct:__anon1
|
|
||||||
read2end fifo.h /^ uint8_t read2end, write2end; \/\/ # Zeichen bis zum Überlauf Lese-\/Schreibzeiger$/;" m struct:__anon1
|
|
||||||
read_buffer main.c /^uint8_t read_buffer[TRANSFER_BUFFER_SIZE];$/;" v
|
|
||||||
req_addr main.c /^uint32_t req_addr = 0;$/;" v
|
|
||||||
req_addr_end main.c /^uint32_t req_addr_end = 0;$/;" v
|
|
||||||
req_bank main.c /^uint8_t req_bank;$/;" v
|
|
||||||
req_bank_cnt main.c /^uint16_t req_bank_cnt;$/;" v
|
|
||||||
req_bank_size main.c /^uint32_t req_bank_size;$/;" v
|
|
||||||
req_percent main.c /^uint8_t req_percent;$/;" v
|
|
||||||
req_percent_last main.c /^uint8_t req_percent_last;$/;" v
|
|
||||||
req_size main.c /^uint32_t req_size;$/;" v
|
|
||||||
req_state main.c /^uint8_t req_state = REQ_STATUS_IDLE;$/;" v
|
|
||||||
rle_decode rle.c /^uint8_t rle_decode(PGM_VOID_P in_addr, int32_t in_len, uint32_t out_addr)$/;" f
|
|
||||||
rootDir fat.h /^ unsigned long int rootDir; \/\/ Sektor(f16)\/Cluster(f32) nr root directory$/;" m struct:Fat
|
|
||||||
row fat.h /^ unsigned char row; \/\/ reihe im sektor in der die datei infos stehen (reihe 0-15)$/;" m struct:File
|
|
||||||
rx_int uart.c /^ uint8_t rx_int:1;$/;" m struct:__anon2 file:
|
|
||||||
rx_remaining main.c /^uint8_t rx_remaining = 0;$/;" v
|
|
||||||
rxbuff uart.c /^volatile char rxbuff;$/;" v
|
|
||||||
scratchpad_cmd shared_memory.c /^uint8_t scratchpad_cmd;$/;" v
|
|
||||||
scratchpad_payload shared_memory.c /^uint8_t scratchpad_payload;$/;" v
|
|
||||||
scratchpad_state shared_memory.c /^uint8_t scratchpad_state;$/;" v
|
|
||||||
secPerClust fat.h /^ unsigned char secPerClust; \/\/ anzahl der sektoren pro cluster$/;" m struct:Fat
|
|
||||||
second timer.c /^uint16_t volatile second; \/\/ count seconds$/;" v
|
|
||||||
sector fat.h /^ unsigned char sector[512]; \/\/ der puffer für sektoren !$/;" m struct:Fat
|
|
||||||
seek fat.h /^ unsigned long int seek; \/\/ schreib position in der datei$/;" m struct:File
|
|
||||||
send_irq command.c /^void send_irq()$/;" f
|
|
||||||
send_reset command.c /^void send_reset()$/;" f
|
|
||||||
set_rom_mode command.c /^void set_rom_mode()$/;" f
|
|
||||||
shared_memory_irq_hook shared_memory.c /^void shared_memory_irq_hook()$/;" f
|
|
||||||
shared_memory_irq_restore shared_memory.c /^void shared_memory_irq_restore()$/;" f
|
|
||||||
shared_memory_read shared_memory.c /^int shared_memory_read(uint8_t *cmd, uint8_t *len,uint8_t *buffer)$/;" f
|
|
||||||
shared_memory_scratchpad_tx_restore shared_memory.c /^void shared_memory_scratchpad_tx_restore()$/;" f
|
|
||||||
shared_memory_scratchpad_tx_save shared_memory.c /^void shared_memory_scratchpad_tx_save()$/;" f
|
|
||||||
shared_memory_write shared_memory.c /^void shared_memory_write(uint8_t cmd, uint8_t value)$/;" f
|
|
||||||
shared_memory_yield shared_memory.c /^void shared_memory_yield()$/;" f
|
|
||||||
size fifo.h /^ uint8_t size; \/\/ Puffer-Größe$/;" m struct:__anon1
|
|
||||||
snes_bus_active sram.h 162;" d
|
|
||||||
snes_hirom sram.h 169;" d
|
|
||||||
snes_irq_hi sram.h 83;" d
|
|
||||||
snes_irq_lo sram.h 86;" d
|
|
||||||
snes_irq_off sram.h 85;" d
|
|
||||||
snes_irq_on sram.h 82;" d
|
|
||||||
snes_lorom sram.h 170;" d
|
|
||||||
snes_reset_hi sram.h 94;" d
|
|
||||||
snes_reset_lo sram.h 97;" d
|
|
||||||
snes_reset_off sram.h 96;" d
|
|
||||||
snes_reset_on sram.h 93;" d
|
|
||||||
snes_wr_disable sram.h 176;" d
|
|
||||||
snes_wr_enable sram.h 178;" d
|
|
||||||
soft_reset watchdog.h 32;" d
|
|
||||||
sram_bulk_addr_restore sram.c /^inline void sram_bulk_addr_restore()$/;" f
|
|
||||||
sram_bulk_addr_save sram.c /^inline void sram_bulk_addr_save()$/;" f
|
|
||||||
sram_bulk_copy sram.c /^void sram_bulk_copy_from_buffer(uint32_t addr, uint8_t * src, uint32_t len)$/;" f
|
|
||||||
sram_bulk_read sram.c /^inline uint8_t sram_bulk_read(void)$/;" f
|
|
||||||
sram_bulk_copy_into_buffer sram.c /^void sram_bulk_copy_into_buffer(uint32_t addr, uint8_t * dst, uint32_t len)$/;" f
|
|
||||||
sram_bulk_read_end sram.c /^void sram_bulk_read_end(void)$/;" f
|
|
||||||
sram_bulk_read_next sram.c /^inline void sram_bulk_read_next(void)$/;" f
|
|
||||||
sram_bulk_read_start sram.c /^void sram_bulk_read_start(uint32_t addr)$/;" f
|
|
||||||
sram_bulk_set sram.c /^void sram_bulk_set(uint32_t addr, uint32_t len,uint8_t value){$/;" f
|
|
||||||
sram_bulk_write sram.c /^inline void sram_bulk_write( uint8_t data)$/;" f
|
|
||||||
sram_bulk_write_end sram.c /^void sram_bulk_write_end(void)$/;" f
|
|
||||||
sram_bulk_write_next sram.c /^inline void sram_bulk_write_next(void)$/;" f
|
|
||||||
sram_bulk_write_start sram.c /^void sram_bulk_write_start(uint32_t addr)$/;" f
|
|
||||||
sram_read sram.c /^uint8_t sram_read(uint32_t addr)$/;" f
|
|
||||||
sram_write sram.c /^void sram_write(uint32_t addr, uint8_t data)$/;" f
|
|
||||||
sreg_set sram.c /^void sreg_set(uint32_t addr)$/;" f
|
|
||||||
startSectors fat.h /^ unsigned long int startSectors; \/\/ der erste sektor in einer reihe (freie oder verkettete)$/;" m struct:Fat
|
|
||||||
sync_errors main.c /^uint16_t sync_errors = 0;$/;" v
|
|
||||||
system_init sram.c /^void system_init(void)$/;" f
|
|
||||||
test_bulk_read_write testing.c /^void test_bulk_read_write()$/;" f
|
|
||||||
test_crc testing.c /^void test_crc()$/;" f
|
|
||||||
test_non_zero_memory testing.c /^void test_non_zero_memory(uint32_t bottom_addr, uint32_t top_addr)$/;" f
|
|
||||||
test_read_write testing.c /^void test_read_write()$/;" f
|
|
||||||
test_sdcard testing.c /^void test_sdcard(void){$/;" f
|
|
||||||
timer_start timer.c /^void timer_start( void )$/;" f
|
|
||||||
timer_stop_int timer.c /^uint16_t timer_stop_int(void)$/;" f
|
|
||||||
tmr_int uart.c /^ uint8_t tmr_int:1;$/;" m struct:__anon2 file:
|
|
||||||
tx_buffer main.c /^uint8_t tx_buffer[32];$/;" v
|
|
||||||
tx_remaining main.c /^uint8_t tx_remaining = 0;$/;" v
|
|
||||||
uart_init uart.c /^void uart_init(void)$/;" f
|
|
||||||
uart_putc uart.c /^void uart_putc(uint8_t c)$/;" f
|
|
||||||
uart_puts uart.c /^void uart_puts(const char *s)$/;" f
|
|
||||||
uart_puts_P uart.c /^void uart_puts_P(PGM_P s)$/;" f
|
|
||||||
uart_stdout uart.c /^FILE uart_stdout = FDEV_SETUP_STREAM(uart_stream, NULL, _FDEV_SETUP_WRITE);$/;" v
|
|
||||||
uart_stream uart.c /^static int uart_stream(char c, FILE * stream)$/;" f file:
|
|
||||||
uint timer.c 47;" d file:
|
|
||||||
uint8_t timer.c 46;" d file:
|
|
||||||
usbFunctionRead usb_bulk.c /^uint8_t usbFunctionRead(uint8_t * data, uint8_t len)$/;" f
|
|
||||||
usbFunctionSetup main.c /^usbMsgLen_t usbFunctionSetup(uchar data[8])$/;" f
|
|
||||||
usbFunctionWrite usb_bulk.c /^uint8_t usbFunctionWrite(uint8_t * data, uint8_t len)$/;" f
|
|
||||||
usb_connect main.c /^void usb_connect()$/;" f
|
|
||||||
wdt_init watchdog.c /^void wdt_init(void)$/;" f
|
|
||||||
write2end fifo.h /^ uint8_t read2end, write2end; \/\/ # Zeichen bis zum Überlauf Lese-\/Schreibzeiger$/;" m struct:__anon1
|
|
||||||
@@ -22,15 +22,31 @@
|
|||||||
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdint.h>
|
#include <string.h>
|
||||||
#include <util/delay.h>
|
#include <avr/io.h>
|
||||||
|
#include <avr/interrupt.h>
|
||||||
|
#include <util/delay.h>
|
||||||
|
#include <avr/pgmspace.h>
|
||||||
|
#include <avr/eeprom.h>
|
||||||
|
|
||||||
#include "shared_memory.h"
|
#include "usbdrv.h"
|
||||||
|
#include "oddebug.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
#include "requests.h"
|
||||||
|
#include "uart.h"
|
||||||
#include "sram.h"
|
#include "sram.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "crc.h"
|
|
||||||
#include "info.h"
|
#include "info.h"
|
||||||
|
#include "dump.h"
|
||||||
|
#include "crc.h"
|
||||||
|
#include "usb_bulk.h"
|
||||||
|
#include "timer.h"
|
||||||
|
#include "watchdog.h"
|
||||||
|
#include "rle.h"
|
||||||
|
#include "loader.h"
|
||||||
|
#include "command.h"
|
||||||
|
#include "shared_memory.h"
|
||||||
|
#include "testing.h"
|
||||||
|
|
||||||
void test_read_write()
|
void test_read_write()
|
||||||
{
|
{
|
||||||
@@ -45,7 +61,7 @@ void test_read_write()
|
|||||||
}
|
}
|
||||||
addr = 0x000000;
|
addr = 0x000000;
|
||||||
while (addr++ <= 0x0000ff) {
|
while (addr++ <= 0x0000ff) {
|
||||||
info_P(PSTR("read addr=0x%08lx %x\n"), addr, sram_read(addr));
|
info("read addr=0x%08lx %x\n", addr, sram_read(addr));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -69,7 +85,7 @@ void test_bulk_read_write()
|
|||||||
addr = 0x000000;
|
addr = 0x000000;
|
||||||
sram_bulk_read_start(addr);
|
sram_bulk_read_start(addr);
|
||||||
while (addr <= 0x8000) {
|
while (addr <= 0x8000) {
|
||||||
info_P(PSTR("addr=0x%08lx %x\n"), addr, sram_bulk_read());
|
info("addr=0x%08lx %x\n", addr, sram_bulk_read());
|
||||||
sram_bulk_read_next();
|
sram_bulk_read_next();
|
||||||
addr++;
|
addr++;
|
||||||
}
|
}
|
||||||
@@ -85,7 +101,7 @@ void test_non_zero_memory(uint32_t bottom_addr, uint32_t top_addr)
|
|||||||
for (addr = bottom_addr; addr < top_addr; addr++) {
|
for (addr = bottom_addr; addr < top_addr; addr++) {
|
||||||
c = sram_bulk_read();
|
c = sram_bulk_read();
|
||||||
if (c != 0xff)
|
if (c != 0xff)
|
||||||
info_P(PSTR("addr=0x%08lx c=0x%x\n"), addr, c);
|
info("addr=0x%08lx c=0x%x\n", addr, c);
|
||||||
sram_bulk_read_next();
|
sram_bulk_read_next();
|
||||||
}
|
}
|
||||||
sram_bulk_read_end();
|
sram_bulk_read_end();
|
||||||
@@ -95,12 +111,154 @@ void test_non_zero_memory(uint32_t bottom_addr, uint32_t top_addr)
|
|||||||
|
|
||||||
void test_crc()
|
void test_crc()
|
||||||
{
|
{
|
||||||
info_P(PSTR("test_crc: clear\n"));
|
info("test_crc: clear\n");
|
||||||
avr_bus_active();
|
avr_bus_active();
|
||||||
sram_bulk_set(0x000000, 0x10000, 0xff);
|
sram_bulk_set(0x000000, 0x10000, 0xff);
|
||||||
info_P(PSTR("test_crc: crc\n"));
|
info("test_crc: crc\n");
|
||||||
crc_check_bulk_memory(0x000000, 0x10000, 0x8000);
|
crc_check_bulk_memory(0x000000, 0x10000, 0x8000);
|
||||||
info_P(PSTR("test_crc: check\n"));
|
info("test_crc: check\n");
|
||||||
test_non_zero_memory(0x000000, 0x10000);
|
test_non_zero_memory(0x000000, 0x10000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------*/
|
||||||
|
/* FAT file system sample project for FatFs R0.06 (C)ChaN, 2008 */
|
||||||
|
/*----------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "ff.h"
|
||||||
|
#include "diskio.h"
|
||||||
|
#include "rtc.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
DWORD acc_size; /* Work register for fs command */
|
||||||
|
WORD acc_files, acc_dirs;
|
||||||
|
FILINFO finfo;
|
||||||
|
|
||||||
|
|
||||||
|
FATFS fatfs[2]; /* File system object for each logical drive */
|
||||||
|
BYTE Buff[1024]; /* Working buffer */
|
||||||
|
|
||||||
|
volatile WORD Timer; /* 100Hz increment timer */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#if _MULTI_PARTITION != 0
|
||||||
|
const PARTITION Drives[] = { {0,0}, {0,1} };
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
ISR(TIMER2_COMP_vect)
|
||||||
|
{
|
||||||
|
Timer++;
|
||||||
|
disk_timerproc();
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
DWORD get_fattime ()
|
||||||
|
{
|
||||||
|
RTC rtc;
|
||||||
|
|
||||||
|
|
||||||
|
//rtc_gettime(&rtc);
|
||||||
|
|
||||||
|
return ((DWORD)(rtc.year - 1980) << 25)
|
||||||
|
| ((DWORD)rtc.month << 21)
|
||||||
|
| ((DWORD)rtc.mday << 16)
|
||||||
|
| ((DWORD)rtc.hour << 11)
|
||||||
|
| ((DWORD)rtc.min << 5)
|
||||||
|
| ((DWORD)rtc.sec >> 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static
|
||||||
|
FRESULT scan_files (char* path)
|
||||||
|
{
|
||||||
|
DIR dirs;
|
||||||
|
FRESULT res;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if ((res = f_opendir(&dirs, path)) == FR_OK) {
|
||||||
|
i = strlen(path);
|
||||||
|
while (((res = f_readdir(&dirs, &finfo)) == FR_OK) && finfo.fname[0]) {
|
||||||
|
if (finfo.fattrib & AM_DIR) {
|
||||||
|
acc_dirs++;
|
||||||
|
*(path+i) = '/'; strcpy(path+i+1, &finfo.fname[0]);
|
||||||
|
res = scan_files(path);
|
||||||
|
*(path+i) = '\0';
|
||||||
|
if (res != FR_OK) break;
|
||||||
|
} else {
|
||||||
|
acc_files++;
|
||||||
|
acc_size += finfo.fsize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static
|
||||||
|
void put_rc (FRESULT rc)
|
||||||
|
{
|
||||||
|
const prog_char *p;
|
||||||
|
static const prog_char str[] =
|
||||||
|
"OK\0" "DISK_ERR\0" "INT_ERR\0" "NOT_READY\0" "NO_FILE\0" "NO_PATH\0"
|
||||||
|
"INVALID_NAME\0" "DENIED\0" "EXIST\0" "INVALID_OBJECT\0" "WRITE_PROTECTED\0"
|
||||||
|
"INVALID_DRIVE\0" "NOT_ENABLED\0" "NO_FILE_SYSTEM\0" "MKFS_ABORTED\0" "TIMEOUT\0";
|
||||||
|
FRESULT i;
|
||||||
|
|
||||||
|
for (p = str, i = 0; i != rc && pgm_read_byte_near(p); i++) {
|
||||||
|
while(pgm_read_byte_near(p++));
|
||||||
|
}
|
||||||
|
printf("rc=%u FR_%s\n", (WORD)rc, p);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void test_sdcard (void)
|
||||||
|
{
|
||||||
|
char *ptr, *ptr2;
|
||||||
|
DWORD p1, p2, p3;
|
||||||
|
BYTE res, b1;
|
||||||
|
WORD w1;
|
||||||
|
UINT s1, s2, cnt;
|
||||||
|
DWORD ofs, sect = 0;
|
||||||
|
RTC rtc;
|
||||||
|
FATFS *fs;
|
||||||
|
DIR dir; /* Directory object */
|
||||||
|
FIL file1, file2; /* File object */
|
||||||
|
|
||||||
|
|
||||||
|
printf("Try to init disk\n");
|
||||||
|
put_rc(f_mount((BYTE) 0, &fatfs[0]));
|
||||||
|
res = f_getfree("", &p2, &fs);
|
||||||
|
if (res)
|
||||||
|
put_rc(res);
|
||||||
|
|
||||||
|
printf( "FAT TYPE = %u\nBYTES/CLUSTER = %lu\nNUMBER OF FATS = %u\n"
|
||||||
|
"ROOT DIR ENTRIES = %u\nSECTORS/FAT = %lu\nNUMBER OF CLUSTERS = %lu\n"
|
||||||
|
"FAT START = %lu\nDIR START LBA,CLUSTER = %lu\nDATA START LBA = %lu\n",
|
||||||
|
(WORD) fs->fs_type, (DWORD) fs->csize * 512,
|
||||||
|
(WORD) fs->n_fats, fs->n_rootdir, (DWORD) fs->sects_fat,
|
||||||
|
(DWORD) fs->max_clust - 2, fs->fatbase, fs->dirbase, fs->database);
|
||||||
|
acc_size = acc_files = acc_dirs = 0;
|
||||||
|
|
||||||
|
printf("scan files\n");
|
||||||
|
res = scan_files("");
|
||||||
|
if (res)
|
||||||
|
put_rc(res);
|
||||||
|
printf("%u FILES, %lu BYTES\n%u FOLDERS\n"
|
||||||
|
"%lu KB TOTAK DISK SPACE\n%lu KB AVAILABLE\n", acc_files,
|
||||||
|
acc_size, acc_dirs, (fs->max_clust - 2) * (fs->csize / 2),
|
||||||
|
p2 * (fs->csize / 2));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -29,11 +29,7 @@
|
|||||||
|
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "info.h"
|
#include "info.h"
|
||||||
#include "sram.h"
|
|
||||||
|
|
||||||
|
|
||||||
extern uint8_t snes_reset_line;
|
|
||||||
|
|
||||||
#ifndef OCR1A
|
#ifndef OCR1A
|
||||||
#define OCR1A OCR1 // 2313 support
|
#define OCR1A OCR1 // 2313 support
|
||||||
#endif
|
#endif
|
||||||
@@ -56,7 +52,6 @@ uint16_t volatile second; // count seconds
|
|||||||
|
|
||||||
ISR (SIG_OUTPUT_COMPARE1A)
|
ISR (SIG_OUTPUT_COMPARE1A)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
#if XTAL % DEBOUNCE // bei rest
|
#if XTAL % DEBOUNCE // bei rest
|
||||||
OCR1A = 20000000UL / DEBOUNCE - 1; // compare DEBOUNCE - 1 times
|
OCR1A = 20000000UL / DEBOUNCE - 1; // compare DEBOUNCE - 1 times
|
||||||
|
|||||||
@@ -31,7 +31,10 @@ volatile struct {
|
|||||||
uint8_t rx_int:1;
|
uint8_t rx_int:1;
|
||||||
} intflags;
|
} intflags;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* * Last character read from the UART.
|
||||||
|
*
|
||||||
|
*/
|
||||||
volatile char rxbuff;
|
volatile char rxbuff;
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -56,14 +56,14 @@ uint8_t usbFunctionWrite(uint8_t * data, uint8_t len)
|
|||||||
uint8_t i;
|
uint8_t i;
|
||||||
|
|
||||||
if (len > rx_remaining) {
|
if (len > rx_remaining) {
|
||||||
info_P(PSTR("ERROR:usbFunctionWrite more data than expected remain: %i len: %i\n"),
|
info("ERROR:usbFunctionWrite more data than expected remain: %i len: %i\n",
|
||||||
rx_remaining, len);
|
rx_remaining, len);
|
||||||
len = rx_remaining;
|
len = rx_remaining;
|
||||||
}
|
}
|
||||||
if (req_state == REQ_STATUS_BULK_UPLOAD) {
|
if (req_state == REQ_STATUS_BULK_UPLOAD) {
|
||||||
|
|
||||||
rx_remaining -= len;
|
rx_remaining -= len;
|
||||||
debug_P(DEBUG_USB_TRANS, PSTR("usbFunctionWrite REQ_STATUS_BULK_UPLOAD addr: 0x%08lx len: %i rx_remaining=%i\n"),
|
debug(DEBUG_USB_TRANS,"usbFunctionWrite REQ_STATUS_BULK_UPLOAD addr: 0x%08lx len: %i rx_remaining=%i\n",
|
||||||
req_addr, len, rx_remaining);
|
req_addr, len, rx_remaining);
|
||||||
ptr = data;
|
ptr = data;
|
||||||
i = len;
|
i = len;
|
||||||
@@ -72,6 +72,8 @@ uint8_t usbFunctionWrite(uint8_t * data, uint8_t len)
|
|||||||
sram_bulk_write_next();
|
sram_bulk_write_next();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/* test this */
|
||||||
|
//return rx_remaining == 0
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -81,7 +83,7 @@ uint8_t usbFunctionRead(uint8_t * data, uint8_t len)
|
|||||||
if (len > tx_remaining)
|
if (len > tx_remaining)
|
||||||
len = tx_remaining;
|
len = tx_remaining;
|
||||||
tx_remaining -= len;
|
tx_remaining -= len;
|
||||||
debug_P(DEBUG_USB_TRANS, PSTR("usbFunctionRead len=%i tx_remaining=%i \n"), len, tx_remaining);
|
debug(DEBUG_USB_TRANS,"usbFunctionRead len=%i tx_remaining=%i \n", len, tx_remaining);
|
||||||
|
|
||||||
for (i = 0; i < len; i++) {
|
for (i = 0; i < len; i++) {
|
||||||
*data = tx_buffer[len];
|
*data = tx_buffer[len];
|
||||||
|
|||||||
@@ -248,8 +248,8 @@ section at the end of this file).
|
|||||||
* obdev's free shared VID/PID pair. See the file USBID-License.txt for
|
* obdev's free shared VID/PID pair. See the file USBID-License.txt for
|
||||||
* details.
|
* details.
|
||||||
*/
|
*/
|
||||||
#define USB_CFG_DEVICE_NAME 'Q', 'U', 'I', 'C', 'K', 'D', 'E', 'V', '1', '6'
|
#define USB_CFG_DEVICE_NAME 'S', 'N', 'E', 'S', 'R', 'A', 'M'
|
||||||
#define USB_CFG_DEVICE_NAME_LEN 10
|
#define USB_CFG_DEVICE_NAME_LEN 7
|
||||||
/* Same as above for the device name. If you don't want a device name, undefine
|
/* Same as above for the device name. If you don't want a device name, undefine
|
||||||
* the macros. See the file USBID-License.txt before you assign a name if you
|
* the macros. See the file USBID-License.txt before you assign a name if you
|
||||||
* use a shared VID/PID.
|
* use a shared VID/PID.
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@@ -1,77 +0,0 @@
|
|||||||
# SDK Config
|
|
||||||
|
|
||||||
|
|
||||||
PLATFORM=$(shell uname)
|
|
||||||
|
|
||||||
ifeq ($(PLATFORM),Linux)
|
|
||||||
# Linux Wine
|
|
||||||
SDK=/home/david/.wine/drive_c/65xx_FreeSDK
|
|
||||||
WINE=wine
|
|
||||||
EMU=../../tools/bsnes/bsnes
|
|
||||||
DISASM=/home/david/Devel/arch/snes/devkit/bin/disasm
|
|
||||||
UCON=ucon64
|
|
||||||
else
|
|
||||||
# Mac Wine
|
|
||||||
SDK=/Users/david/.wine/drive_c/65xx_FreeSDK
|
|
||||||
WINE=wine
|
|
||||||
EMU=zsnes
|
|
||||||
DISASM=/Users/david/Devel/arch/snes/devkit/bin/disasm
|
|
||||||
UCON=ucon64
|
|
||||||
endif
|
|
||||||
|
|
||||||
CC=$(WINE) $(SDK)/bin/WDC816CC.exe
|
|
||||||
AS=$(WINE) $(SDK)/bin/WDC816AS.exe
|
|
||||||
LD=$(WINE) $(SDK)/bin/WDCLN.exe
|
|
||||||
PADBIN=$(WINE) tools/padbin.exe
|
|
||||||
|
|
||||||
# Project
|
|
||||||
|
|
||||||
INC=$(SDK)/include
|
|
||||||
LIBS=-L$(SDK)/lib/cc
|
|
||||||
#-L$(SDK)/lib/c134
|
|
||||||
|
|
||||||
|
|
||||||
OBJS=StartupSnes.obj main.obj pad.obj PPU.obj debug.obj ressource.obj
|
|
||||||
APP=loadertest.smc
|
|
||||||
GFX=debugfont
|
|
||||||
|
|
||||||
all: $(APP)
|
|
||||||
|
|
||||||
run:
|
|
||||||
$(EMU) $(APP)
|
|
||||||
|
|
||||||
|
|
||||||
disasm: $(APP)
|
|
||||||
rm -rf $(APP)
|
|
||||||
$(DISASM) $(APP) > $(APP).asm
|
|
||||||
|
|
||||||
upload: header
|
|
||||||
ucon64 --port=usb --xsnesram $(APP)
|
|
||||||
|
|
||||||
repair: $(APP)
|
|
||||||
$(UCON) -snes -chk $(APP) 2>&1 >/dev/null
|
|
||||||
rm -rf *.bak
|
|
||||||
|
|
||||||
header: $(APP)
|
|
||||||
$(UCON) -smc $(APP)
|
|
||||||
rm -rf *.bak
|
|
||||||
|
|
||||||
StartupSnes.obj: StartupSnes.asm
|
|
||||||
$(AS) -V $?
|
|
||||||
|
|
||||||
ressource.obj: ressource.asm
|
|
||||||
$(AS) -V $?
|
|
||||||
|
|
||||||
%.obj: %.c
|
|
||||||
$(CC) -wl -wp -sop -MC -I $(INC) $?
|
|
||||||
|
|
||||||
$(APP): $(OBJS)
|
|
||||||
$(LD) -B -HB -M21 -V -T -Pff \
|
|
||||||
-C008000,0000 -U0000,0000 \
|
|
||||||
-Avectors=FFE4,7FE4 \
|
|
||||||
-Aregistration_data=FFB0,7FB0 \
|
|
||||||
-Aressource=18000,8000 \
|
|
||||||
-N $(OBJS) $(LIBS) -O $@
|
|
||||||
$(PADBIN) 0x20000 $(APP)
|
|
||||||
clean:
|
|
||||||
rm -vf $(APP) *.obj *.TMP
|
|
||||||
@@ -1,90 +0,0 @@
|
|||||||
#include "data.h"
|
|
||||||
|
|
||||||
byte tileMapLocation[4];
|
|
||||||
word characterLocation[4];
|
|
||||||
|
|
||||||
void waitForVBlank(void)
|
|
||||||
{
|
|
||||||
byte Status;
|
|
||||||
do {
|
|
||||||
Status = *(byte *) 0x4210;
|
|
||||||
} while (!(Status & 0x80));
|
|
||||||
}
|
|
||||||
|
|
||||||
void setTileMapLocation(word vramDst, byte screenProp, byte bgNumber)
|
|
||||||
{
|
|
||||||
tileMapLocation[bgNumber] = ((vramDst >> 8) & 0xfc) | (screenProp & 0x03);
|
|
||||||
*(byte *) (0x2107 + bgNumber) = tileMapLocation[bgNumber];
|
|
||||||
}
|
|
||||||
|
|
||||||
void restoreTileMapLocation(byte bgNumber)
|
|
||||||
{
|
|
||||||
*(byte *) (0x2107 + bgNumber) = tileMapLocation[bgNumber];
|
|
||||||
}
|
|
||||||
|
|
||||||
void setCharacterLocation(word vramDst, byte bgNumber)
|
|
||||||
{
|
|
||||||
characterLocation[bgNumber] = vramDst;
|
|
||||||
if (bgNumber < 2) {
|
|
||||||
*(byte *) 0x210b =
|
|
||||||
(characterLocation[1] >> 8 & 0xf0) + (characterLocation[0] >> 12);
|
|
||||||
} else {
|
|
||||||
*(byte *) 0x210c =
|
|
||||||
(characterLocation[3] >> 8 & 0xf0) + (characterLocation[2] >> 12);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void restoreCharacterLocation(byte bgNumber)
|
|
||||||
{
|
|
||||||
setCharacterLocation(characterLocation[bgNumber], bgNumber);
|
|
||||||
}
|
|
||||||
|
|
||||||
void VRAMByteWrite(byte value, word vramDst)
|
|
||||||
{
|
|
||||||
*(byte *) 0x2115 = 0x80;
|
|
||||||
*(word *) 0x2116 = vramDst;
|
|
||||||
|
|
||||||
*(byte *) 0x2118 = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
void VRAMLoad(word src, word vramDst, word size)
|
|
||||||
{
|
|
||||||
// set address in VRam for read or write ($2116) + block size transfer ($2115)
|
|
||||||
*(byte *) 0x2115 = 0x80;
|
|
||||||
*(word *) 0x2116 = vramDst;
|
|
||||||
|
|
||||||
*(word *) 0x4300 = 0x1801; // set DMA control register (1 word inc)
|
|
||||||
// and destination ($21xx xx -> 0x18)
|
|
||||||
*(word *) 0x4302 = src; // DMA channel x source address offset
|
|
||||||
// (low $4302 and high $4303 optimisation)
|
|
||||||
*(byte *) 0x4304 = 0x01; // DMA channel x source address bank
|
|
||||||
*(word *) 0x4305 = size; // DMA channel x transfer size
|
|
||||||
// (low $4305 and high $4306 optimisation)
|
|
||||||
|
|
||||||
// Turn on DMA transfer for this channel
|
|
||||||
waitForVBlank();
|
|
||||||
*(byte *) 0x2100 = 0x80;
|
|
||||||
*(byte *) 0x420b = 0x01;
|
|
||||||
*(byte *) 0x2100 = 0x00;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CGRAMLoad(word src, byte cgramDst, word size)
|
|
||||||
{
|
|
||||||
|
|
||||||
// set address in VRam for read or write + block size
|
|
||||||
*(byte *) 0x2121 = cgramDst;
|
|
||||||
|
|
||||||
*(word *) 0x4300 = 0x2200; // set DMA control register (1 byte inc)
|
|
||||||
// and destination ($21xx xx -> 022)
|
|
||||||
*(word *) 0x4302 = src; // DMA channel x source address offset
|
|
||||||
// (low $4302 and high $4303 optimisation)
|
|
||||||
*(byte *) 0x4304 = 0x01; // DMA channel x source address bank
|
|
||||||
*(word *) 0x4305 = size; // DMA channel x transfer size
|
|
||||||
// (low $4305 and high $4306 optimisation)
|
|
||||||
|
|
||||||
// Turn on DMA transfer for this channel
|
|
||||||
waitForVBlank();
|
|
||||||
*(byte *) 0x2100 = 0x80;
|
|
||||||
*(byte *) 0x420b = 0x01;
|
|
||||||
*(byte *) 0x2100 = 0x00;
|
|
||||||
}
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
extern byte tileMapLocation[4];
|
|
||||||
extern word characterLocation[4];
|
|
||||||
|
|
||||||
void waitForVBlank(void);
|
|
||||||
void setTileMapLocation(word vramDst, byte screenProp, byte bgNumber);
|
|
||||||
void restoreTileMapLocation(byte bgNumber);
|
|
||||||
void setCharacterLocation(word vramDst, byte bgNumber);
|
|
||||||
void restoreCharacterLocation(byte bgNumber);
|
|
||||||
void VRAMByteWrite(byte value, word vramDst);
|
|
||||||
void VRAMLoad(word src, word vramDst, word size);
|
|
||||||
void CGRAMLoad(word src, byte cgramDst, word size);
|
|
||||||
@@ -1,240 +0,0 @@
|
|||||||
; SNES ROM startup code
|
|
||||||
|
|
||||||
;******************************************************************************
|
|
||||||
;*** Define a special section in case most of the code is not in bank 0. ***
|
|
||||||
;******************************************************************************
|
|
||||||
|
|
||||||
;STACK EQU $01ff ;CHANGE THIS FOR YOUR SYSTEM
|
|
||||||
|
|
||||||
;STARTUP SECTION OFFSET $008000
|
|
||||||
|
|
||||||
CODE
|
|
||||||
|
|
||||||
XDEF START
|
|
||||||
START:
|
|
||||||
XREF _~main
|
|
||||||
|
|
||||||
sei ; Disabled interrupts
|
|
||||||
clc ; clear carry to switch to native mode
|
|
||||||
xce ; Xchange carry & emulation bit. native mode
|
|
||||||
rep #$18 ; Binary mode (decimal mode off), X/Y 16 bit
|
|
||||||
LONGI ON
|
|
||||||
ldx #$1FFF ; set stack to $1FFF
|
|
||||||
txs
|
|
||||||
|
|
||||||
rep #$30
|
|
||||||
longa on
|
|
||||||
longi on
|
|
||||||
|
|
||||||
; Init data used for heap
|
|
||||||
; see heap definition below
|
|
||||||
XREF _~_heap_top
|
|
||||||
XREF _~_mem_start
|
|
||||||
stz _~_heap_top
|
|
||||||
stz _~_mem_start
|
|
||||||
|
|
||||||
XREF _~preInit
|
|
||||||
jsr >_~preInit
|
|
||||||
|
|
||||||
sep #$30 ; X,Y,A are 8 bit numbers
|
|
||||||
LONGA OFF
|
|
||||||
LONGI OFF
|
|
||||||
lda #$8F ; screen off, full brightness
|
|
||||||
sta $2100 ; brightness + screen enable register
|
|
||||||
stz $2101 ; Sprite register (size + address in VRAM)
|
|
||||||
stz $2102 ; Sprite registers (address of sprite memory [OAM])
|
|
||||||
stz $2103 ; "" ""
|
|
||||||
stz $2105 ; Mode 0, = Graphic mode register
|
|
||||||
stz $2106 ; noplanes, no mosaic, = Mosaic register
|
|
||||||
stz $2107 ; Plane 0 map VRAM location
|
|
||||||
stz $2108 ; Plane 1 map VRAM location
|
|
||||||
stz $2109 ; Plane 2 map VRAM location
|
|
||||||
stz $210A ; Plane 3 map VRAM location
|
|
||||||
stz $210B ; Plane 0+1 Tile data location
|
|
||||||
stz $210C ; Plane 2+3 Tile data location
|
|
||||||
stz $210D ; Plane 0 scroll x (first 8 bits)
|
|
||||||
stz $210D ; Plane 0 scroll x (last 3 bits) #$0 - #$07ff
|
|
||||||
stz $210E ; Plane 0 scroll y (first 8 bits)
|
|
||||||
stz $210E ; Plane 0 scroll y (last 3 bits) #$0 - #$07ff
|
|
||||||
stz $210F ; Plane 1 scroll x (first 8 bits)
|
|
||||||
stz $210F ; Plane 1 scroll x (last 3 bits) #$0 - #$07ff
|
|
||||||
stz $2110 ; Plane 1 scroll y (first 8 bits)
|
|
||||||
stz $2110 ; Plane 1 scroll y (last 3 bits) #$0 - #$07ff
|
|
||||||
stz $2111 ; Plane 2 scroll x (first 8 bits)
|
|
||||||
stz $2111 ; Plane 2 scroll x (last 3 bits) #$0 - #$07ff
|
|
||||||
stz $2112 ; Plane 2 scroll y (first 8 bits)
|
|
||||||
stz $2112 ; Plane 2 scroll y (last 3 bits) #$0 - #$07ff
|
|
||||||
stz $2113 ; Plane 3 scroll x (first 8 bits)
|
|
||||||
stz $2113 ; Plane 3 scroll x (last 3 bits) #$0 - #$07ff
|
|
||||||
stz $2114 ; Plane 3 scroll y (first 8 bits)
|
|
||||||
stz $2114 ; Plane 3 scroll y (last 3 bits) #$0 - #$07ff
|
|
||||||
lda #$80 ; increase VRAM address after writing to $2119
|
|
||||||
sta $2115 ; VRAM address increment register
|
|
||||||
stz $2116 ; VRAM address low
|
|
||||||
stz $2117 ; VRAM address high
|
|
||||||
stz $211A ; Initial Mode 7 setting register
|
|
||||||
stz $211B ; Mode 7 matrix parameter A register (low)
|
|
||||||
lda #$01
|
|
||||||
sta $211B ; Mode 7 matrix parameter A register (high)
|
|
||||||
stz $211C ; Mode 7 matrix parameter B register (low)
|
|
||||||
stz $211C ; Mode 7 matrix parameter B register (high)
|
|
||||||
stz $211D ; Mode 7 matrix parameter C register (low)
|
|
||||||
stz $211D ; Mode 7 matrix parameter C register (high)
|
|
||||||
stz $211E ; Mode 7 matrix parameter D register (low)
|
|
||||||
sta $211E ; Mode 7 matrix parameter D register (high)
|
|
||||||
stz $211F ; Mode 7 center position X register (low)
|
|
||||||
stz $211F ; Mode 7 center position X register (high)
|
|
||||||
stz $2120 ; Mode 7 center position Y register (low)
|
|
||||||
stz $2120 ; Mode 7 center position Y register (high)
|
|
||||||
stz $2121 ; Color number register ($0-ff)
|
|
||||||
stz $2123 ; BG1 & BG2 Window mask setting register
|
|
||||||
stz $2124 ; BG3 & BG4 Window mask setting register
|
|
||||||
stz $2125 ; OBJ & Color Window mask setting register
|
|
||||||
stz $2126 ; Window 1 left position register
|
|
||||||
stz $2127 ; Window 2 left position register
|
|
||||||
stz $2128 ; Window 3 left position register
|
|
||||||
stz $2129 ; Window 4 left position register
|
|
||||||
stz $212A ; BG1, BG2, BG3, BG4 Window Logic register
|
|
||||||
stz $212B ; OBJ, Color Window Logic Register (or,and,xor,xnor)
|
|
||||||
sta $212C ; Main Screen designation (planes, sprites enable)
|
|
||||||
stz $212D ; Sub Screen designation
|
|
||||||
stz $212E ; Window mask for Main Screen
|
|
||||||
stz $212F ; Window mask for Sub Screen
|
|
||||||
lda #$30
|
|
||||||
sta $2130 ; Color addition & screen addition init setting
|
|
||||||
stz $2131 ; Add/Sub sub designation for screen, sprite, color
|
|
||||||
lda #$E0
|
|
||||||
sta $2132 ; color data for addition/subtraction
|
|
||||||
stz $2133 ; Screen setting (interlace x,y/enable SFX data)
|
|
||||||
stz $4200 ; Enable V-blank, interrupt, Joypad register
|
|
||||||
lda #$FF
|
|
||||||
sta $4201 ; Programmable I/O port
|
|
||||||
stz $4202 ; Multiplicand A
|
|
||||||
stz $4203 ; Multiplier B
|
|
||||||
stz $4204 ; Multiplier C
|
|
||||||
stz $4205 ; Multiplicand C
|
|
||||||
stz $4206 ; Divisor B
|
|
||||||
stz $4207 ; Horizontal Count Timer
|
|
||||||
stz $4208 ; Horizontal Count Timer MSB (most significant bit)
|
|
||||||
stz $4209 ; Vertical Count Timer
|
|
||||||
stz $420A ; Vertical Count Timer MSB
|
|
||||||
stz $420B ; General DMA enable (bits 0-7)
|
|
||||||
stz $420C ; Horizontal DMA (HDMA) enable (bits 0-7)
|
|
||||||
stz $420D ; Access cycle designation (slow/fast rom)
|
|
||||||
cli ; Enable interrupts
|
|
||||||
|
|
||||||
rep #$30
|
|
||||||
longa on
|
|
||||||
longi on
|
|
||||||
|
|
||||||
jsr >_~main
|
|
||||||
brk
|
|
||||||
|
|
||||||
XDEF IRQ
|
|
||||||
IRQ:
|
|
||||||
XREF _~IRQHandler
|
|
||||||
LONGA ON
|
|
||||||
LONGI ON
|
|
||||||
rep #$30
|
|
||||||
pha
|
|
||||||
phx
|
|
||||||
phy
|
|
||||||
jsr _~IRQHandler
|
|
||||||
ply
|
|
||||||
plx
|
|
||||||
pla
|
|
||||||
rti
|
|
||||||
|
|
||||||
XDEF NMI
|
|
||||||
NMI:
|
|
||||||
XREF _~NMIHandler
|
|
||||||
LONGA ON
|
|
||||||
LONGI ON
|
|
||||||
rep #$30
|
|
||||||
pha
|
|
||||||
phx
|
|
||||||
phy
|
|
||||||
phd
|
|
||||||
phb
|
|
||||||
lda #$0000
|
|
||||||
sep #$30 ; X,Y,A are 8 bit numbers
|
|
||||||
LONGA OFF
|
|
||||||
LONGI OFF
|
|
||||||
lda $4210 ; Read NMI
|
|
||||||
LONGA ON
|
|
||||||
LONGI ON
|
|
||||||
rep #$30
|
|
||||||
jsr _~NMIHandler
|
|
||||||
plb
|
|
||||||
pld
|
|
||||||
ply
|
|
||||||
plx
|
|
||||||
pla
|
|
||||||
rti
|
|
||||||
|
|
||||||
DIRQ:
|
|
||||||
rti
|
|
||||||
|
|
||||||
ENDS
|
|
||||||
|
|
||||||
;******************************************************************************
|
|
||||||
;*** Heap definition ***
|
|
||||||
;******************************************************************************
|
|
||||||
|
|
||||||
DATA
|
|
||||||
|
|
||||||
XDEF _~heap_start
|
|
||||||
XDEF _~heap_end
|
|
||||||
|
|
||||||
_~heap_start:
|
|
||||||
WORD $1000
|
|
||||||
_~heap_end:
|
|
||||||
WORD $1200
|
|
||||||
|
|
||||||
;******************************************************************************
|
|
||||||
;*** SNES ROM Registartion Data ***
|
|
||||||
;******************************************************************************
|
|
||||||
|
|
||||||
REGISTRATION_DATA SECTION
|
|
||||||
|
|
||||||
MAKER_CODE FCC /FF/
|
|
||||||
GAME_CODE FCC /SMWJ/
|
|
||||||
FIXED_VALUE0 BYTE $00, $00, $00, $00, $00, $00, $00
|
|
||||||
EXPANSION_RAM_SIZE BYTE $00
|
|
||||||
SPECIAL_VERSION BYTE $00
|
|
||||||
CARTRIDGE_TYPE_SUB BYTE $00
|
|
||||||
GAME_TITLE FCC /GAME TITLE !/
|
|
||||||
;012345678901234567890;
|
|
||||||
MAP_MODE BYTE $20
|
|
||||||
CARTRIDGE_SIZE BYTE $00
|
|
||||||
ROM_SIZE BYTE $09
|
|
||||||
RAM_SIZE BYTE $00
|
|
||||||
DESTINATION_CODE BYTE $00
|
|
||||||
FIXED_VALUE1 BYTE $33
|
|
||||||
MASK_ROM_VERSION BYTE $00
|
|
||||||
COMPLEMENT_CHECK BYTE $00, $00
|
|
||||||
CHEKSUM BYTE $00, $00
|
|
||||||
|
|
||||||
;******************************************************************************
|
|
||||||
;*** SNES Interrupts and Reset vector ***
|
|
||||||
;******************************************************************************
|
|
||||||
|
|
||||||
VECTORS SECTION
|
|
||||||
; Native vector
|
|
||||||
N_COP DW DIRQ
|
|
||||||
N_BRK DW DIRQ
|
|
||||||
N_ABORT DW DIRQ
|
|
||||||
N_NMI DW NMI
|
|
||||||
N_RSRVD DW DIRQ
|
|
||||||
N_IRQ DW IRQ
|
|
||||||
DS 4
|
|
||||||
; Emulation vector
|
|
||||||
E_COP DW DIRQ
|
|
||||||
E_RSRVD DW DIRQ
|
|
||||||
E_ABORT DW DIRQ
|
|
||||||
E_NMI DW DIRQ
|
|
||||||
E_RESET DW START
|
|
||||||
E_IRQ DW DIRQ
|
|
||||||
|
|
||||||
END
|
|
||||||
|
|
||||||
@@ -1,37 +0,0 @@
|
|||||||
#include "data.h"
|
|
||||||
|
|
||||||
|
|
||||||
word crc_update(char far * data, word size)
|
|
||||||
{
|
|
||||||
word i;
|
|
||||||
word j;
|
|
||||||
word crc = 0;
|
|
||||||
for (j = 0; j < size; j++) {
|
|
||||||
crc = crc ^ ((word) data[j] << 8);
|
|
||||||
for (i = 0; i < 8; i++) {
|
|
||||||
if (crc & 0x8000)
|
|
||||||
crc = (crc << 1) ^ 0x1021;
|
|
||||||
else
|
|
||||||
crc <<= 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return crc;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
word crc_update_mem(unsigned long addr, word size)
|
|
||||||
{
|
|
||||||
word i;
|
|
||||||
word j;
|
|
||||||
word crc = 0;
|
|
||||||
for (j = 0; j < size; j++) {
|
|
||||||
crc = crc ^ ((word) * (byte *) (addr + j) << 8);
|
|
||||||
for (i = 0; i < 8; i++) {
|
|
||||||
if (crc & 0x8000)
|
|
||||||
crc = (crc << 1) ^ 0x1021;
|
|
||||||
else
|
|
||||||
crc <<= 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return crc;
|
|
||||||
}
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
|
|
||||||
word crc_update(byte * data, word size);
|
|
||||||
word crc_update_mem(unsigned long, word size);
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
|
|
||||||
#ifndef _DATA
|
|
||||||
|
|
||||||
typedef unsigned char byte;
|
|
||||||
typedef unsigned short word;
|
|
||||||
|
|
||||||
#define _DATA
|
|
||||||
#endif
|
|
||||||
@@ -1,224 +0,0 @@
|
|||||||
#include <string.h>
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
|
|
||||||
#include "debug.h"
|
|
||||||
#include "data.h"
|
|
||||||
#include "pad.h"
|
|
||||||
#include "PPU.h"
|
|
||||||
#include "ressource.h"
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define DEBUG_BUFFER_SIZE 128
|
|
||||||
|
|
||||||
word debugMap[0x400];
|
|
||||||
char debug_buffer[DEBUG_BUFFER_SIZE];
|
|
||||||
char screen_buffer[DEBUG_BUFFER_SIZE];
|
|
||||||
|
|
||||||
|
|
||||||
void debug_init(void)
|
|
||||||
{
|
|
||||||
word i;
|
|
||||||
for (i = 0; i < 0x400; i++) {
|
|
||||||
debugMap[i] = 0x00;
|
|
||||||
}
|
|
||||||
memset(debug_buffer, 0, DEBUG_BUFFER_SIZE);
|
|
||||||
memset(screen_buffer, 0,DEBUG_BUFFER_SIZE);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void debug_enable(void)
|
|
||||||
{
|
|
||||||
VRAMLoad((word) debugFont_pic, 0x5000, 2048);
|
|
||||||
VRAMLoad((word) debugMap, 0x4000, 0x0800);
|
|
||||||
setTileMapLocation(0x4000, (byte) 0x00, (byte) 0);
|
|
||||||
setCharacterLocation(0x5000, (byte) 0);
|
|
||||||
*(byte *) 0x2100 = 0x0f; // enable background
|
|
||||||
|
|
||||||
// Font Color
|
|
||||||
// hex(24 << 10 | 24 << 5 | 24 ) = '0x6318'
|
|
||||||
*(byte *) 0x2121 = 0x02;
|
|
||||||
*(byte *) 0x2122 = 0xff;
|
|
||||||
*(byte *) 0x2122 = 0x7f;
|
|
||||||
|
|
||||||
// Font Border Color
|
|
||||||
*(byte *) 0x2121 = 0x00;
|
|
||||||
*(byte *) 0x2122 = 0x00;
|
|
||||||
*(byte *) 0x2122 = 0x00;
|
|
||||||
|
|
||||||
// Background Color
|
|
||||||
*(byte *) 0x2121 = 0x01;
|
|
||||||
*(byte *) 0x2122 = 0x05;
|
|
||||||
*(byte *) 0x2122 = 0x29;
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void clears(void)
|
|
||||||
{
|
|
||||||
word i, y;
|
|
||||||
for (y = 0; y < 20; y++) {
|
|
||||||
waitForVBlank();
|
|
||||||
for (i = 0; i < 32; i++) {
|
|
||||||
*(byte *) 0x2115 = 0x80;
|
|
||||||
*(word *) 0x2116 = 0x4000 + i + (y * 0x20);
|
|
||||||
*(byte *) 0x2118 = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void _print_char(word y, word x, char c)
|
|
||||||
{
|
|
||||||
waitForVBlank();
|
|
||||||
VRAMByteWrite((byte) (c - 32), (word) (0x4000 + x + (y * 0x20)));
|
|
||||||
}
|
|
||||||
|
|
||||||
void _print_screen(word y, char *buffer)
|
|
||||||
{
|
|
||||||
char l;
|
|
||||||
unsigned int x;
|
|
||||||
x = y * 0x20;
|
|
||||||
l = strlen(buffer);
|
|
||||||
waitForVBlank();
|
|
||||||
while (*buffer) {
|
|
||||||
if (*buffer == '\n') {
|
|
||||||
while (x++ < 32) {
|
|
||||||
*(byte *) 0x2115 = 0x80;
|
|
||||||
*(word *) 0x2116 = 0x4000 + x + (y * 0x20);
|
|
||||||
*(byte *) 0x2118 = 0;
|
|
||||||
}
|
|
||||||
x = 0;
|
|
||||||
y += 0x20;
|
|
||||||
buffer++;
|
|
||||||
waitForVBlank();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
*(byte *) 0x2115 = 0x80;
|
|
||||||
*(word *) 0x2116 = 0x4000 + x;
|
|
||||||
*(byte *) 0x2118 = *buffer - 32;
|
|
||||||
x++;
|
|
||||||
buffer++;
|
|
||||||
#if 1
|
|
||||||
waitForVBlank();
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
void _print_console(const char *buffer)
|
|
||||||
{
|
|
||||||
while (*buffer)
|
|
||||||
*(byte *) 0x3000 = *buffer++;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void printfc(const char *fmt, ...)
|
|
||||||
{
|
|
||||||
va_list ap;
|
|
||||||
va_start(ap, fmt);
|
|
||||||
vsprintf(debug_buffer, fmt, ap);
|
|
||||||
va_end(ap);
|
|
||||||
_print_console(debug_buffer);
|
|
||||||
//memset(debug_buffer,0,DEBUG_BUFFER_SIZE);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void printfs(word y, const char *fmt, ...)
|
|
||||||
{
|
|
||||||
va_list ap;
|
|
||||||
va_start(ap, fmt);
|
|
||||||
vsprintf(screen_buffer, fmt, ap);
|
|
||||||
va_end(ap);
|
|
||||||
_print_screen(y, screen_buffer);
|
|
||||||
//memset(screen_buffer, 0, DEBUG_BUFFER_SIZE);
|
|
||||||
}
|
|
||||||
|
|
||||||
void printc_packet(unsigned long addr, unsigned int len, byte * packet)
|
|
||||||
{
|
|
||||||
unsigned int i, j;
|
|
||||||
unsigned int sum = 0;
|
|
||||||
unsigned int last_sum = 0;
|
|
||||||
unsigned int clear = 0;
|
|
||||||
|
|
||||||
for (i = 0; i < len; i += 16) {
|
|
||||||
|
|
||||||
sum = 0;
|
|
||||||
for (j = 0; j < 16; j++) {
|
|
||||||
sum += packet[i + j];
|
|
||||||
}
|
|
||||||
if (!sum) {
|
|
||||||
clear = 1;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (last_sum == sum) {
|
|
||||||
clear = 1;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (clear) {
|
|
||||||
printfc("*\n");
|
|
||||||
clear = 0;
|
|
||||||
}
|
|
||||||
printfc("%06lX:", addr + i);
|
|
||||||
for (j = 0; j < 16; j++) {
|
|
||||||
printfc(" %02x", packet[i + j]);
|
|
||||||
}
|
|
||||||
printfc(" |");
|
|
||||||
for (j = 0; j < 16; j++) {
|
|
||||||
if (packet[i + j] >= 33 && packet[i + j] <= 126)
|
|
||||||
printfc("%c", packet[i + j]);
|
|
||||||
else
|
|
||||||
printfc(".");
|
|
||||||
}
|
|
||||||
printfc("|\n");
|
|
||||||
last_sum = sum;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
* keep the linker happy
|
|
||||||
*/
|
|
||||||
int open(const char *_name, int _mode)
|
|
||||||
{
|
|
||||||
_print_console("open called\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int close(int fd)
|
|
||||||
{
|
|
||||||
_print_console("close called\n");
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t read(int fd, void *buff, size_t len)
|
|
||||||
{
|
|
||||||
_print_console("read called\n");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t write(int fd, void *buffer, size_t len)
|
|
||||||
{
|
|
||||||
_print_console("write called\n");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
long lseek(int fd, long off, int count)
|
|
||||||
{
|
|
||||||
_print_console("lseek called\n");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int unlink(const char *name)
|
|
||||||
{
|
|
||||||
_print_console("unlink called\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int isatty()
|
|
||||||
{
|
|
||||||
_print_console("isatty called\n");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
#include "data.h"
|
|
||||||
|
|
||||||
void debug_init(void);
|
|
||||||
void debug_enable(void);
|
|
||||||
void printfs(word y, const char *fmt, ...);
|
|
||||||
void printfc(const char *fmt, ...);
|
|
||||||
void clears(void);
|
|
||||||
void printc_packet(unsigned long addr, unsigned int len, byte * packet);
|
|
||||||
@@ -1,106 +0,0 @@
|
|||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
#include "data.h";
|
|
||||||
#include "event.h";
|
|
||||||
|
|
||||||
event *events;
|
|
||||||
|
|
||||||
void initEvents(void)
|
|
||||||
{
|
|
||||||
events = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
event *createEvent(char (*callback) (word counter))
|
|
||||||
{
|
|
||||||
event *myEvent;
|
|
||||||
|
|
||||||
myEvent = (event *) malloc(sizeof(event));
|
|
||||||
|
|
||||||
myEvent->VBlankCount = 0;
|
|
||||||
myEvent->callback = callback;
|
|
||||||
myEvent->nextEvent = NULL;
|
|
||||||
myEvent->previousEvent = NULL;
|
|
||||||
|
|
||||||
|
|
||||||
return myEvent;
|
|
||||||
}
|
|
||||||
|
|
||||||
event *addEvent(char (*callback) (word counter), int noDuplicateCallback)
|
|
||||||
{
|
|
||||||
|
|
||||||
event *lastEvent;
|
|
||||||
event *myEvent;
|
|
||||||
|
|
||||||
if (events == NULL) {
|
|
||||||
events = createEvent(callback);
|
|
||||||
return events;
|
|
||||||
} else {
|
|
||||||
lastEvent = events;
|
|
||||||
// TODO optimise this with noduplicate
|
|
||||||
while (lastEvent->nextEvent != NULL) {
|
|
||||||
if (noDuplicateCallback == 1 && lastEvent->callback == *callback) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
lastEvent = lastEvent->nextEvent;
|
|
||||||
}
|
|
||||||
if (noDuplicateCallback == 1 && lastEvent->callback == *callback) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
myEvent = createEvent(callback);
|
|
||||||
myEvent->previousEvent = lastEvent;
|
|
||||||
lastEvent->nextEvent = myEvent;
|
|
||||||
return myEvent;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void removeEvent(event * eventElement)
|
|
||||||
{
|
|
||||||
|
|
||||||
byte alone = 0;
|
|
||||||
event *next, *previous;
|
|
||||||
|
|
||||||
next = eventElement->nextEvent;
|
|
||||||
previous = eventElement->previousEvent;
|
|
||||||
|
|
||||||
if (eventElement->nextEvent != NULL && eventElement->previousEvent != NULL) {
|
|
||||||
alone++;
|
|
||||||
next->previousEvent = previous;
|
|
||||||
previous->nextEvent = next;
|
|
||||||
|
|
||||||
} else if (eventElement->nextEvent != NULL) {
|
|
||||||
alone++;
|
|
||||||
next->previousEvent = NULL;
|
|
||||||
events = next;
|
|
||||||
|
|
||||||
} else if (eventElement->previousEvent != NULL) {
|
|
||||||
alone++;
|
|
||||||
previous->nextEvent = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
free(eventElement);
|
|
||||||
|
|
||||||
if (alone == 0) {
|
|
||||||
events = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void processEvents(void)
|
|
||||||
{
|
|
||||||
|
|
||||||
event *currentEvent;
|
|
||||||
char returnValue;
|
|
||||||
|
|
||||||
currentEvent = events;
|
|
||||||
while (currentEvent != NULL) {
|
|
||||||
returnValue = currentEvent->callback(currentEvent->VBlankCount);
|
|
||||||
if (returnValue == EVENT_CONTINUE) {
|
|
||||||
currentEvent->VBlankCount++;
|
|
||||||
} else {
|
|
||||||
removeEvent(currentEvent);
|
|
||||||
}
|
|
||||||
currentEvent = currentEvent->nextEvent;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
typedef struct event {
|
|
||||||
word VBlankCount;
|
|
||||||
char (*callback) (word counter);
|
|
||||||
struct event *previousEvent;
|
|
||||||
struct event *nextEvent;
|
|
||||||
} event;
|
|
||||||
|
|
||||||
#define EVENT_STOP 0
|
|
||||||
#define EVENT_CONTINUE 1
|
|
||||||
|
|
||||||
extern event *events;
|
|
||||||
|
|
||||||
void initEvents(void);
|
|
||||||
extern event *addEvent(char (*callback) (word counter),
|
|
||||||
int noDuplicateCallback);
|
|
||||||
extern void removeEvent(event * eventElement);
|
|
||||||
extern void processEvents(void);
|
|
||||||
@@ -1,48 +0,0 @@
|
|||||||
/*-------------------------------------------*/
|
|
||||||
/*
|
|
||||||
* Integer type definitions for FatFs module
|
|
||||||
*/
|
|
||||||
/*-------------------------------------------*/
|
|
||||||
|
|
||||||
#ifndef _INTEGER
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* These types must be 16-bit, 32-bit or larger integer
|
|
||||||
*/
|
|
||||||
typedef int INT;
|
|
||||||
typedef unsigned int UINT;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* These types must be 8-bit integer
|
|
||||||
*/
|
|
||||||
typedef signed char CHAR;
|
|
||||||
typedef unsigned char UCHAR;
|
|
||||||
typedef unsigned char BYTE;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* These types must be 16-bit integer
|
|
||||||
*/
|
|
||||||
typedef short SHORT;
|
|
||||||
typedef unsigned short USHORT;
|
|
||||||
typedef unsigned short WORD;
|
|
||||||
typedef unsigned short WCHAR;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* These types must be 32-bit integer
|
|
||||||
*/
|
|
||||||
typedef long LONG;
|
|
||||||
typedef unsigned long ULONG;
|
|
||||||
typedef unsigned long DWORD;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Boolean type
|
|
||||||
*/
|
|
||||||
// enum { false = 0 , true } bool;
|
|
||||||
|
|
||||||
//typedef int BOOL;
|
|
||||||
#define FALSE 0
|
|
||||||
#define TRUE 1
|
|
||||||
|
|
||||||
#define _INTEGER
|
|
||||||
#endif
|
|
||||||
@@ -1,93 +0,0 @@
|
|||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <time.h>
|
|
||||||
|
|
||||||
#include "data.h";
|
|
||||||
#include "pad.h";
|
|
||||||
#include "event.h";
|
|
||||||
#include "myEvents.h";
|
|
||||||
#include "ressource.h";
|
|
||||||
#include "PPU.h"
|
|
||||||
#include "debug.h"
|
|
||||||
#include "integer.h"
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
typedef void (*FUNC) (void);
|
|
||||||
|
|
||||||
padStatus pad1;
|
|
||||||
|
|
||||||
void initInternalRegisters(void)
|
|
||||||
{
|
|
||||||
characterLocation[0] = 0x0000;
|
|
||||||
characterLocation[1] = 0x0000;
|
|
||||||
characterLocation[2] = 0x0000;
|
|
||||||
characterLocation[3] = 0x0000;
|
|
||||||
debug_init();
|
|
||||||
}
|
|
||||||
|
|
||||||
void preInit(void)
|
|
||||||
{
|
|
||||||
|
|
||||||
// For testing purpose ...
|
|
||||||
// Insert code here to be executed before register init
|
|
||||||
}
|
|
||||||
|
|
||||||
void halt(void)
|
|
||||||
{
|
|
||||||
while (1);
|
|
||||||
}
|
|
||||||
|
|
||||||
void wait(void)
|
|
||||||
{
|
|
||||||
printfc("SNES::wait: press A to continue\n");
|
|
||||||
enablePad();
|
|
||||||
pad1 = readPad((byte) 0);
|
|
||||||
while (!pad1.A) {
|
|
||||||
waitForVBlank();
|
|
||||||
pad1 = readPad((byte) 0);
|
|
||||||
}
|
|
||||||
printfc("SNES::wait: done\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
void boot(DWORD addr)
|
|
||||||
{
|
|
||||||
FUNC fn;
|
|
||||||
//printfc("SNES::boot addr=%lx\n", addr);
|
|
||||||
fn = (FUNC) addr;
|
|
||||||
fn();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned char i;
|
|
||||||
unsigned char j;
|
|
||||||
|
|
||||||
void main(void)
|
|
||||||
{
|
|
||||||
initInternalRegisters();
|
|
||||||
*(byte *) 0x2105 = 0x01; // MODE 1 value
|
|
||||||
*(byte *) 0x212c = 0x01; // Plane 0 (bit one) enable register
|
|
||||||
*(byte *) 0x212d = 0x00; // All subPlane disable
|
|
||||||
*(byte *) 0x2100 = 0x0f; // enable background
|
|
||||||
|
|
||||||
debug_enable();
|
|
||||||
i=0;
|
|
||||||
j=0;
|
|
||||||
while (1) {
|
|
||||||
printfs(0,"IRQ COUNT %i", i);
|
|
||||||
printfs(1,"NMI COUNT %i", j++);
|
|
||||||
waitForVBlank();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void IRQHandler(void)
|
|
||||||
{
|
|
||||||
i = i + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void NMIHandler(void)
|
|
||||||
{
|
|
||||||
|
|
||||||
// processEvents();
|
|
||||||
}
|
|
||||||
@@ -1,103 +0,0 @@
|
|||||||
#include "data.h";
|
|
||||||
#include "pad.h";
|
|
||||||
#include "event.h";
|
|
||||||
|
|
||||||
extern padStatus pad1;
|
|
||||||
extern word scrollValue;
|
|
||||||
|
|
||||||
char fadeOut(word counter)
|
|
||||||
{
|
|
||||||
static byte fadeOutValue;
|
|
||||||
|
|
||||||
if (counter == 0) {
|
|
||||||
// init fade value
|
|
||||||
fadeOutValue = 0x0f;
|
|
||||||
} else {
|
|
||||||
fadeOutValue--;
|
|
||||||
}
|
|
||||||
|
|
||||||
*(byte *) 0x2100 = fadeOutValue;
|
|
||||||
|
|
||||||
if (fadeOutValue == 0x00) {
|
|
||||||
return EVENT_STOP;
|
|
||||||
} else {
|
|
||||||
return EVENT_CONTINUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
char fadeIn(word counter)
|
|
||||||
{
|
|
||||||
static byte fadeInValue;
|
|
||||||
|
|
||||||
if (counter == 0) {
|
|
||||||
// init fade value
|
|
||||||
fadeInValue = 0x00;
|
|
||||||
} else {
|
|
||||||
fadeInValue++;
|
|
||||||
}
|
|
||||||
|
|
||||||
*(byte *) 0x2100 = fadeInValue;
|
|
||||||
|
|
||||||
if (fadeInValue >= 0x0f) {
|
|
||||||
return EVENT_STOP;
|
|
||||||
} else {
|
|
||||||
return EVENT_CONTINUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
char mosaicOut(word counter)
|
|
||||||
{
|
|
||||||
static byte mosaicOutValue;
|
|
||||||
|
|
||||||
if (counter == 0) {
|
|
||||||
// init fade value
|
|
||||||
mosaicOutValue = 0xff;
|
|
||||||
} else {
|
|
||||||
mosaicOutValue -= 0x10;
|
|
||||||
}
|
|
||||||
|
|
||||||
*(byte *) 0x2106 = mosaicOutValue;
|
|
||||||
|
|
||||||
if (mosaicOutValue == 0x0f) {
|
|
||||||
return EVENT_STOP;
|
|
||||||
} else {
|
|
||||||
return EVENT_CONTINUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
char mosaicIn(word counter)
|
|
||||||
{
|
|
||||||
static byte mosaicInValue;
|
|
||||||
|
|
||||||
if (counter == 0) {
|
|
||||||
// init fade value
|
|
||||||
mosaicInValue = 0x0f;
|
|
||||||
} else {
|
|
||||||
mosaicInValue += 0x10;
|
|
||||||
}
|
|
||||||
|
|
||||||
*(byte *) 0x2106 = mosaicInValue;
|
|
||||||
|
|
||||||
if (mosaicInValue == 0xff) {
|
|
||||||
return EVENT_STOP;
|
|
||||||
} else {
|
|
||||||
return EVENT_CONTINUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
char NMIReadPad(word counter)
|
|
||||||
{
|
|
||||||
pad1 = readPad((byte) 0);
|
|
||||||
|
|
||||||
return EVENT_CONTINUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
char scrollLeft(word counter)
|
|
||||||
{
|
|
||||||
scrollValue++;
|
|
||||||
|
|
||||||
*(byte *) 0x210d = (byte) scrollValue;
|
|
||||||
*(byte *) 0x210d = (byte) (scrollValue >> 8);
|
|
||||||
|
|
||||||
return EVENT_CONTINUE;
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
char fadeOut(word counter);
|
|
||||||
char fadeIn(word counter);
|
|
||||||
char mosaicOut(word counter);
|
|
||||||
char mosaicIn(word counter);
|
|
||||||
char NMIReadPad(word counter);
|
|
||||||
char scrollLeft(word counter);
|
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
#include "data.h";
|
|
||||||
#include "pad.h";
|
|
||||||
#include "debug.h";
|
|
||||||
|
|
||||||
void enablePad(void)
|
|
||||||
{
|
|
||||||
// Enable pad reading and NMI
|
|
||||||
*(byte *) 0x4200 = 0x01;
|
|
||||||
}
|
|
||||||
|
|
||||||
void disablePad(void)
|
|
||||||
{
|
|
||||||
// Enable pad reading and NMI
|
|
||||||
*(byte *) 0x4200 = 0x00;
|
|
||||||
}
|
|
||||||
|
|
||||||
padStatus readPad(byte padNumber)
|
|
||||||
{
|
|
||||||
word test;
|
|
||||||
padStatus *status;
|
|
||||||
padNumber = padNumber << 1;
|
|
||||||
test = (word) * (byte *) 0x4218 + padNumber << 8;
|
|
||||||
test |= (word) * (byte *) 0x4219 + padNumber;
|
|
||||||
status = (padStatus *) & test;
|
|
||||||
return *status;
|
|
||||||
}
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
typedef struct padStatus {
|
|
||||||
byte right:1;
|
|
||||||
byte left:1;
|
|
||||||
byte down:1;
|
|
||||||
byte up:1;
|
|
||||||
byte start:1; // Enter
|
|
||||||
byte select:1; // Space
|
|
||||||
byte Y:1; // X
|
|
||||||
byte B:1; // C
|
|
||||||
// --------------------------------
|
|
||||||
byte Dummy:4;
|
|
||||||
byte R:1; // Z
|
|
||||||
byte L:1; // A
|
|
||||||
byte X:1; // S
|
|
||||||
byte A:1; // D
|
|
||||||
} padStatus;
|
|
||||||
|
|
||||||
extern void enablePad(void);
|
|
||||||
extern void disablePad(void);
|
|
||||||
extern padStatus readPad(byte padNumber);
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
ressource .section
|
|
||||||
|
|
||||||
|
|
||||||
XDEF _~debugFont_pic
|
|
||||||
_~debugFont_pic
|
|
||||||
INSERT ressource/debugFont.pic
|
|
||||||
|
|
||||||
|
|
||||||
.ends
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
|
|
||||||
extern word debugFont_pic[];
|
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,36 +0,0 @@
|
|||||||
import binascii
|
|
||||||
data = open("rom.smc","r").read()
|
|
||||||
data = binascii.rlecode_hqx(data)
|
|
||||||
|
|
||||||
cfile = open("loader.c","w")
|
|
||||||
hfile = open("loader.h","w")
|
|
||||||
|
|
||||||
hfile.write('''
|
|
||||||
#ifndef __FIFO_H__
|
|
||||||
#define __FIFO_H__
|
|
||||||
|
|
||||||
#define ROM_SIZE %i
|
|
||||||
|
|
||||||
#endif
|
|
||||||
''' % len(data))
|
|
||||||
|
|
||||||
cfile.write('''
|
|
||||||
|
|
||||||
#include <avr/pgmspace.h>
|
|
||||||
#include <loader.h>
|
|
||||||
|
|
||||||
const char _rom[ROM_SIZE] PROGMEM = {
|
|
||||||
''')
|
|
||||||
|
|
||||||
for idx,c in enumerate(data):
|
|
||||||
c = ord(c)
|
|
||||||
if idx<len(data)-1:
|
|
||||||
cfile.write("0x%02x," % c)
|
|
||||||
else:
|
|
||||||
cfile.write("0x%02x" % c)
|
|
||||||
if idx and idx%16==0:
|
|
||||||
cfile.write("\n")
|
|
||||||
cfile.write('''
|
|
||||||
};
|
|
||||||
''')
|
|
||||||
cfile.close()
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,7 +0,0 @@
|
|||||||
|
|
||||||
#ifndef __FIFO_H__
|
|
||||||
#define __FIFO_H__
|
|
||||||
|
|
||||||
#define ROM_SIZE 30346
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
# 65816 stuff
|
|
||||||
AC = wla-65816
|
|
||||||
AFLAGS = -o
|
|
||||||
LD = wlalink
|
|
||||||
LDFLAGS = -vsr
|
|
||||||
FL = snesflash
|
|
||||||
FLFLAGS = -wf
|
|
||||||
UCON = ucon64
|
|
||||||
UCONFLAGS = --port=usb --xsnesram
|
|
||||||
SFILES = main.asm
|
|
||||||
OFILES = $(SFILES:.asm=.o)
|
|
||||||
ROMFILE = main.smc
|
|
||||||
EMU = zsnes
|
|
||||||
# spc stuff
|
|
||||||
SPCAC = wla-spc700
|
|
||||||
SPCSFILES = data/apu/apucode.asm
|
|
||||||
SPCOFILES = $(SPCSFILES:.asm=.o)
|
|
||||||
SPCFILE = $(SPCSFILES:.asm=.bin)
|
|
||||||
|
|
||||||
|
|
||||||
all:
|
|
||||||
mv -v main.smc main.smc.last
|
|
||||||
wget http://dforce3000.de/main.smc
|
|
||||||
python ../../scripts/conv_rle.py main.smc
|
|
||||||
957
todo.sh
957
todo.sh
@@ -1,957 +0,0 @@
|
|||||||
#! /bin/bash
|
|
||||||
|
|
||||||
# NOTE: Todo.sh requires the .todo/config configuration file to run.
|
|
||||||
# Place the .todo/config file in your home directory or use the -d option for a custom location.
|
|
||||||
|
|
||||||
# Your todo/done/report.txt locations
|
|
||||||
export TODO_DIR=$(pwd)
|
|
||||||
export TODO_FILE="$TODO_DIR/todo.txt"
|
|
||||||
export DONE_FILE="$TODO_DIR/done.txt"
|
|
||||||
export REPORT_FILE="$TODO_DIR/report.txt"
|
|
||||||
export TMP_FILE="$TODO_DIR/todo.tmp"
|
|
||||||
|
|
||||||
[ -f VERSION-FILE ] && . VERSION-FILE || VERSION="@DEV_VERSION@"
|
|
||||||
version() { sed -e 's/^ //' <<EndVersion
|
|
||||||
TODO.TXT Command Line Interface v$VERSION
|
|
||||||
|
|
||||||
First release: 5/11/2006
|
|
||||||
Original conception by: Gina Trapani (http://ginatrapani.org)
|
|
||||||
Contributors: http://github.com/ginatrapani/todo.txt-cli/network
|
|
||||||
License: GPL, http://www.gnu.org/copyleft/gpl.html
|
|
||||||
More information and mailing list at http://todotxt.com
|
|
||||||
Code repository: http://github.com/ginatrapani/todo.txt-cli/tree/master
|
|
||||||
EndVersion
|
|
||||||
exit 1
|
|
||||||
}
|
|
||||||
|
|
||||||
# Set script name early.
|
|
||||||
TODO_SH=$(basename "$0")
|
|
||||||
export TODO_SH
|
|
||||||
|
|
||||||
oneline_usage="$TODO_SH [-fhpantvV] [-d todo_config] action [task_number] [task_description]"
|
|
||||||
|
|
||||||
usage()
|
|
||||||
{
|
|
||||||
sed -e 's/^ //' <<EndUsage
|
|
||||||
Usage: $oneline_usage
|
|
||||||
Try '$TODO_SH -h' for more information.
|
|
||||||
EndUsage
|
|
||||||
exit 1
|
|
||||||
}
|
|
||||||
|
|
||||||
shorthelp()
|
|
||||||
{
|
|
||||||
sed -e 's/^ //' <<EndHelp
|
|
||||||
Usage: $oneline_usage
|
|
||||||
|
|
||||||
Actions:
|
|
||||||
add|a "THING I NEED TO DO +project @context"
|
|
||||||
addto DEST "TEXT TO ADD"
|
|
||||||
append|app NUMBER "TEXT TO APPEND"
|
|
||||||
archive
|
|
||||||
command [ACTIONS]
|
|
||||||
del|rm NUMBER [TERM]
|
|
||||||
dp|depri NUMBER
|
|
||||||
do NUMBER
|
|
||||||
help
|
|
||||||
list|ls [TERM...]
|
|
||||||
listall|lsa [TERM...]
|
|
||||||
listcon|lsc
|
|
||||||
listfile|lf SRC [TERM...]
|
|
||||||
listpri|lsp [PRIORITY]
|
|
||||||
listproj|lsprj
|
|
||||||
move|mv NUMBER DEST [SRC]
|
|
||||||
prepend|prep NUMBER "TEXT TO PREPEND"
|
|
||||||
pri|p NUMBER PRIORITY
|
|
||||||
replace NUMBER "UPDATED TODO"
|
|
||||||
report
|
|
||||||
|
|
||||||
See "help" for more details.
|
|
||||||
EndHelp
|
|
||||||
exit 0
|
|
||||||
}
|
|
||||||
|
|
||||||
help()
|
|
||||||
{
|
|
||||||
sed -e 's/^ //' <<EndHelp
|
|
||||||
Usage: $oneline_usage
|
|
||||||
|
|
||||||
Actions:
|
|
||||||
add "THING I NEED TO DO +project @context"
|
|
||||||
a "THING I NEED TO DO +project @context"
|
|
||||||
Adds THING I NEED TO DO to your todo.txt file on its own line.
|
|
||||||
Project and context notation optional.
|
|
||||||
Quotes optional.
|
|
||||||
|
|
||||||
addto DEST "TEXT TO ADD"
|
|
||||||
Adds a line of text to any file located in the todo.txt directory.
|
|
||||||
For example, addto inbox.txt "decide about vacation"
|
|
||||||
|
|
||||||
append NUMBER "TEXT TO APPEND"
|
|
||||||
app NUMBER "TEXT TO APPEND"
|
|
||||||
Adds TEXT TO APPEND to the end of the todo on line NUMBER.
|
|
||||||
Quotes optional.
|
|
||||||
|
|
||||||
archive
|
|
||||||
Moves done items from todo.txt to done.txt and removes blank lines.
|
|
||||||
|
|
||||||
command [ACTIONS]
|
|
||||||
Runs the remaining arguments using only todo.sh builtins.
|
|
||||||
Will not call any .todo.actions.d scripts.
|
|
||||||
|
|
||||||
del NUMBER [TERM]
|
|
||||||
rm NUMBER [TERM]
|
|
||||||
Deletes the item on line NUMBER in todo.txt.
|
|
||||||
If term specified, deletes only the term from the line.
|
|
||||||
|
|
||||||
depri NUMBER
|
|
||||||
dp NUMBER
|
|
||||||
Deprioritizes (removes the priority) from the item
|
|
||||||
on line NUMBER in todo.txt.
|
|
||||||
|
|
||||||
do NUMBER[, NUMBER, NUMBER, ...]
|
|
||||||
Marks item(s) on line NUMBER as done in todo.txt.
|
|
||||||
|
|
||||||
help
|
|
||||||
Display this help message.
|
|
||||||
|
|
||||||
list [TERM...]
|
|
||||||
ls [TERM...]
|
|
||||||
Displays all todo's that contain TERM(s) sorted by priority with line
|
|
||||||
numbers. If no TERM specified, lists entire todo.txt.
|
|
||||||
|
|
||||||
listall [TERM...]
|
|
||||||
lsa [TERM...]
|
|
||||||
Displays all the lines in todo.txt AND done.txt that contain TERM(s)
|
|
||||||
sorted by priority with line numbers. If no TERM specified, lists
|
|
||||||
entire todo.txt AND done.txt concatenated and sorted.
|
|
||||||
|
|
||||||
listcon
|
|
||||||
lsc
|
|
||||||
Lists all the task contexts that start with the @ sign in todo.txt.
|
|
||||||
|
|
||||||
listfile SRC [TERM...]
|
|
||||||
lf SRC [TERM...]
|
|
||||||
Displays all the lines in SRC file located in the todo.txt directory,
|
|
||||||
sorted by priority with line numbers. If TERM specified, lists
|
|
||||||
all lines that contain TERM in SRC file.
|
|
||||||
|
|
||||||
listpri [PRIORITY]
|
|
||||||
lsp [PRIORITY]
|
|
||||||
Displays all items prioritized PRIORITY.
|
|
||||||
If no PRIORITY specified, lists all prioritized items.
|
|
||||||
|
|
||||||
listproj
|
|
||||||
lsprj
|
|
||||||
Lists all the projects that start with the + sign in todo.txt.
|
|
||||||
|
|
||||||
move NUMBER DEST [SRC]
|
|
||||||
mv NUMBER DEST [SRC]
|
|
||||||
Moves a line from source text file (SRC) to destination text file (DEST).
|
|
||||||
Both source and destination file must be located in the directory defined
|
|
||||||
in the configuration directory. When SRC is not defined
|
|
||||||
it's by default todo.txt.
|
|
||||||
|
|
||||||
prepend NUMBER "TEXT TO PREPEND"
|
|
||||||
prep NUMBER "TEXT TO PREPEND"
|
|
||||||
Adds TEXT TO PREPEND to the beginning of the todo on line NUMBER.
|
|
||||||
Quotes optional.
|
|
||||||
|
|
||||||
pri NUMBER PRIORITY
|
|
||||||
p NUMBER PRIORITY
|
|
||||||
Adds PRIORITY to todo on line NUMBER. If the item is already
|
|
||||||
prioritized, replaces current priority with new PRIORITY.
|
|
||||||
PRIORITY must be an uppercase letter between A and Z.
|
|
||||||
|
|
||||||
replace NUMBER "UPDATED TODO"
|
|
||||||
Replaces todo on line NUMBER with UPDATED TODO.
|
|
||||||
|
|
||||||
report
|
|
||||||
Adds the number of open todo's and closed done's to report.txt.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Options:
|
|
||||||
-@
|
|
||||||
Hide context names in list output. Use twice to show context
|
|
||||||
names (default).
|
|
||||||
-+
|
|
||||||
Hide project names in list output. Use twice to show project
|
|
||||||
names (default).
|
|
||||||
-d CONFIG_FILE
|
|
||||||
Use a configuration file other than the default ~/.todo/config
|
|
||||||
-f
|
|
||||||
Forces actions without confirmation or interactive input
|
|
||||||
-h
|
|
||||||
Display a short help message
|
|
||||||
-p
|
|
||||||
Plain mode turns off colors
|
|
||||||
-P
|
|
||||||
Hide priority labels in list output. Use twice to show
|
|
||||||
priority labels (default).
|
|
||||||
-a
|
|
||||||
Don't auto-archive tasks automatically on completion
|
|
||||||
-n
|
|
||||||
Don't preserve line numbers; automatically remove blank lines
|
|
||||||
on task deletion
|
|
||||||
-t
|
|
||||||
Prepend the current date to a task automatically
|
|
||||||
when it's added.
|
|
||||||
-v
|
|
||||||
Verbose mode turns on confirmation messages
|
|
||||||
-vv
|
|
||||||
Extra verbose mode prints some debugging information
|
|
||||||
-V
|
|
||||||
Displays version, license and credits
|
|
||||||
|
|
||||||
|
|
||||||
Environment variables:
|
|
||||||
TODOTXT_AUTO_ARCHIVE=0 is same as option -a
|
|
||||||
TODOTXT_CFG_FILE=CONFIG_FILE is same as option -d CONFIG_FILE
|
|
||||||
TODOTXT_FORCE=1 is same as option -f
|
|
||||||
TODOTXT_PRESERVE_LINE_NUMBERS=0 is same as option -n
|
|
||||||
TODOTXT_PLAIN=1 is same as option -p
|
|
||||||
TODOTXT_DATE_ON_ADD=1 is same as option -t
|
|
||||||
TODOTXT_VERBOSE=1 is same as option -v
|
|
||||||
TODOTXT_DEFAULT_ACTION="" run this when called with no arguments
|
|
||||||
TODOTXT_SORT_COMMAND="sort ..." customize list output
|
|
||||||
TODOTXT_FINAL_FILTER="sed ..." customize list after color, P@+ hiding
|
|
||||||
EndHelp
|
|
||||||
|
|
||||||
if [ -d "$TODO_ACTIONS_DIR" ]
|
|
||||||
then
|
|
||||||
echo ""
|
|
||||||
for action in "$TODO_ACTIONS_DIR"/*
|
|
||||||
do
|
|
||||||
if [ -x "$action" ]
|
|
||||||
then
|
|
||||||
"$action" usage
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
echo ""
|
|
||||||
fi
|
|
||||||
|
|
||||||
|
|
||||||
exit 1
|
|
||||||
}
|
|
||||||
|
|
||||||
die()
|
|
||||||
{
|
|
||||||
echo "$*"
|
|
||||||
exit 1
|
|
||||||
}
|
|
||||||
|
|
||||||
cleanup()
|
|
||||||
{
|
|
||||||
[ -f "$TMP_FILE" ] && rm "$TMP_FILE"
|
|
||||||
exit 0
|
|
||||||
}
|
|
||||||
|
|
||||||
archive()
|
|
||||||
{
|
|
||||||
#defragment blank lines
|
|
||||||
sed -i.bak -e '/./!d' "$TODO_FILE"
|
|
||||||
[ $TODOTXT_VERBOSE -gt 0 ] && grep "^x " "$TODO_FILE"
|
|
||||||
grep "^x " "$TODO_FILE" >> "$DONE_FILE"
|
|
||||||
sed -i.bak '/^x /d' "$TODO_FILE"
|
|
||||||
cp "$TODO_FILE" "$TMP_FILE"
|
|
||||||
sed -n 'G; s/\n/&&/; /^\([ ~-]*\n\).*\n\1/d; s/\n//; h; P' "$TMP_FILE" > "$TODO_FILE"
|
|
||||||
#[[ $TODOTXT_VERBOSE -gt 0 ]] && echo "TODO: Duplicate tasks have been removed."
|
|
||||||
[ $TODOTXT_VERBOSE -gt 0 ] && echo "TODO: $TODO_FILE archived."
|
|
||||||
cleanup
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
# == PROCESS OPTIONS ==
|
|
||||||
while getopts ":fhpnatvV+@Pd:" Option
|
|
||||||
do
|
|
||||||
case $Option in
|
|
||||||
'@' )
|
|
||||||
## HIDE_CONTEXT_NAMES starts at zero (false); increment it to one
|
|
||||||
## (true) the first time this flag is seen. Each time the flag
|
|
||||||
## is seen after that, increment it again so that an even
|
|
||||||
## number hides project names and an odd number shows project
|
|
||||||
## names.
|
|
||||||
: $(( HIDE_CONTEXT_NAMES++ ))
|
|
||||||
if [ $(( $HIDE_CONTEXT_NAMES % 2 )) -eq 0 ]
|
|
||||||
then
|
|
||||||
## Zero or even value -- show context names
|
|
||||||
unset HIDE_CONTEXTS_SUBSTITUTION
|
|
||||||
else
|
|
||||||
## One or odd value -- hide context names
|
|
||||||
export HIDE_CONTEXTS_SUBSTITUTION='[[:space:]]@[^[:space:]]\{1,\}'
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
'+' )
|
|
||||||
## HIDE_PROJECT_NAMES starts at zero (false); increment it to one
|
|
||||||
## (true) the first time this flag is seen. Each time the flag
|
|
||||||
## is seen after that, increment it again so that an even
|
|
||||||
## number hides project names and an odd number shows project
|
|
||||||
## names.
|
|
||||||
: $(( HIDE_PROJECT_NAMES++ ))
|
|
||||||
if [ $(( $HIDE_PROJECT_NAMES % 2 )) -eq 0 ]
|
|
||||||
then
|
|
||||||
## Zero or even value -- show project names
|
|
||||||
unset HIDE_PROJECTS_SUBSTITUTION
|
|
||||||
else
|
|
||||||
## One or odd value -- hide project names
|
|
||||||
export HIDE_PROJECTS_SUBSTITUTION='[[:space:]][+][^[:space:]]\{1,\}'
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
a )
|
|
||||||
TODOTXT_AUTO_ARCHIVE=0
|
|
||||||
;;
|
|
||||||
d )
|
|
||||||
TODOTXT_CFG_FILE=$OPTARG
|
|
||||||
;;
|
|
||||||
f )
|
|
||||||
TODOTXT_FORCE=1
|
|
||||||
;;
|
|
||||||
h )
|
|
||||||
shorthelp
|
|
||||||
;;
|
|
||||||
n )
|
|
||||||
TODOTXT_PRESERVE_LINE_NUMBERS=0
|
|
||||||
;;
|
|
||||||
p )
|
|
||||||
TODOTXT_PLAIN=1
|
|
||||||
;;
|
|
||||||
P )
|
|
||||||
## HIDE_PRIORITY_LABELS starts at zero (false); increment it to one
|
|
||||||
## (true) the first time this flag is seen. Each time the flag
|
|
||||||
## is seen after that, increment it again so that an even
|
|
||||||
## number hides project names and an odd number shows project
|
|
||||||
## names.
|
|
||||||
: $(( HIDE_PRIORITY_LABELS++ ))
|
|
||||||
if [ $(( $HIDE_PRIORITY_LABELS % 2 )) -eq 0 ]
|
|
||||||
then
|
|
||||||
## Zero or even value -- show priority labels
|
|
||||||
unset HIDE_PRIORITY_SUBSTITUTION
|
|
||||||
else
|
|
||||||
## One or odd value -- hide priority labels
|
|
||||||
export HIDE_PRIORITY_SUBSTITUTION="([A-Z])[[:space:]]"
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
t )
|
|
||||||
TODOTXT_DATE_ON_ADD=1
|
|
||||||
;;
|
|
||||||
v )
|
|
||||||
: $(( TODOTXT_VERBOSE++ ))
|
|
||||||
;;
|
|
||||||
V )
|
|
||||||
version
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
done
|
|
||||||
shift $(($OPTIND - 1))
|
|
||||||
|
|
||||||
# defaults if not yet defined
|
|
||||||
TODOTXT_VERBOSE=${TODOTXT_VERBOSE:-1}
|
|
||||||
TODOTXT_PLAIN=${TODOTXT_PLAIN:-0}
|
|
||||||
TODOTXT_CFG_FILE=${TODOTXT_CFG_FILE:-$HOME/.todo/config}
|
|
||||||
TODOTXT_FORCE=${TODOTXT_FORCE:-0}
|
|
||||||
TODOTXT_PRESERVE_LINE_NUMBERS=${TODOTXT_PRESERVE_LINE_NUMBERS:-1}
|
|
||||||
TODOTXT_AUTO_ARCHIVE=${TODOTXT_AUTO_ARCHIVE:-1}
|
|
||||||
TODOTXT_DATE_ON_ADD=${TODOTXT_DATE_ON_ADD:-0}
|
|
||||||
TODOTXT_DEFAULT_ACTION=${TODOTXT_DEFAULT_ACTION:-}
|
|
||||||
TODOTXT_SORT_COMMAND=${TODOTXT_SORT_COMMAND:-env LC_COLLATE=C sort -f -k2}
|
|
||||||
TODOTXT_FINAL_FILTER=${TODOTXT_FINAL_FILTER:-cat}
|
|
||||||
|
|
||||||
# Export all TODOTXT_* variables
|
|
||||||
export ${!TODOTXT_@}
|
|
||||||
|
|
||||||
# Default color map
|
|
||||||
export NONE=''
|
|
||||||
export BLACK='\\033[0;30m'
|
|
||||||
export RED='\\033[0;31m'
|
|
||||||
export GREEN='\\033[0;32m'
|
|
||||||
export BROWN='\\033[0;33m'
|
|
||||||
export BLUE='\\033[0;34m'
|
|
||||||
export PURPLE='\\033[0;35m'
|
|
||||||
export CYAN='\\033[0;36m'
|
|
||||||
export LIGHT_GREY='\\033[0;37m'
|
|
||||||
export DARK_GREY='\\033[1;30m'
|
|
||||||
export LIGHT_RED='\\033[1;31m'
|
|
||||||
export LIGHT_GREEN='\\033[1;32m'
|
|
||||||
export YELLOW='\\033[1;33m'
|
|
||||||
export LIGHT_BLUE='\\033[1;34m'
|
|
||||||
export LIGHT_PURPLE='\\033[1;35m'
|
|
||||||
export LIGHT_CYAN='\\033[1;36m'
|
|
||||||
export WHITE='\\033[1;37m'
|
|
||||||
export DEFAULT='\\033[0m'
|
|
||||||
|
|
||||||
# Default priority->color map.
|
|
||||||
export PRI_A=$YELLOW # color for A priority
|
|
||||||
export PRI_B=$GREEN # color for B priority
|
|
||||||
export PRI_C=$LIGHT_BLUE # color for C priority
|
|
||||||
export PRI_X=$WHITE # color for rest of them
|
|
||||||
|
|
||||||
[ -e "$TODOTXT_CFG_FILE" ] || {
|
|
||||||
CFG_FILE_ALT="$HOME/todo.cfg"
|
|
||||||
|
|
||||||
if [ -e "$CFG_FILE_ALT" ]
|
|
||||||
then
|
|
||||||
TODOTXT_CFG_FILE="$CFG_FILE_ALT"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
[ -e "$TODOTXT_CFG_FILE" ] || {
|
|
||||||
CFG_FILE_ALT="$HOME/.todo.cfg"
|
|
||||||
|
|
||||||
if [ -e "$CFG_FILE_ALT" ]
|
|
||||||
then
|
|
||||||
TODOTXT_CFG_FILE="$CFG_FILE_ALT"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
if [ -z "$TODO_ACTIONS_DIR" -o ! -d "$TODO_ACTIONS_DIR" ]
|
|
||||||
then
|
|
||||||
TODO_ACTIONS_DIR="$HOME/.todo/actions"
|
|
||||||
export TODO_ACTIONS_DIR
|
|
||||||
fi
|
|
||||||
|
|
||||||
[ -d "$TODO_ACTIONS_DIR" ] || {
|
|
||||||
TODO_ACTIONS_DIR_ALT="$HOME/.todo.actions.d"
|
|
||||||
|
|
||||||
if [ -d "$TODO_ACTIONS_DIR_ALT" ]
|
|
||||||
then
|
|
||||||
TODO_ACTIONS_DIR="$TODO_ACTIONS_DIR_ALT"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# === SANITY CHECKS (thanks Karl!) ===
|
|
||||||
#[ -r "$TODOTXT_CFG_FILE" ] || die "Fatal error: Cannot read configuration file $TODOTXT_CFG_FILE"
|
|
||||||
|
|
||||||
#. "$TODOTXT_CFG_FILE"
|
|
||||||
|
|
||||||
ACTION=${1:-$TODOTXT_DEFAULT_ACTION}
|
|
||||||
|
|
||||||
[ -z "$ACTION" ] && usage
|
|
||||||
[ -d "$TODO_DIR" ] || die "Fatal Error: $TODO_DIR is not a directory"
|
|
||||||
( cd "$TODO_DIR" ) || die "Fatal Error: Unable to cd to $TODO_DIR"
|
|
||||||
|
|
||||||
[ -w "$TMP_FILE" ] || echo -n > "$TMP_FILE" || die "Fatal Error: Unable to write to $TMP_FILE"
|
|
||||||
[ -f "$TODO_FILE" ] || cp /dev/null "$TODO_FILE"
|
|
||||||
[ -f "$DONE_FILE" ] || cp /dev/null "$DONE_FILE"
|
|
||||||
[ -f "$REPORT_FILE" ] || cp /dev/null "$REPORT_FILE"
|
|
||||||
|
|
||||||
if [ $TODOTXT_PLAIN = 1 ]; then
|
|
||||||
PRI_A=$NONE
|
|
||||||
PRI_B=$NONE
|
|
||||||
PRI_C=$NONE
|
|
||||||
PRI_X=$NONE
|
|
||||||
DEFAULT=$NONE
|
|
||||||
fi
|
|
||||||
|
|
||||||
# === HEAVY LIFTING ===
|
|
||||||
shopt -s extglob
|
|
||||||
|
|
||||||
_list() {
|
|
||||||
local FILE="$1"
|
|
||||||
## If the file starts with a "/" use absolute path. Otherwise,
|
|
||||||
## try to find it in either $TODO_DIR or using a relative path
|
|
||||||
if [ "${1:0:1}" == / ]
|
|
||||||
then
|
|
||||||
## Absolute path
|
|
||||||
src="$FILE"
|
|
||||||
elif [ -f "$TODO_DIR/$FILE" ]
|
|
||||||
then
|
|
||||||
## Path relative to todo.sh directory
|
|
||||||
src="$TODO_DIR/$1"
|
|
||||||
elif [ -f "$FILE" ]
|
|
||||||
then
|
|
||||||
## Path relative to current working directory
|
|
||||||
src="$FILE"
|
|
||||||
else
|
|
||||||
echo "TODO: File $FILE does not exist."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
## Get our search arguments, if any
|
|
||||||
shift ## was file name, new $1 is first search term
|
|
||||||
|
|
||||||
## Prefix the filter_command with the pre_filter_command
|
|
||||||
filter_command="${pre_filter_command:-}"
|
|
||||||
|
|
||||||
for search_term in "$@"
|
|
||||||
do
|
|
||||||
## See if the first character of $search_term is a dash
|
|
||||||
if [ ${search_term:0:1} != '-' ]
|
|
||||||
then
|
|
||||||
## First character isn't a dash: hide lines that don't match
|
|
||||||
## this $search_term
|
|
||||||
filter_command="${filter_command:-} ${filter_command:+|} \
|
|
||||||
grep -i \"$search_term\" "
|
|
||||||
else
|
|
||||||
## First character is a dash: hide lines that match this
|
|
||||||
## $search_term
|
|
||||||
#
|
|
||||||
## Remove the first character (-) before adding to our filter command
|
|
||||||
filter_command="${filter_command:-} ${filter_command:+|} \
|
|
||||||
grep -v -i \"${search_term:1}\" "
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
## If post_filter_command is set, append it to the filter_command
|
|
||||||
[ -n "$post_filter_command" ] && {
|
|
||||||
filter_command="${filter_command:-}${filter_command:+ | }${post_filter_command:-}"
|
|
||||||
}
|
|
||||||
|
|
||||||
## Figure out how much padding we need to use
|
|
||||||
## We need one level of padding for each power of 10 $LINES uses
|
|
||||||
LINES=$( sed -n '$ =' "$src" )
|
|
||||||
PADDING=${#LINES}
|
|
||||||
|
|
||||||
## Number the file, then run the filter command,
|
|
||||||
## then sort and mangle output some more
|
|
||||||
items=$(
|
|
||||||
sed = "$src" \
|
|
||||||
| sed "N; s/^/ /; s/ *\(.\{$PADDING,\}\)\n/\1 /" \
|
|
||||||
| grep -v "^[0-9]\+ *$"
|
|
||||||
)
|
|
||||||
if [ "${filter_command}" ]; then
|
|
||||||
filtered_items=$(echo -ne "$items" | eval ${filter_command})
|
|
||||||
else
|
|
||||||
filtered_items=$items
|
|
||||||
fi
|
|
||||||
filtered_items=$(
|
|
||||||
echo -ne "$filtered_items" \
|
|
||||||
| sed '''
|
|
||||||
s/^ /00000/;
|
|
||||||
s/^ /0000/;
|
|
||||||
s/^ /000/;
|
|
||||||
s/^ /00/;
|
|
||||||
s/^ /0/;
|
|
||||||
''' \
|
|
||||||
| eval ${TODOTXT_SORT_COMMAND} \
|
|
||||||
| sed '''
|
|
||||||
/^[0-9]\{'$PADDING'\} x /! {
|
|
||||||
s/\(.*(A).*\)/'$PRI_A'\1'$DEFAULT'/g;
|
|
||||||
s/\(.*(B).*\)/'$PRI_B'\1'$DEFAULT'/g;
|
|
||||||
s/\(.*(C).*\)/'$PRI_C'\1'$DEFAULT'/g;
|
|
||||||
s/\(.*([D-Z]).*\)/'$PRI_X'\1'$DEFAULT'/g;
|
|
||||||
}
|
|
||||||
''' \
|
|
||||||
| sed '''
|
|
||||||
s/'${HIDE_PRIORITY_SUBSTITUTION:-^}'//g
|
|
||||||
s/'${HIDE_PROJECTS_SUBSTITUTION:-^}'//g
|
|
||||||
s/'${HIDE_CONTEXTS_SUBSTITUTION:-^}'//g
|
|
||||||
''' \
|
|
||||||
| eval ${TODOTXT_FINAL_FILTER} \
|
|
||||||
)
|
|
||||||
echo -ne "$filtered_items${filtered_items:+\n}"
|
|
||||||
|
|
||||||
if [ $TODOTXT_VERBOSE -gt 0 ]; then
|
|
||||||
NUMTASKS=$( echo -ne "$filtered_items" | sed -n '$ =' )
|
|
||||||
TOTALTASKS=$( echo -ne "$items" | sed -n '$ =' )
|
|
||||||
|
|
||||||
echo "--"
|
|
||||||
echo "TODO: ${NUMTASKS:-0} of ${TOTALTASKS:-0} tasks shown from $FILE"
|
|
||||||
fi
|
|
||||||
if [ $TODOTXT_VERBOSE -gt 1 ]
|
|
||||||
then
|
|
||||||
echo "TODO DEBUG: Filter Command was: ${filter_command:-cat}"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
export -f _list
|
|
||||||
|
|
||||||
# == HANDLE ACTION ==
|
|
||||||
action=$( printf "%s\n" "$ACTION" | tr 'A-Z' 'a-z' )
|
|
||||||
|
|
||||||
## If the first argument is "command", run the rest of the arguments
|
|
||||||
## using todo.sh builtins.
|
|
||||||
## Else, run a actions script with the name of the command if it exists
|
|
||||||
## or fallback to using a builtin
|
|
||||||
if [ "$action" == command ]
|
|
||||||
then
|
|
||||||
## Get rid of "command" from arguments list
|
|
||||||
shift
|
|
||||||
## Reset action to new first argument
|
|
||||||
action=$( printf "%s\n" "$1" | tr 'A-Z' 'a-z' )
|
|
||||||
elif [ -d "$TODO_ACTIONS_DIR" -a -x "$TODO_ACTIONS_DIR/$action" ]
|
|
||||||
then
|
|
||||||
"$TODO_ACTIONS_DIR/$action" "$@"
|
|
||||||
cleanup
|
|
||||||
fi
|
|
||||||
|
|
||||||
## Only run if $action isn't found in .todo.actions.d
|
|
||||||
case $action in
|
|
||||||
"add" | "a")
|
|
||||||
if [[ -z "$2" && $TODOTXT_FORCE = 0 ]]; then
|
|
||||||
echo -n "Add: "
|
|
||||||
read input
|
|
||||||
else
|
|
||||||
[ -z "$2" ] && die "usage: $TODO_SH add \"TODO ITEM\""
|
|
||||||
shift
|
|
||||||
input=$*
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ $TODOTXT_DATE_ON_ADD = 1 ]]; then
|
|
||||||
now=`date '+%Y-%m-%d'`
|
|
||||||
input="$now $input"
|
|
||||||
fi
|
|
||||||
echo "$input" >> "$TODO_FILE"
|
|
||||||
TASKNUM=$(sed -n '$ =' "$TODO_FILE")
|
|
||||||
[ $TODOTXT_VERBOSE -gt 0 ] && echo "TODO: '$input' added on line $TASKNUM."
|
|
||||||
cleanup;;
|
|
||||||
|
|
||||||
"addto" )
|
|
||||||
[ -z "$2" ] && die "usage: $TODO_SH addto DEST \"TODO ITEM\""
|
|
||||||
dest="$TODO_DIR/$2"
|
|
||||||
[ -z "$3" ] && die "usage: $TODO_SH addto DEST \"TODO ITEM\""
|
|
||||||
shift
|
|
||||||
shift
|
|
||||||
input=$*
|
|
||||||
|
|
||||||
if [ -f "$dest" ]; then
|
|
||||||
echo "$input" >> "$dest"
|
|
||||||
TASKNUM=$(sed -n '$ =' "$dest")
|
|
||||||
[ $TODOTXT_VERBOSE -gt 0 ] && echo "TODO: '$input' added to $dest on line $TASKNUM."
|
|
||||||
else
|
|
||||||
echo "TODO: Destination file $dest does not exist."
|
|
||||||
fi
|
|
||||||
cleanup;;
|
|
||||||
|
|
||||||
"append" | "app" )
|
|
||||||
errmsg="usage: $TODO_SH append ITEM# \"TEXT TO APPEND\""
|
|
||||||
shift; item=$1; shift
|
|
||||||
|
|
||||||
[ -z "$item" ] && die "$errmsg"
|
|
||||||
[[ "$item" = +([0-9]) ]] || die "$errmsg"
|
|
||||||
todo=$(sed "$item!d" "$TODO_FILE")
|
|
||||||
[ -z "$todo" ] && die "$item: No such todo."
|
|
||||||
if [[ -z "$1" && $TODOTXT_FORCE = 0 ]]; then
|
|
||||||
echo -n "Append: "
|
|
||||||
read input
|
|
||||||
else
|
|
||||||
input=$*
|
|
||||||
fi
|
|
||||||
if sed -i.bak $item" s|^.*|& $input|" "$TODO_FILE"; then
|
|
||||||
newtodo=$(sed "$item!d" "$TODO_FILE")
|
|
||||||
[ $TODOTXT_VERBOSE -gt 0 ] && echo "$item: $newtodo"
|
|
||||||
else
|
|
||||||
echo "TODO: Error appending task $item."
|
|
||||||
fi
|
|
||||||
cleanup;;
|
|
||||||
|
|
||||||
"archive" )
|
|
||||||
archive;;
|
|
||||||
|
|
||||||
"del" | "rm" )
|
|
||||||
# replace deleted line with a blank line when TODOTXT_PRESERVE_LINE_NUMBERS is 1
|
|
||||||
errmsg="usage: $TODO_SH del ITEM#"
|
|
||||||
item=$2
|
|
||||||
[ -z "$item" ] && die "$errmsg"
|
|
||||||
|
|
||||||
if [ -z "$3" ]; then
|
|
||||||
|
|
||||||
[[ "$item" = +([0-9]) ]] || die "$errmsg"
|
|
||||||
if sed -ne "$item p" "$TODO_FILE" | grep "^."; then
|
|
||||||
DELETEME=$(sed "$item!d" "$TODO_FILE")
|
|
||||||
|
|
||||||
if [ $TODOTXT_FORCE = 0 ]; then
|
|
||||||
echo "Delete '$DELETEME'? (y/n)"
|
|
||||||
read ANSWER
|
|
||||||
else
|
|
||||||
ANSWER="y"
|
|
||||||
fi
|
|
||||||
if [ "$ANSWER" = "y" ]; then
|
|
||||||
if [ $TODOTXT_PRESERVE_LINE_NUMBERS = 0 ]; then
|
|
||||||
# delete line (changes line numbers)
|
|
||||||
sed -i.bak -e $item"s/^.*//" -e '/./!d' "$TODO_FILE"
|
|
||||||
else
|
|
||||||
# leave blank line behind (preserves line numbers)
|
|
||||||
sed -i.bak -e $item"s/^.*//" "$TODO_FILE"
|
|
||||||
fi
|
|
||||||
[ $TODOTXT_VERBOSE -gt 0 ] && echo "TODO: '$DELETEME' deleted."
|
|
||||||
cleanup
|
|
||||||
else
|
|
||||||
echo "TODO: No tasks were deleted."
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
echo "$item: No such todo."
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
sed -i.bak -e $item"s/$3/ /g" "$TODO_FILE"
|
|
||||||
[ $TODOTXT_VERBOSE -gt 0 ] && echo "TODO: $3 removed from $item."
|
|
||||||
fi ;;
|
|
||||||
|
|
||||||
"depri" | "dp" )
|
|
||||||
item=$2
|
|
||||||
errmsg="usage: $TODO_SH depri ITEM#"
|
|
||||||
|
|
||||||
todo=$(sed "$item!d" "$TODO_FILE")
|
|
||||||
[ -z "$todo" ] && die "$item: No such todo."
|
|
||||||
[[ "$item" = +([0-9]) ]] || die "$errmsg"
|
|
||||||
|
|
||||||
sed -e $item"s/^(.) //" "$TODO_FILE" > /dev/null 2>&1
|
|
||||||
|
|
||||||
if [ "$?" -eq 0 ]; then
|
|
||||||
#it's all good, continue
|
|
||||||
sed -i.bak -e $item"s/^(.) //" "$TODO_FILE"
|
|
||||||
NEWTODO=$(sed "$item!d" "$TODO_FILE")
|
|
||||||
[ $TODOTXT_VERBOSE -gt 0 ] && echo -e "`echo "$item: $NEWTODO"`"
|
|
||||||
[ $TODOTXT_VERBOSE -gt 0 ] && echo "TODO: $item deprioritized."
|
|
||||||
cleanup
|
|
||||||
else
|
|
||||||
die "$errmsg"
|
|
||||||
fi;;
|
|
||||||
|
|
||||||
"do" )
|
|
||||||
errmsg="usage: $TODO_SH do ITEM#"
|
|
||||||
# shift so we get arguments to the do request
|
|
||||||
shift;
|
|
||||||
|
|
||||||
# Split multiple do's, if comma seperated change to whitespace sepereated
|
|
||||||
# Loop the 'do' function for each item
|
|
||||||
for item in `echo $* | tr ',' ' '`; do
|
|
||||||
[ -z "$item" ] && die "$errmsg"
|
|
||||||
[[ "$item" = +([0-9]) ]] || die "$errmsg"
|
|
||||||
|
|
||||||
todo=$(sed "$item!d" "$TODO_FILE")
|
|
||||||
[ -z "$todo" ] && die "$item: No such todo."
|
|
||||||
|
|
||||||
now=`date '+%Y-%m-%d'`
|
|
||||||
# remove priority once item is done
|
|
||||||
sed -i.bak $item"s/^(.) //" "$TODO_FILE"
|
|
||||||
sed -i.bak $item"s|^|&x $now |" "$TODO_FILE"
|
|
||||||
newtodo=$(sed "$item!d" "$TODO_FILE")
|
|
||||||
[ $TODOTXT_VERBOSE -gt 0 ] && echo "$item: $newtodo"
|
|
||||||
[ $TODOTXT_VERBOSE -gt 0 ] && echo "TODO: $item marked as done."
|
|
||||||
done
|
|
||||||
|
|
||||||
if [ $TODOTXT_AUTO_ARCHIVE = 1 ]; then
|
|
||||||
archive
|
|
||||||
fi
|
|
||||||
cleanup ;;
|
|
||||||
|
|
||||||
"help" )
|
|
||||||
help
|
|
||||||
;;
|
|
||||||
|
|
||||||
"list" | "ls" )
|
|
||||||
shift ## Was ls; new $1 is first search term
|
|
||||||
_list "$TODO_FILE" "$@"
|
|
||||||
|
|
||||||
cleanup
|
|
||||||
;;
|
|
||||||
|
|
||||||
"listall" | "lsa" )
|
|
||||||
shift ## Was lsa; new $1 is first search term
|
|
||||||
|
|
||||||
cat "$TODO_FILE" "$DONE_FILE" > "$TMP_FILE"
|
|
||||||
_list "$TMP_FILE" "$@"
|
|
||||||
|
|
||||||
cleanup
|
|
||||||
;;
|
|
||||||
|
|
||||||
"listfile" | "lf" )
|
|
||||||
shift ## Was listfile, next $1 is file name
|
|
||||||
FILE="$1"
|
|
||||||
shift ## Was filename; next $1 is first search term
|
|
||||||
|
|
||||||
_list "$FILE" "$@"
|
|
||||||
|
|
||||||
cleanup
|
|
||||||
;;
|
|
||||||
|
|
||||||
"listcon" | "lsc" )
|
|
||||||
grep -o '[^ ]*@[^ ]\+' "$TODO_FILE" | grep '^@' | sort -u
|
|
||||||
cleanup ;;
|
|
||||||
|
|
||||||
"listproj" | "lsprj" )
|
|
||||||
grep -o '[^ ]*+[^ ]\+' "$TODO_FILE" | grep '^+' | sort -u
|
|
||||||
cleanup ;;
|
|
||||||
|
|
||||||
|
|
||||||
"listpri" | "lsp" )
|
|
||||||
shift ## was "listpri", new $1 is priority to list
|
|
||||||
|
|
||||||
if [ "${1:-}" ]
|
|
||||||
then
|
|
||||||
## A priority was specified
|
|
||||||
pri=$( printf "%s\n" "$1" | tr 'a-z' 'A-Z' | grep '^[A-Z]$' ) || {
|
|
||||||
die "usage: $TODO_SH listpri PRIORITY
|
|
||||||
note: PRIORITY must a single letter from A to Z."
|
|
||||||
}
|
|
||||||
else
|
|
||||||
## No priority specified; show all priority tasks
|
|
||||||
pri="[[:upper:]]"
|
|
||||||
fi
|
|
||||||
pri="($pri)"
|
|
||||||
|
|
||||||
_list "$TODO_FILE" "$pri"
|
|
||||||
;;
|
|
||||||
|
|
||||||
"move" | "mv" )
|
|
||||||
# replace moved line with a blank line when TODOTXT_PRESERVE_LINE_NUMBERS is 1
|
|
||||||
errmsg="usage: $TODO_SH mv ITEM# DEST [SRC]"
|
|
||||||
item=$2
|
|
||||||
dest="$TODO_DIR/$3"
|
|
||||||
src="$TODO_DIR/$4"
|
|
||||||
|
|
||||||
[ -z "$item" ] && die "$errmsg"
|
|
||||||
[ -z "$4" ] && src="$TODO_FILE"
|
|
||||||
[ -z "$dest" ] && die "$errmsg"
|
|
||||||
|
|
||||||
[[ "$item" = +([0-9]) ]] || die "$errmsg"
|
|
||||||
|
|
||||||
if [ -f "$src" ]; then
|
|
||||||
if [ -f "$dest" ]; then
|
|
||||||
if sed -ne "$item p" "$src" | grep "^."; then
|
|
||||||
MOVEME=$(sed "$item!d" "$src")
|
|
||||||
if [ $TODOTXT_FORCE = 0 ]; then
|
|
||||||
echo "Move '$MOVEME' from $src to $dest? (y/n)"
|
|
||||||
read ANSWER
|
|
||||||
else
|
|
||||||
ANSWER="y"
|
|
||||||
fi
|
|
||||||
if [ "$ANSWER" = "y" ]; then
|
|
||||||
if [ $TODOTXT_PRESERVE_LINE_NUMBERS = 0 ]; then
|
|
||||||
# delete line (changes line numbers)
|
|
||||||
sed -i.bak -e $item"s/^.*//" -e '/./!d' "$src"
|
|
||||||
else
|
|
||||||
# leave blank line behind (preserves line numbers)
|
|
||||||
sed -i.bak -e $item"s/^.*//" "$src"
|
|
||||||
fi
|
|
||||||
echo "$MOVEME" >> "$dest"
|
|
||||||
|
|
||||||
[ $TODOTXT_VERBOSE -gt 0 ] && echo "TODO: '$MOVEME' moved from '$src' to '$dest'."
|
|
||||||
cleanup
|
|
||||||
else
|
|
||||||
echo "TODO: No tasks moved."
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
echo "$item: No such item in $src."
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
echo "TODO: Destination file $dest does not exist."
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
echo "TODO: Source file $src does not exist."
|
|
||||||
fi
|
|
||||||
cleanup;;
|
|
||||||
|
|
||||||
"prepend" | "prep" )
|
|
||||||
errmsg="usage: $TODO_SH prepend ITEM# \"TEXT TO PREPEND\""
|
|
||||||
shift; item=$1; shift
|
|
||||||
|
|
||||||
[ -z "$item" ] && die "$errmsg"
|
|
||||||
[[ "$item" = +([0-9]) ]] || die "$errmsg"
|
|
||||||
|
|
||||||
todo=$(sed "$item!d" "$TODO_FILE")
|
|
||||||
[ -z "$todo" ] && die "$item: No such todo."
|
|
||||||
|
|
||||||
if [[ -z "$1" && $TODOTXT_FORCE = 0 ]]; then
|
|
||||||
echo -n "Prepend: "
|
|
||||||
read input
|
|
||||||
else
|
|
||||||
input=$*
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Test for then set priority
|
|
||||||
if [ `sed "$item!d" "$TODO_FILE"|grep -c "^(\\w)"` -eq 1 ]; then
|
|
||||||
priority=$(sed "$item!d" "$TODO_FILE" | awk -F '\\(|\\)' '{print $2}')
|
|
||||||
fi
|
|
||||||
|
|
||||||
# If priority isn't set prepend
|
|
||||||
if [ -z $priority ]; then
|
|
||||||
if sed -i.bak $item" s|^.*|$input &|" "$TODO_FILE"; then
|
|
||||||
newtodo=$(sed "$item!d" "$TODO_FILE")
|
|
||||||
[ $TODOTXT_VERBOSE -gt 0 ] && echo "$item: $newtodo"
|
|
||||||
else
|
|
||||||
echo "TODO: Error prepending task $item."
|
|
||||||
fi
|
|
||||||
# If priority is set, remove priority, prepend and add back priority
|
|
||||||
else
|
|
||||||
if sed -i.bak -e "$item s/^(.) //" -e "$item s|^.*|\($priority\) $1 &|" "$TODO_FILE"; then
|
|
||||||
newtodo=$(sed "$item!d" "$TODO_FILE")
|
|
||||||
[ $TODOTXT_VERBOSE -gt 0 ] && echo "$item: $newtodo"
|
|
||||||
else
|
|
||||||
echo "TODO: Error prepending task $item."
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
cleanup;;
|
|
||||||
|
|
||||||
"pri" | "p" )
|
|
||||||
item=$2
|
|
||||||
newpri=$( printf "%s\n" "$3" | tr 'a-z' 'A-Z' )
|
|
||||||
|
|
||||||
errmsg="usage: $TODO_SH pri ITEM# PRIORITY
|
|
||||||
note: PRIORITY must be anywhere from A to Z."
|
|
||||||
|
|
||||||
[ "$#" -ne 3 ] && die "$errmsg"
|
|
||||||
[[ "$item" = +([0-9]) ]] || die "$errmsg"
|
|
||||||
[[ "$newpri" = @([A-Z]) ]] || die "$errmsg"
|
|
||||||
|
|
||||||
sed -e $item"s/^(.) //" -e $item"s/^/($newpri) /" "$TODO_FILE" > /dev/null 2>&1
|
|
||||||
|
|
||||||
if [ "$?" -eq 0 ]; then
|
|
||||||
#it's all good, continue
|
|
||||||
sed -i.bak -e $item"s/^(.) //" -e $item"s/^/($newpri) /" "$TODO_FILE"
|
|
||||||
NEWTODO=$(sed "$item!d" "$TODO_FILE")
|
|
||||||
[ $TODOTXT_VERBOSE -gt 0 ] && echo -e "`echo "$item: $NEWTODO"`"
|
|
||||||
[ $TODOTXT_VERBOSE -gt 0 ] && echo "TODO: $item prioritized ($newpri)."
|
|
||||||
cleanup
|
|
||||||
else
|
|
||||||
die "$errmsg"
|
|
||||||
fi;;
|
|
||||||
|
|
||||||
"replace" )
|
|
||||||
errmsg="usage: $TODO_SH replace ITEM# \"UPDATED ITEM\""
|
|
||||||
shift; item=$1; shift
|
|
||||||
|
|
||||||
[ -z "$item" ] && die "$errmsg"
|
|
||||||
[[ "$item" = +([0-9]) ]] || die "$errmsg"
|
|
||||||
|
|
||||||
todo=$(sed "$item!d" "$TODO_FILE")
|
|
||||||
[ -z "$todo" ] && die "$item: No such todo."
|
|
||||||
|
|
||||||
# Test for then set priority
|
|
||||||
if [ `sed "$item!d" "$TODO_FILE"|grep -c "^(\\w)"` -eq 1 ]; then
|
|
||||||
priority=$(sed "$item!d" "$TODO_FILE" | awk -F '\\(|\\)' '{print $2}')
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ -z "$1" && $TODOTXT_FORCE = 0 ]]; then
|
|
||||||
echo -n "Replacement: "
|
|
||||||
read input
|
|
||||||
else
|
|
||||||
input=$*
|
|
||||||
fi
|
|
||||||
|
|
||||||
# If priority isn't set replace, if it is remove priority, replace then add priority again
|
|
||||||
if [ -z $priority ]; then
|
|
||||||
sed -i.bak $item" s|^.*|$input|" "$TODO_FILE"
|
|
||||||
else
|
|
||||||
sed -i.bak -e "$item s/^(.) //" -e "$item s|^.*|\($priority\) $1|" "$TODO_FILE"
|
|
||||||
fi
|
|
||||||
[ $TODOTXT_VERBOSE -gt 0 ] && NEWTODO=$(head -$item "$TODO_FILE" | tail -1)
|
|
||||||
[ $TODOTXT_VERBOSE -gt 0 ] && echo "$item: $todo"
|
|
||||||
[ $TODOTXT_VERBOSE -gt 0 ] && echo "replaced with"
|
|
||||||
[ $TODOTXT_VERBOSE -gt 0 ] && echo "$item: $NEWTODO"
|
|
||||||
cleanup;;
|
|
||||||
|
|
||||||
"report" )
|
|
||||||
#archive first
|
|
||||||
sed '/^x /!d' "$TODO_FILE" >> "$DONE_FILE"
|
|
||||||
sed -i.bak '/^x /d' "$TODO_FILE"
|
|
||||||
|
|
||||||
NUMLINES=$( sed -n '$ =' "$TODO_FILE" )
|
|
||||||
if [ ${NUMLINES:-0} = "0" ]; then
|
|
||||||
echo "datetime todos dones" >> "$REPORT_FILE"
|
|
||||||
fi
|
|
||||||
#now report
|
|
||||||
TOTAL=$( sed -n '$ =' "$TODO_FILE" )
|
|
||||||
TDONE=$( sed -n '$ =' "$DONE_FILE" )
|
|
||||||
TECHO=$(echo $(date +%Y-%m-%d-%T); echo ' '; echo ${TOTAL:-0}; echo ' ';
|
|
||||||
echo ${TDONE:-0})
|
|
||||||
echo $TECHO >> "$REPORT_FILE"
|
|
||||||
[ $TODOTXT_VERBOSE -gt 0 ] && echo "TODO: Report file updated."
|
|
||||||
cat "$REPORT_FILE"
|
|
||||||
cleanup;;
|
|
||||||
|
|
||||||
* )
|
|
||||||
usage
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
@@ -1,39 +0,0 @@
|
|||||||
CHANGEFILE
|
|
||||||
----------
|
|
||||||
|
|
||||||
This is the Changefile for the development 0.3 branch of EFSL.
|
|
||||||
Recording began with EFSL-0.3.3
|
|
||||||
|
|
||||||
0.3.5
|
|
||||||
-----
|
|
||||||
* Added warning in documentation that it is outdated
|
|
||||||
* Changed structure definitions
|
|
||||||
* Implemnted full-feature cp
|
|
||||||
* Renamed some efsl-functions (all starting with EFSL_)
|
|
||||||
* Added another example for AVR.
|
|
||||||
* Updated docs on getting started on AVR.
|
|
||||||
|
|
||||||
0.3.4
|
|
||||||
-----
|
|
||||||
* Fixed avr support
|
|
||||||
* Created new avr example + makefile
|
|
||||||
* Some more work on new fsutils
|
|
||||||
|
|
||||||
0.3.3
|
|
||||||
-----
|
|
||||||
|
|
||||||
* Renamed src/core to src/base
|
|
||||||
* Implemented new hwInterface structure
|
|
||||||
Support for multiple hwEndpoints in one project
|
|
||||||
* Modified SD_SPI to work as a general protocol
|
|
||||||
* Modified Linuxfile to the new hwInterface model
|
|
||||||
* Created a new efs_configger, now supports every
|
|
||||||
combination of partitions/disc
|
|
||||||
* Implemented full support for little and big endian
|
|
||||||
machines, as well as for little and big endian
|
|
||||||
filesystems
|
|
||||||
* Created new build system, for multiple platforms,
|
|
||||||
configurable from one file
|
|
||||||
* Changes cpo to use the new library functions
|
|
||||||
* Broke both dsp & atmega support
|
|
||||||
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
include conf/config.makefile
|
|
||||||
|
|
||||||
linux: efsl-base efsl-fs-vfat efsl-hwd-linuxfile
|
|
||||||
avr: efsl-base efsl-fs-vfat efsl-prot-sdspi efsl-hwd-atmega_sd
|
|
||||||
|
|
||||||
efsl-base:
|
|
||||||
make -C src/base/
|
|
||||||
cp src/base/efsl-base.a lib/libefsl-base.a
|
|
||||||
|
|
||||||
efsl-fs-vfat:
|
|
||||||
make -C src/fs/vfat/
|
|
||||||
cp src/fs/vfat/efsl-fs-vfat.a lib/libefsl-fs-vfat.a
|
|
||||||
|
|
||||||
efsl-prot-sdspi:
|
|
||||||
make -C src/protocols/sdcard_spi/
|
|
||||||
cp src/protocols/sdcard_spi/efsl-prot-sdspi.a lib/libefsl-prot-sdspi.a
|
|
||||||
|
|
||||||
efsl-hwd-linuxfile:
|
|
||||||
make -C src/hwdrivers/linuxfile/
|
|
||||||
cp src/hwdrivers/linuxfile/efsl-hwd-linuxfile.a lib/libefsl-hwd-linuxfile.a
|
|
||||||
|
|
||||||
efsl-hwd-atmega_sd:
|
|
||||||
make -C src/hwdrivers/atmega_spi/
|
|
||||||
cp src/hwdrivers/atmega_spi/efsl-hwd-atmega_spi.a lib/libefsl-hwd-atmega_spi.a
|
|
||||||
|
|
||||||
clean:
|
|
||||||
make -C src/base/ clean
|
|
||||||
make -C src/fs/vfat/ clean
|
|
||||||
make -C src/hwdrivers/linuxfile/ clean
|
|
||||||
make -C src/hwdrivers/atmega_spi clean
|
|
||||||
rm -rf lib/*.a
|
|
||||||
@@ -1,174 +0,0 @@
|
|||||||
#ifndef __EFSL_CONFIG_H__
|
|
||||||
#define __EFSL_CONFIG_H__
|
|
||||||
|
|
||||||
/* Hardware target
|
|
||||||
---------------
|
|
||||||
|
|
||||||
* Here you will define for what hardware-endpoint EFSL should be compiled.
|
|
||||||
* Look in interfaces.h to see what systems are supported, and add your own
|
|
||||||
* there if you need to write your own driver. Then, define the name you
|
|
||||||
* selected for your hardware there here. Make sure that you only select one
|
|
||||||
* device!
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*#define HW_ENDPOINT_LINUX*/
|
|
||||||
#define HW_ENDPOINT_ATMEGA128_SD
|
|
||||||
/*#define HW_ENDPOINT_DSP_TI6713_SD*/
|
|
||||||
|
|
||||||
#define MULTIPLE_INTERFACE_SUPPORT
|
|
||||||
|
|
||||||
/* Architecture
|
|
||||||
------------
|
|
||||||
|
|
||||||
* In this section you should configure how large the default variable
|
|
||||||
* types in your system are. This is controlled in types.h in the general
|
|
||||||
* include directory. The selection you make here defines to what the various
|
|
||||||
* e(s|u)int(8,16,32) types will map.
|
|
||||||
* For 32 bit Linux : VARSIZE_LINUX32
|
|
||||||
* For 64 bit Linux : VARSIZE_LINUX64
|
|
||||||
* For AVR's : VARSIZE_ATMEGA
|
|
||||||
* For TMS67XX : VARSIZE_TMS67XX
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define VARSIZE_ATMEGA
|
|
||||||
|
|
||||||
|
|
||||||
/* Memory configuration
|
|
||||||
--------------------
|
|
||||||
|
|
||||||
* Here you must configure wheter your processor can access memory byte
|
|
||||||
* oriented. All x86 processors can do it, AVR's can do it to. Some DSP
|
|
||||||
* or other microcontrollers can't. If you have an 8 bit system you're safe.
|
|
||||||
* If you are really unsure, leave the setting commented out, it will be slower
|
|
||||||
* but it will work for sure.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define BYTE_ALIGNMENT
|
|
||||||
|
|
||||||
/* Cache configuration
|
|
||||||
-------------------
|
|
||||||
|
|
||||||
* Here you must configure how much memory of cache you can/want to use.
|
|
||||||
* The number you put at IOMAN_NUMBUFFER is multiplied by 512. So 1 means
|
|
||||||
* 512 bytes cache, 4 means 2048 bytes cache. More is better.
|
|
||||||
* The number after IOMAN_NUMITERATIONS should be untouched.
|
|
||||||
* The last field (IOMAN_DO_MEMALLOC) is to tell ioman to allocate it's
|
|
||||||
* own memory in it's structure, or not. If you choose to do it yourself
|
|
||||||
* you will have to pass a pointer to the memory as the last argument of
|
|
||||||
* ioman_init.
|
|
||||||
*/
|
|
||||||
#define IOMAN_NUMBUFFER 1
|
|
||||||
#define IOMAN_NUMITERATIONS 3
|
|
||||||
#define IOMAN_DO_MEMALLOC
|
|
||||||
|
|
||||||
/* Cluster pre-allocation
|
|
||||||
----------------------
|
|
||||||
|
|
||||||
* When writing files, the function that performs the actual write has to
|
|
||||||
* calculate how many clusters it will need for that request. It then allocates
|
|
||||||
* that number of new clusters to the file. Since this involves some
|
|
||||||
* calculations and writing of the FAT, you might find it beneficial to limit
|
|
||||||
* the number of allocations, and allow fwrite to pre-allocate a number of
|
|
||||||
* clusters extra. This setting determines how many clusters will be extra
|
|
||||||
* allocated whenever this is required.
|
|
||||||
* Take in carefull consideration how large your clustersize is, putting 10 here
|
|
||||||
* with a clustersize of 32kb means you might waste 320 kb.
|
|
||||||
* The first option is for preallocating files, the other is used when enlarging
|
|
||||||
* a directory to accomodate more files
|
|
||||||
*/
|
|
||||||
#define CLUSTER_PREALLOC_FILE 0
|
|
||||||
#define CLUSTER_PREALLOC_DIRECTORY 0
|
|
||||||
|
|
||||||
|
|
||||||
/* Endianess configuration
|
|
||||||
-----------------------
|
|
||||||
|
|
||||||
* Here you can configure wheter your architecture is little or big endian. This
|
|
||||||
* is important since all FAT structures are stored in intel little endian
|
|
||||||
* order. So if you have a big endian system the library has to convert all
|
|
||||||
* figures to big endian in order to work.
|
|
||||||
*/
|
|
||||||
#define HOST_LITTLE_ENDIAN
|
|
||||||
|
|
||||||
|
|
||||||
/* Date and Time support
|
|
||||||
---------------------
|
|
||||||
|
|
||||||
* Here you can enable or disable date and time support. If you enable
|
|
||||||
* it you will have to create 6 functions, that are described in the
|
|
||||||
* EFSL manual. If the functions are not present when linking your
|
|
||||||
* program with the library you will get unresolved dependencies.
|
|
||||||
*/
|
|
||||||
/* #define DATE_TIME_SUPPORT */
|
|
||||||
|
|
||||||
/* Error reporting support
|
|
||||||
-----------------------
|
|
||||||
|
|
||||||
* When you receive an error in userland, it usually only gives limited
|
|
||||||
* information (most likely, fail or success). If error detection and
|
|
||||||
* reporting is important for you, you can enable more detailed error
|
|
||||||
* reporting here. This is optional, the costs are 1 byte per object,
|
|
||||||
* and a small increase in code size.
|
|
||||||
* You can enable error recording for all object, or you can select the
|
|
||||||
* object manually.
|
|
||||||
* For full error reporting use FULL_ERROR_SUPPORT
|
|
||||||
* For only the base-core of the library use BASE_ERROR_SUPPORT
|
|
||||||
* For IO/Man use ERRSUP_IOMAN
|
|
||||||
* For Disc use ERRSUP_IOMAN
|
|
||||||
* For Part use ERRSUP_PARTITION
|
|
||||||
* For Fs use ERRSUP_FILESYSTEM
|
|
||||||
* For File use ERRSUP_FILE
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define FULL_ERROR_SUPPORT
|
|
||||||
/*#define BASE_ERROR_SUPPORT*/
|
|
||||||
|
|
||||||
/* List options
|
|
||||||
------------
|
|
||||||
|
|
||||||
* In this section you can configure what kind of data you will get from
|
|
||||||
* directory listing requests. Please refer to the documentation for
|
|
||||||
* more information
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define LIST_MAXLENFILENAME 12
|
|
||||||
|
|
||||||
|
|
||||||
/* Debugging configuration
|
|
||||||
-----------------------
|
|
||||||
|
|
||||||
* Here you can configure the debugging behaviour. Debugging is different
|
|
||||||
* on every platform (see debug.h for more information).
|
|
||||||
* If your hardware has no means of output (printf) dont define any anything,
|
|
||||||
* and nothing will happen. For real world use debugging should be turned off.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define DEBUG
|
|
||||||
|
|
||||||
|
|
||||||
/* Debugging configuration - AVR Specific: PORT
|
|
||||||
--------------------------------------------
|
|
||||||
|
|
||||||
* Here you can select which UART you want to use for debugging.
|
|
||||||
* If you did not define DEBUG, this setting has no effect.
|
|
||||||
* Note that it is not a good idea to use a port that you use in userspace.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*#define DEBUG_PORT 0*/ /* Select UART0 */
|
|
||||||
#define DEBUG_PORT 1 /* Select UART1 */
|
|
||||||
|
|
||||||
|
|
||||||
/* Debugging configuration - AVR Specific: UBRR
|
|
||||||
--------------------------------------------
|
|
||||||
|
|
||||||
* Here you can set UBRR, this value will select the serial clock speed.
|
|
||||||
* This value depends on your baudrate and clockrate. U2X is by standard 0,
|
|
||||||
* if you would want this 1 for some reason, this can be done in debug.c.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*#define DEBUG_UBRR 51*/ /* 9600bps on 8Mhz */
|
|
||||||
#define DEBUG_UBRR 95 /* 9600bps on 14.7456Mhz */
|
|
||||||
/*#define DEBUG_UBRR 103*/ /* 9600bps on 16Mhz */
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
################################################################################
|
|
||||||
### EFSL - Embedded Filesystems Library ###
|
|
||||||
### ----------------------------------- ###
|
|
||||||
### ###
|
|
||||||
################################################################################
|
|
||||||
|
|
||||||
# This is the configuration file for EFSL. This file will enable your to build
|
|
||||||
# the library if you have GNU make, or compatible, on your system.
|
|
||||||
# If you do not have a make utility on your system, or it cannot be used in this
|
|
||||||
# fashion (when using IDE's, like MSVC or Code composer), please refer to the
|
|
||||||
# documentation on how to build EFSL. It is possible to build EFSL with any C
|
|
||||||
# compiler although it will be a bit more work.
|
|
||||||
|
|
||||||
# C compiler
|
|
||||||
# ----------
|
|
||||||
#
|
|
||||||
# Here you select with what binary the sourcefiles must be compiled
|
|
||||||
|
|
||||||
CC=avr-gcc
|
|
||||||
|
|
||||||
# AR archiver
|
|
||||||
# -----------
|
|
||||||
#
|
|
||||||
# This variable controls what archiver is to be used. This utility is optional,
|
|
||||||
# if you don't have GNU make, you probably need to link differently as well.
|
|
||||||
|
|
||||||
AR=avr-ar
|
|
||||||
|
|
||||||
# Objcopy
|
|
||||||
# --------
|
|
||||||
#
|
|
||||||
# This variable controls what objcopy is to be used. This utility will be used
|
|
||||||
# when the program is converted to an format that your uC understands.
|
|
||||||
|
|
||||||
OBJCOPY=avr-objcopy
|
|
||||||
|
|
||||||
# C compiler options
|
|
||||||
# ------------------
|
|
||||||
#
|
|
||||||
# Here you can configure several options about the compilation.
|
|
||||||
|
|
||||||
DEBUGGING=-g3
|
|
||||||
VERIFY=-Wall
|
|
||||||
ARCHITECTURE=-mmcu=atmega128
|
|
||||||
OPTIMISE=-Os
|
|
||||||
GCFLAGS=$(DEBUGGING) $(VERIFY) $(ARCHITECTURE) $(OPTIMISE)
|
|
||||||
@@ -1,151 +0,0 @@
|
|||||||
#ifndef __EFSL_CONFIG_H__
|
|
||||||
#define __EFSL_CONFIG_H__
|
|
||||||
|
|
||||||
/* Hardware target
|
|
||||||
---------------
|
|
||||||
|
|
||||||
* Here you will define for what hardware-endpoint EFSL should be compiled.
|
|
||||||
* Look in interfaces.h to see what systems are supported, and add your own
|
|
||||||
* there if you need to write your own driver. Then, define the name you
|
|
||||||
* selected for your hardware there here. Make sure that you only select one
|
|
||||||
* device!
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*#define HW_ENDPOINT_LINUX*/
|
|
||||||
/*#define HW_ENDPOINT_ATMEGA128_SD*/
|
|
||||||
/*#define HW_ENDPOINT_DSP_TI6713_SD*/
|
|
||||||
|
|
||||||
#define MULTIPLE_INTERFACE_SUPPORT
|
|
||||||
/*#define HWIFUNC_INIT(x) lf_init(x)
|
|
||||||
#define HWIFUNC_READ(x,y,z) lf_readBuf(x,y,z)
|
|
||||||
#define HWIFUNC_WRITE(x,y,z) lf_writeBuf(x,y,z)
|
|
||||||
#define HWIFUNC_HEADER interfaces/linuxfile.h */
|
|
||||||
|
|
||||||
/* Architecture
|
|
||||||
------------
|
|
||||||
|
|
||||||
* In this section you should configure how large the default variable
|
|
||||||
* types in your system are. This is controlled in types.h in the general
|
|
||||||
* include directory. The selection you make here defines to what the various
|
|
||||||
* e(s|u)int(8,16,32) types will map.
|
|
||||||
* For 32 bit Linux : VARSIZE_LINUX32
|
|
||||||
* For 64 bit Linux : VARSIZE_LINUX64
|
|
||||||
* For AVR's : VARSIZE_ATMEGA
|
|
||||||
* For TMS67XX : VARSIZE_TMS67XX
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define VARSIZE_LINUX32
|
|
||||||
|
|
||||||
/* Memory configuration
|
|
||||||
--------------------
|
|
||||||
|
|
||||||
* Here you must configure wheter your processor can access memory byte
|
|
||||||
* oriented. All x86 processors can do it, AVR's can do it to. Some DSP
|
|
||||||
* or other microcontrollers can't. If you have an 8 bit system you're safe.
|
|
||||||
* If you are really unsure, leave the setting commented out, it will be slower
|
|
||||||
* but it will work for sure.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define BYTE_ALIGNMENT
|
|
||||||
|
|
||||||
/* Cache configuration
|
|
||||||
-------------------
|
|
||||||
|
|
||||||
* Here you must configure how much memory of cache you can/want to use.
|
|
||||||
* The number you put at IOMAN_NUMBUFFER is multiplied by 512. So 1 means
|
|
||||||
* 512 bytes cache, 4 means 2048 bytes cache. More is better.
|
|
||||||
* The number after IOMAN_NUMITERATIONS should be untouched.
|
|
||||||
* The last field (IOMAN_DO_MEMALLOC) is to tell ioman to allocate it's
|
|
||||||
* own memory in it's structure, or not. If you choose to do it yourself
|
|
||||||
* you will have to pass a pointer to the memory as the last argument of
|
|
||||||
* ioman_init.
|
|
||||||
*/
|
|
||||||
#define IOMAN_NUMBUFFER 10
|
|
||||||
#define IOMAN_NUMITERATIONS 3
|
|
||||||
#define IOMAN_DO_MEMALLOC
|
|
||||||
|
|
||||||
/* Cluster pre-allocation
|
|
||||||
----------------------
|
|
||||||
|
|
||||||
* When writing files, the function that performs the actual write has to
|
|
||||||
* calculate how many clusters it will need for that request. It then allocates
|
|
||||||
* that number of new clusters to the file. Since this involves some
|
|
||||||
* calculations and writing of the FAT, you might find it beneficial to limit
|
|
||||||
* the number of allocations, and allow fwrite to pre-allocate a number of
|
|
||||||
* clusters extra. This setting determines how many clusters will be extra
|
|
||||||
* allocated whenever this is required.
|
|
||||||
* Take in carefull consideration how large your clustersize is, putting 10 here
|
|
||||||
* with a clustersize of 32kb means you might waste 320 kb.
|
|
||||||
* The first option is for preallocating files, the other is used when enlarging
|
|
||||||
* a directory to accomodate more files
|
|
||||||
*/
|
|
||||||
#define CLUSTER_PREALLOC_FILE 5
|
|
||||||
#define CLUSTER_PREALLOC_DIRECTORY 2
|
|
||||||
|
|
||||||
/* Endianess configuration
|
|
||||||
-----------------------
|
|
||||||
|
|
||||||
* Here you can configure wheter your architecture is little or big endian. This
|
|
||||||
* is important since all FAT structures are stored in intel little endian
|
|
||||||
* order. So if you have a big endian system the library has to convert all
|
|
||||||
* figures to big endian in order to work.
|
|
||||||
*/
|
|
||||||
/*#define HOST_BIG_ENDIAN*/
|
|
||||||
#define HOST_LITTLE_ENDIAN
|
|
||||||
|
|
||||||
/* Date and Time support
|
|
||||||
---------------------
|
|
||||||
|
|
||||||
* Here you can enable or disable date and time support. If you enable
|
|
||||||
* it you will have to create 6 functions, that are described in the
|
|
||||||
* EFSL manual. If the functions are not present when linking your
|
|
||||||
* program with the library you will get unresolved dependencies.
|
|
||||||
*/
|
|
||||||
/* #define DATE_TIME_SUPPORT */
|
|
||||||
|
|
||||||
/* Error reporting support
|
|
||||||
-----------------------
|
|
||||||
|
|
||||||
* When you receive an error in userland, it usually only gives limited
|
|
||||||
* information (most likely, fail or success). If error detection and
|
|
||||||
* reporting is important for you, you can enable more detailed error
|
|
||||||
* reporting here. This is optional, the costs are 1 byte per object,
|
|
||||||
* and a small increase in code size.
|
|
||||||
* You can enable error recording for all object, or you can select the
|
|
||||||
* object manually.
|
|
||||||
* For full error reporting use FULL_ERROR_SUPPORT
|
|
||||||
* For only the base-core of the library use BASE_ERROR_SUPPORT
|
|
||||||
* For IO/Man use ERRSUP_IOMAN
|
|
||||||
* For Disc use ERRSUP_IOMAN
|
|
||||||
* For Part use ERRSUP_PARTITION
|
|
||||||
* For Fs use ERRSUP_FILESYSTEM
|
|
||||||
* For File use ERRSUP_FILE
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define FULL_ERROR_SUPPORT
|
|
||||||
/*#define BASE_ERROR_SUPPORT*/
|
|
||||||
|
|
||||||
|
|
||||||
/* Debugging configuration
|
|
||||||
-----------------------
|
|
||||||
|
|
||||||
* Here you can configure the debugging behaviour. Debugging is different
|
|
||||||
* on every platform (see debug.h for more information).
|
|
||||||
* If your hardware has no means of output (printf) dont define any anything,
|
|
||||||
* and nothing will happen. For real world use debugging should be turned off.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*#define DEBUG*/
|
|
||||||
/*#define DO_FUNC_DEBUG*/
|
|
||||||
|
|
||||||
/* List options
|
|
||||||
------------
|
|
||||||
|
|
||||||
* In this section you can configure what kind of data you will get from
|
|
||||||
* directory listing requests. Please refer to the documentation for
|
|
||||||
* more information
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define LIST_MAXLENFILENAME 12
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
################################################################################
|
|
||||||
### EFSL - Embedded Filesystems Library ###
|
|
||||||
### ----------------------------------- ###
|
|
||||||
### ###
|
|
||||||
################################################################################
|
|
||||||
|
|
||||||
# This is the configuration file for EFSL. This file will enable your to build
|
|
||||||
# the library if you have GNU make, or compatible, on your system.
|
|
||||||
# If you do not have a make utility on your system, or it cannot be used in this
|
|
||||||
# fashion (when using IDE's, like MSVC or Code composer), please refer to the
|
|
||||||
# documentation on how to build EFSL. It is possible to build EFSL with any C
|
|
||||||
# compiler although it will be a bit more work.
|
|
||||||
|
|
||||||
# C compiler
|
|
||||||
# ----------
|
|
||||||
#
|
|
||||||
# Here you select with what binary the sourcefiles must be compiled
|
|
||||||
|
|
||||||
CC=gcc
|
|
||||||
|
|
||||||
# AR archiver
|
|
||||||
# -----------
|
|
||||||
#
|
|
||||||
# This variable controls what archiver is to be used. This utility is optional,
|
|
||||||
# if you don't have GNU make, you probably need to link differently as well.
|
|
||||||
|
|
||||||
AR=ar
|
|
||||||
|
|
||||||
# C compiler options
|
|
||||||
# ------------------
|
|
||||||
#
|
|
||||||
# Here you can configure several options about the compilation.
|
|
||||||
|
|
||||||
DEBUGGING=-g3
|
|
||||||
VERIFY=-Wall -pedantic -ansi
|
|
||||||
ARCHITECTURE=-march=i386
|
|
||||||
OPTIMISE=-O0
|
|
||||||
GCFLAGS=$(DEBUGGING) $(VERIFY) $(ARCHITECTURE) $(OPTIMISE)
|
|
||||||
@@ -1,151 +0,0 @@
|
|||||||
#ifndef __EFSL_CONFIG_H__
|
|
||||||
#define __EFSL_CONFIG_H__
|
|
||||||
|
|
||||||
/* Hardware target
|
|
||||||
---------------
|
|
||||||
|
|
||||||
* Here you will define for what hardware-endpoint EFSL should be compiled.
|
|
||||||
* Look in interfaces.h to see what systems are supported, and add your own
|
|
||||||
* there if you need to write your own driver. Then, define the name you
|
|
||||||
* selected for your hardware there here. Make sure that you only select one
|
|
||||||
* device!
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*#define HW_ENDPOINT_LINUX*/
|
|
||||||
/*#define HW_ENDPOINT_ATMEGA128_SD*/
|
|
||||||
/*#define HW_ENDPOINT_DSP_TI6713_SD*/
|
|
||||||
|
|
||||||
#define MULTIPLE_INTERFACE_SUPPORT
|
|
||||||
/*#define HWIFUNC_INIT(x) lf_init(x)
|
|
||||||
#define HWIFUNC_READ(x,y,z) lf_readBuf(x,y,z)
|
|
||||||
#define HWIFUNC_WRITE(x,y,z) lf_writeBuf(x,y,z)
|
|
||||||
#define HWIFUNC_HEADER interfaces/linuxfile.h */
|
|
||||||
|
|
||||||
/* Architecture
|
|
||||||
------------
|
|
||||||
|
|
||||||
* In this section you should configure how large the default variable
|
|
||||||
* types in your system are. This is controlled in types.h in the general
|
|
||||||
* include directory. The selection you make here defines to what the various
|
|
||||||
* e(s|u)int(8,16,32) types will map.
|
|
||||||
* For 32 bit Linux : VARSIZE_LINUX32
|
|
||||||
* For 64 bit Linux : VARSIZE_LINUX64
|
|
||||||
* For AVR's : VARSIZE_ATMEGA
|
|
||||||
* For TMS67XX : VARSIZE_TMS67XX
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define VARSIZE_LINUX64
|
|
||||||
|
|
||||||
/* Memory configuration
|
|
||||||
--------------------
|
|
||||||
|
|
||||||
* Here you must configure wheter your processor can access memory byte
|
|
||||||
* oriented. All x86 processors can do it, AVR's can do it to. Some DSP
|
|
||||||
* or other microcontrollers can't. If you have an 8 bit system you're safe.
|
|
||||||
* If you are really unsure, leave the setting commented out, it will be slower
|
|
||||||
* but it will work for sure.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define BYTE_ALIGNMENT
|
|
||||||
|
|
||||||
/* Cache configuration
|
|
||||||
-------------------
|
|
||||||
|
|
||||||
* Here you must configure how much memory of cache you can/want to use.
|
|
||||||
* The number you put at IOMAN_NUMBUFFER is multiplied by 512. So 1 means
|
|
||||||
* 512 bytes cache, 4 means 2048 bytes cache. More is better.
|
|
||||||
* The number after IOMAN_NUMITERATIONS should be untouched.
|
|
||||||
* The last field (IOMAN_DO_MEMALLOC) is to tell ioman to allocate it's
|
|
||||||
* own memory in it's structure, or not. If you choose to do it yourself
|
|
||||||
* you will have to pass a pointer to the memory as the last argument of
|
|
||||||
* ioman_init.
|
|
||||||
*/
|
|
||||||
#define IOMAN_NUMBUFFER 10
|
|
||||||
#define IOMAN_NUMITERATIONS 3
|
|
||||||
#define IOMAN_DO_MEMALLOC
|
|
||||||
|
|
||||||
/* Cluster pre-allocation
|
|
||||||
----------------------
|
|
||||||
|
|
||||||
* When writing files, the function that performs the actual write has to
|
|
||||||
* calculate how many clusters it will need for that request. It then allocates
|
|
||||||
* that number of new clusters to the file. Since this involves some
|
|
||||||
* calculations and writing of the FAT, you might find it beneficial to limit
|
|
||||||
* the number of allocations, and allow fwrite to pre-allocate a number of
|
|
||||||
* clusters extra. This setting determines how many clusters will be extra
|
|
||||||
* allocated whenever this is required.
|
|
||||||
* Take in carefull consideration how large your clustersize is, putting 10 here
|
|
||||||
* with a clustersize of 32kb means you might waste 320 kb.
|
|
||||||
* The first option is for preallocating files, the other is used when enlarging
|
|
||||||
* a directory to accomodate more files
|
|
||||||
*/
|
|
||||||
#define CLUSTER_PREALLOC_FILE 5
|
|
||||||
#define CLUSTER_PREALLOC_DIRECTORY 2
|
|
||||||
|
|
||||||
/* Endianess configuration
|
|
||||||
-----------------------
|
|
||||||
|
|
||||||
* Here you can configure wheter your architecture is little or big endian. This
|
|
||||||
* is important since all FAT structures are stored in intel little endian
|
|
||||||
* order. So if you have a big endian system the library has to convert all
|
|
||||||
* figures to big endian in order to work.
|
|
||||||
*/
|
|
||||||
/*#define HOST_BIG_ENDIAN*/
|
|
||||||
#define HOST_LITTLE_ENDIAN
|
|
||||||
|
|
||||||
/* Date and Time support
|
|
||||||
---------------------
|
|
||||||
|
|
||||||
* Here you can enable or disable date and time support. If you enable
|
|
||||||
* it you will have to create 6 functions, that are described in the
|
|
||||||
* EFSL manual. If the functions are not present when linking your
|
|
||||||
* program with the library you will get unresolved dependencies.
|
|
||||||
*/
|
|
||||||
/* #define DATE_TIME_SUPPORT */
|
|
||||||
|
|
||||||
/* Error reporting support
|
|
||||||
-----------------------
|
|
||||||
|
|
||||||
* When you receive an error in userland, it usually only gives limited
|
|
||||||
* information (most likely, fail or success). If error detection and
|
|
||||||
* reporting is important for you, you can enable more detailed error
|
|
||||||
* reporting here. This is optional, the costs are 1 byte per object,
|
|
||||||
* and a small increase in code size.
|
|
||||||
* You can enable error recording for all object, or you can select the
|
|
||||||
* object manually.
|
|
||||||
* For full error reporting use FULL_ERROR_SUPPORT
|
|
||||||
* For only the base-core of the library use BASE_ERROR_SUPPORT
|
|
||||||
* For IO/Man use ERRSUP_IOMAN
|
|
||||||
* For Disc use ERRSUP_IOMAN
|
|
||||||
* For Part use ERRSUP_PARTITION
|
|
||||||
* For Fs use ERRSUP_FILESYSTEM
|
|
||||||
* For File use ERRSUP_FILE
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define FULL_ERROR_SUPPORT
|
|
||||||
/*#define BASE_ERROR_SUPPORT*/
|
|
||||||
|
|
||||||
|
|
||||||
/* Debugging configuration
|
|
||||||
-----------------------
|
|
||||||
|
|
||||||
* Here you can configure the debugging behaviour. Debugging is different
|
|
||||||
* on every platform (see debug.h for more information).
|
|
||||||
* If your hardware has no means of output (printf) dont define any anything,
|
|
||||||
* and nothing will happen. For real world use debugging should be turned off.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*#define DEBUG*/
|
|
||||||
/*#define DO_FUNC_DEBUG*/
|
|
||||||
|
|
||||||
/* List options
|
|
||||||
------------
|
|
||||||
|
|
||||||
* In this section you can configure what kind of data you will get from
|
|
||||||
* directory listing requests. Please refer to the documentation for
|
|
||||||
* more information
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define LIST_MAXLENFILENAME 12
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
################################################################################
|
|
||||||
### EFSL - Embedded Filesystems Library ###
|
|
||||||
### ----------------------------------- ###
|
|
||||||
### ###
|
|
||||||
################################################################################
|
|
||||||
|
|
||||||
# This is the configuration file for EFSL. This file will enable your to build
|
|
||||||
# the library if you have GNU make, or compatible, on your system.
|
|
||||||
# If you do not have a make utility on your system, or it cannot be used in this
|
|
||||||
# fashion (when using IDE's, like MSVC or Code composer), please refer to the
|
|
||||||
# documentation on how to build EFSL. It is possible to build EFSL with any C
|
|
||||||
# compiler although it will be a bit more work.
|
|
||||||
|
|
||||||
# C compiler
|
|
||||||
# ----------
|
|
||||||
#
|
|
||||||
# Here you select with what binary the sourcefiles must be compiled
|
|
||||||
|
|
||||||
CC=gcc
|
|
||||||
|
|
||||||
# AR archiver
|
|
||||||
# -----------
|
|
||||||
#
|
|
||||||
# This variable controls what archiver is to be used. This utility is optional,
|
|
||||||
# if you don't have GNU make, you probably need to link differently as well.
|
|
||||||
|
|
||||||
AR=ar
|
|
||||||
|
|
||||||
# C compiler options
|
|
||||||
# ------------------
|
|
||||||
#
|
|
||||||
# Here you can configure several options about the compilation.
|
|
||||||
|
|
||||||
DEBUGGING=-g3
|
|
||||||
VERIFY=-Wall -pedantic -ansi
|
|
||||||
ARCHITECTURE=-march=k8
|
|
||||||
OPTIMISE=-O0
|
|
||||||
GCFLAGS=$(DEBUGGING) $(VERIFY) $(ARCHITECTURE) $(OPTIMISE)
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
config-linux.h
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
config-linux.makefile
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
all: manual.tex
|
|
||||||
latex manual.tex
|
|
||||||
latex manual.tex # Needs to be done a second time to make sure that the contents table is correct
|
|
||||||
dvips -o manual.ps manual.dvi
|
|
||||||
dvipdfm manual.dvi
|
|
||||||
|
|
||||||
clean:
|
|
||||||
rm -f manual.aux
|
|
||||||
rm -f manual.dvi
|
|
||||||
rm -f manual.log
|
|
||||||
rm -f manual.pdf
|
|
||||||
rm -f manual.ps
|
|
||||||
rm -f manual.toc
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,117 +0,0 @@
|
|||||||
\documentclass[a4paper,fleqn]{article}
|
|
||||||
|
|
||||||
\usepackage{listings}
|
|
||||||
\usepackage{graphicx}
|
|
||||||
\usepackage{amsmath}
|
|
||||||
\usepackage{amssymb}
|
|
||||||
\usepackage{color}
|
|
||||||
\usepackage{array}
|
|
||||||
\usepackage{verbatim}
|
|
||||||
\usepackage{longtable}
|
|
||||||
|
|
||||||
\newcommand{\filename}[1]{
|
|
||||||
\textsf{#1}
|
|
||||||
}
|
|
||||||
\newcommand{\code}[1]{
|
|
||||||
\texttt{#1}
|
|
||||||
}
|
|
||||||
\newcommand{\external}[1]{
|
|
||||||
\textbf{#1}
|
|
||||||
}
|
|
||||||
|
|
||||||
\newcommand{\thead}[1]{
|
|
||||||
\textbf{#1}
|
|
||||||
}
|
|
||||||
|
|
||||||
%\usepackage[latin1]{inputenc}
|
|
||||||
%\usepackage[T1]{fontenc}
|
|
||||||
|
|
||||||
\lstset{language=C}
|
|
||||||
|
|
||||||
\begin{document}
|
|
||||||
\title{\Huge{EFSL}\\\Large{Embedded Filesystems Library - 0.3}}
|
|
||||||
\author{Lennart Yseboodt\\Michael De Nil}
|
|
||||||
\date{$\copyright$ 2005}
|
|
||||||
\maketitle
|
|
||||||
|
|
||||||
\newpage
|
|
||||||
\tableofcontents
|
|
||||||
|
|
||||||
\setlength{\parindent}{0pt}
|
|
||||||
\setlength{\parskip}{1ex plus 0.5ex minus 0.2ex}
|
|
||||||
|
|
||||||
\newpage
|
|
||||||
\section{Document Outdated!}
|
|
||||||
{\Huge{
|
|
||||||
This document is outdated and is in the progress of being renewed.\\
|
|
||||||
\newline\newline
|
|
||||||
If you are just starting with Efsl, we recommend you to start with the stable
|
|
||||||
0.2-branch. This version is currently not really usable, and is intended for people
|
|
||||||
working on the code.
|
|
||||||
}}
|
|
||||||
\newpage
|
|
||||||
\section{Preface}
|
|
||||||
\input{pages/preface}
|
|
||||||
\newpage
|
|
||||||
\section{Getting started}
|
|
||||||
\subsection{On Linux (file) (0.2)}
|
|
||||||
\input{pages/linux}
|
|
||||||
\newpage
|
|
||||||
\subsection{On AVR (SD-Card) (0.3)}
|
|
||||||
\input{pages/avr}
|
|
||||||
\newpage
|
|
||||||
\subsection{On DSP (SD-Card) (0.2)}
|
|
||||||
\input{pages/tms6713}
|
|
||||||
|
|
||||||
\newpage
|
|
||||||
\section{Configuring EFSL (0.2)}
|
|
||||||
\input{pages/config}
|
|
||||||
|
|
||||||
\newpage
|
|
||||||
\section{EFSL Functions}
|
|
||||||
\subsection{Date and time support (0.2)}
|
|
||||||
\input{pages/dateandtime}
|
|
||||||
\newpage
|
|
||||||
\subsection{efs\_init (0.2)}
|
|
||||||
\input{pages/efs_init}
|
|
||||||
\newpage
|
|
||||||
\subsection{file\_fopen (0.2)}
|
|
||||||
\input{pages/file_fopen}
|
|
||||||
\newpage
|
|
||||||
\subsection{file\_fclose (0.2)}
|
|
||||||
\input{pages/file_fclose}
|
|
||||||
\newpage
|
|
||||||
\subsection{file\_read (0.2)}
|
|
||||||
\input{pages/file_read}
|
|
||||||
\newpage
|
|
||||||
\subsection{file\_write (0.2)}
|
|
||||||
\input{pages/file_write}
|
|
||||||
\newpage
|
|
||||||
\subsection{mkdir (0.2)}
|
|
||||||
\input{pages/mkdir}
|
|
||||||
\newpage
|
|
||||||
\subsection{ls\_openDir (0.2)}
|
|
||||||
\input{pages/lsopendir}
|
|
||||||
\newpage
|
|
||||||
\subsection{ls\_getNext (0.2)}
|
|
||||||
\input{pages/lsgetnext}
|
|
||||||
\newpage
|
|
||||||
|
|
||||||
\newpage
|
|
||||||
\section{Developer notes}
|
|
||||||
\subsection{Integer types (0.2)}
|
|
||||||
\input{pages/types}
|
|
||||||
\subsection{Debugging (0.2)}
|
|
||||||
\input{pages/debug}
|
|
||||||
\subsection{Adding support for a new endpoint (0.2)}
|
|
||||||
\input{pages/driver}
|
|
||||||
\subsection{I/O Manager (0.2)}
|
|
||||||
\input{pages/ioman}
|
|
||||||
\subsection{C library for EFSL (0.2)}
|
|
||||||
\input{pages/plibc}
|
|
||||||
|
|
||||||
\newpage
|
|
||||||
\section{Legal notes}
|
|
||||||
\input{pages/license}
|
|
||||||
|
|
||||||
\end{document}
|
|
||||||
@@ -1,223 +0,0 @@
|
|||||||
This section describes how to implement Efsl on a AVR $\mu C$ connected to
|
|
||||||
an SD-Card (SPI). For getting efsl to compile, the avr-gcc compiler and
|
|
||||||
avr-libc library are required. On Windows you should install WinAVR
|
|
||||||
(http://winavr.sourceforge.net/), on Linux you can install the packages
|
|
||||||
separately (see http://www.nongnu.org/avr-libc/user-manual/install\_tools.html
|
|
||||||
for a nice howto).
|
|
||||||
\subsubsection{Hardware}
|
|
||||||
First, you need set up a prototype in which you connect the CD, CMD, DAT0
|
|
||||||
\& CLK lines from the SD-Card to /CS, MOSI, MISO \& SCK from the Atmega.
|
|
||||||
\newline
|
|
||||||
\includegraphics[scale=0.65]{pics/sdcard.eps}
|
|
||||||
\newline
|
|
||||||
%\parbox[c]{.4\textwidth}{\begin{center}\includegraphics[width=.4\textwidth]{pics/sdconnection}\end{center}}
|
|
||||||
\parbox[c]{.5\textwidth}{
|
|
||||||
Connect the following lines on the SD-card:
|
|
||||||
\begin{itemize}
|
|
||||||
\item{Pin 9 (DAT2) - NC\\(or pull-up to 3.3V)}
|
|
||||||
\item{Pin 1 (CD) - Any pin on the Atmega128}
|
|
||||||
\item{Pin 2 (CMD) - MOSI\\(pin 12 on the Atmega128)}
|
|
||||||
\item{Pin 3 (Vss) - GND}
|
|
||||||
\item{Pin 4 (Vdd) - +3.3V}
|
|
||||||
\item{Pin 5 (CLK) - SCK\\(pin 11 on the Atmega128)}
|
|
||||||
\item{Pin 6 (Vss) - GND}
|
|
||||||
\item{Pin 7 (DAT0) - MISO\\(pin 12 on the Atmega128)}
|
|
||||||
\item{Pin 8 (DAT1) - NC\\(or pull-up to 3.3V)}
|
|
||||||
\end{itemize}
|
|
||||||
}
|
|
||||||
\parbox[c]{.5\textwidth}{\begin{center}
|
|
||||||
\includegraphics[width=.5\textwidth]{pics/sdconnection}
|
|
||||||
\newline\newline
|
|
||||||
Remark: this schematic includes pull-up's to 3.3V, which
|
|
||||||
can be left off.
|
|
||||||
\end{center}}
|
|
||||||
\newline
|
|
||||||
Remark 1: Make sure that your $\mu C$ is running on 3,3V, so you don't
|
|
||||||
damage your SD-Card.\newline
|
|
||||||
\newline
|
|
||||||
Remark 2: CD is currently static set to PB0, but will become variable
|
|
||||||
in future releases.
|
|
||||||
\subsubsection{Download \& Compile}
|
|
||||||
Let's get started:
|
|
||||||
\begin{enumerate}
|
|
||||||
\item{Get the latest release of efsl on http://www.sf.net/projects/efsl/}
|
|
||||||
\item{Unpack the library (on Windows, you can use WinACE or WinRAR)}
|
|
||||||
\item{Copy in directory \filename{conf} the file
|
|
||||||
\filename{config-avr.h} to \filename{config.h}}
|
|
||||||
\item{Copy in directory \filename{conf} the file
|
|
||||||
\filename{config-avr.makefile} to \filename{config.makefile}}
|
|
||||||
\item{Compile the library (\code{make avr})}
|
|
||||||
\end{enumerate}
|
|
||||||
Now you should have the following files in a directory called {lib}:
|
|
||||||
\begin{itemize}
|
|
||||||
\item{\filename{libefsl-base.a}}
|
|
||||||
\item{\filename{libefsl-fs-vfat.a}}
|
|
||||||
\item{\filename{libefsl-prot-sdspi.a}}
|
|
||||||
\item{\filename{libefsl-hwd-atmega\_spi.a}}
|
|
||||||
\end{itemize}
|
|
||||||
\subsubsection{Example}
|
|
||||||
Since Efsl itself is only a library, it's not supposed to do anything out of
|
|
||||||
the box, than just compile. To get started, we'll show here a small example
|
|
||||||
program that opens an existing file and writes the content to a new file.
|
|
||||||
\newline\newline
|
|
||||||
First, create a new directory in which you put the compiled efsl-library
|
|
||||||
(\filename{libefsl.a}) and create a new file called \filename{avrtest.c} containing:
|
|
||||||
\lstset{numbers=left, stepnumber=1, numberstyle=\small, numbersep=5pt, tabsize=4}
|
|
||||||
\begin{lstlisting}
|
|
||||||
#include <efs.h>
|
|
||||||
#include <sd.h>
|
|
||||||
#include <atmega_spi.h>
|
|
||||||
|
|
||||||
void hang(void);
|
|
||||||
|
|
||||||
void main(void)
|
|
||||||
{
|
|
||||||
efsl_storage_conf storage_conf;
|
|
||||||
efsl_fs_conf fs_conf;
|
|
||||||
|
|
||||||
efsl_storage storage;
|
|
||||||
efsl_fs fs;
|
|
||||||
File file_r;
|
|
||||||
File file_w;
|
|
||||||
|
|
||||||
atmegaSpiInterface spi_interface;
|
|
||||||
SdSpiProtocol sd_protocol;
|
|
||||||
|
|
||||||
char buf[512];
|
|
||||||
unsigned short e;
|
|
||||||
|
|
||||||
/* Init */
|
|
||||||
spi_interface.pinSelect=0x01;
|
|
||||||
|
|
||||||
sd_protocol.spiHwInterface=&spi_interface;
|
|
||||||
sd_protocol.spiHwInit=(void *)atmega_spi_init;
|
|
||||||
sd_protocol.spiSendByte=(void *)atmega_spi_send;
|
|
||||||
|
|
||||||
storage_conf.hwObject=&sd_protocol;
|
|
||||||
storage_conf.if_init_fptr=(void *)sd_Init;
|
|
||||||
storage_conf.if_read_fptr=(void *)sd_readSector;
|
|
||||||
storage_conf.if_write_fptr=(void *)sd_writeSector;
|
|
||||||
storage_conf.if_ioctl_fptr=(void *)sd_ioctl;
|
|
||||||
storage_conf.ioman_bufmem=0;
|
|
||||||
|
|
||||||
fs_conf.no_partitions=0;
|
|
||||||
fs_conf.storage=&storage;
|
|
||||||
|
|
||||||
if(efsl_initStorage(&storage,&storage_conf)){
|
|
||||||
hang();
|
|
||||||
}
|
|
||||||
|
|
||||||
if(efsl_initFs(&fs,&fs_conf)){
|
|
||||||
hang();
|
|
||||||
}
|
|
||||||
|
|
||||||
if(file_fopen(&file_r,&fs.filesystem,"orig.txt",'r')!=0){
|
|
||||||
hang();
|
|
||||||
}
|
|
||||||
|
|
||||||
if(file_fopen(&file_w,&fs.filesystem,"copy.txt",'w')!=0){
|
|
||||||
hang();
|
|
||||||
}
|
|
||||||
|
|
||||||
if(file_fopen(&file_r,&efs.myFs,"orig.txt",'r')!=0){
|
|
||||||
hang();
|
|
||||||
}
|
|
||||||
|
|
||||||
while((e=file_read(&file_r,512,buf))){
|
|
||||||
file_write(&file_w,e,buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
file_fclose(&file_r);
|
|
||||||
file_fclose(&file_w);
|
|
||||||
|
|
||||||
fs_umount(&fs.filesystem);
|
|
||||||
|
|
||||||
hang();
|
|
||||||
}
|
|
||||||
|
|
||||||
void hang(void)
|
|
||||||
{
|
|
||||||
while((1))
|
|
||||||
_NOP();
|
|
||||||
}
|
|
||||||
\end{lstlisting}
|
|
||||||
$ $\newline
|
|
||||||
Some extra information on the code above: TODO
|
|
||||||
%\begin{itemize}
|
|
||||||
% \item{Line 1: The header file for efsl is included here. When using the
|
|
||||||
% basic efsl functions, \filename{efs.h} is the only header file on the
|
|
||||||
% efsl library that needs to be included.}
|
|
||||||
% \item{Line 7: The object efs is created, this object will contain
|
|
||||||
% information about the hardware layer, the partition table and
|
|
||||||
% the disc.}
|
|
||||||
% \item{Line 8: The objects \code{file\_r} and \code{file\_w} are created, these objects
|
|
||||||
% will contain information about the files that we will open on the
|
|
||||||
% efs-object.}
|
|
||||||
% \item{Line 9: A buffer of 512 bytes is allocated. This buffer will be
|
|
||||||
% used for reading and writing blocks of data.}
|
|
||||||
% \item{Line 12: Call of \code{efs\_init()}, which will initialize the efs-object.
|
|
||||||
% To this function we pass:
|
|
||||||
% \begin{enumerate}
|
|
||||||
% \item{A pointer to the efs-object.}
|
|
||||||
% \item{A pointer to the file that contains the partition table /
|
|
||||||
% file system (in this example, we select a device as file).}
|
|
||||||
% \end{enumerate}
|
|
||||||
% If this function returns 0, it means that a valid fat partition is
|
|
||||||
% found on the SD-card connected.
|
|
||||||
% If no valid fat-filesystem is found, or the file does not exist, the
|
|
||||||
% function returns a negative value. In this example we then go to an
|
|
||||||
% infinite loop to prevent the program to continue.}
|
|
||||||
% \item{Line 16 \& 20: Call of \code{file\_fopen()}, which will initialize the
|
|
||||||
% file-objects. To this function we pass:
|
|
||||||
% \begin{enumerate}
|
|
||||||
% \item{A pointer to the file-object.}
|
|
||||||
% \item{A pointer to the filesystem-object.}
|
|
||||||
% \item{A pointer to the filename.}
|
|
||||||
% \item{A char containing the the mode (read, write, append).}
|
|
||||||
% \end{enumerate}
|
|
||||||
% If this function returns 0, it means the file has successfully been
|
|
||||||
% opened for reading / writing / appending.
|
|
||||||
% If the file could not be opened (because for example a file already
|
|
||||||
% exists), a negative value is returned.}
|
|
||||||
% \item{Line 24: Call of \code{file\_read()}, which will read a given value of
|
|
||||||
% bytes (in this example 512) from a file and put it's content into
|
|
||||||
% the buffer passed (in this example called buf). This function returns
|
|
||||||
% the amount of bytes read, so the while-loop will be executed as long
|
|
||||||
% as there are bytes left in the file.}
|
|
||||||
% \item{Line 25: Call of \code{file\_write()}, which will write a given value
|
|
||||||
% of bytes (in this example, the amount of bytes that was read
|
|
||||||
% by \code{file\_read()}) from the buffer passed to a file. This function returns
|
|
||||||
% the amount of bytes written.}
|
|
||||||
% \item{Line 28 \& 29: Call of \code{file\_fclose()}, which will close the
|
|
||||||
% file-objects.}
|
|
||||||
% \item{Line 31: Call of \code{fs\_umount()}, which will write all buffers to
|
|
||||||
% the the SD-card.}
|
|
||||||
%\end{itemize}
|
|
||||||
\subsubsection{Testing}
|
|
||||||
So now let's test the program:
|
|
||||||
\begin{enumerate}
|
|
||||||
\item
|
|
||||||
{ Compile the program:
|
|
||||||
\begin{itemize}
|
|
||||||
\item{On Linux (with avr-gcc): avr-gcc -I/home/user/src/base/include -I/home/user/src/include -I/home/user/src/fs/vfat/include -I/home/user/src/hwdrivers/atmega\_spi/include -I/home/user/src/protocols/sdcard\_spi/include -I/home/user/conf -ffreestanding -mmcu=atmega128 -Os -o avrtest.o avrtest.c -L/home/user/lib -lefsl-base -lefsl-fs-vfat -lefsl-hwd-atmega\_spi -lefsl-prot-sdspi}
|
|
||||||
\item{On Windows (with WinAVR): replace all slashes with backslashes}
|
|
||||||
\end{itemize}
|
|
||||||
}
|
|
||||||
\item{Generate a hexfile
|
|
||||||
(avr-objcopy -j .text -j .data -O ihex avrtest.o avrtest.hex)}
|
|
||||||
\item{Connect an SD-card to your Atmega128 with a file called
|
|
||||||
\filename{orig.txt} on it.}
|
|
||||||
\item
|
|
||||||
{
|
|
||||||
Flash the hex file into your $\mu C$.
|
|
||||||
\begin{itemize}
|
|
||||||
\item{On Linux: avrdude -P /dev/ttyUSB0 -c stk500 -p m128 -Uflash:w:avrtest.hex}
|
|
||||||
\item{On Windows: use Atmel AVR-Studio}
|
|
||||||
\end{itemize}
|
|
||||||
}
|
|
||||||
\item{Reset your $\mu C$ and wait some time (depending on how big
|
|
||||||
the file \filename{orig.txt} is).}
|
|
||||||
\item{Disconnect the SD-card, so you can put it in your card reader
|
|
||||||
and find out if the file \filename{orig.txt} is copied to
|
|
||||||
\filename{copy.txt}.}
|
|
||||||
\end{enumerate}
|
|
||||||
@@ -1,180 +0,0 @@
|
|||||||
In this section we're going to talk about the configuration file (\filename{config.h}),
|
|
||||||
that defines the behavior of the library. In the configuration files there are many
|
|
||||||
settings, most of which default to safe or 'standard' compliant settings.
|
|
||||||
|
|
||||||
For every platform we try to deliver a sample configuration, with setting tweaked for
|
|
||||||
that architecture. This documentation only refers to the general elements which are
|
|
||||||
tied to the library rather that the target hardware.
|
|
||||||
|
|
||||||
\subsection{Hardware target}
|
|
||||||
Here you will define what kind of hardware you will be using. Please refer to
|
|
||||||
section \ref{hwdriver} to learn how to write a hardware endpoint.
|
|
||||||
Here you must \code{\#define} the name of your hardware endpoint.
|
|
||||||
The following list contains the endpoints that the library ships with.\\
|
|
||||||
\begin{tabular}{|l|p{8cm}|}
|
|
||||||
\hline
|
|
||||||
\code{HW\_ENDPOINT\_LINUX}& This endpoint uses a regular file as
|
|
||||||
a "disc" containing a filesystem. This is a great endpoint for
|
|
||||||
testing and debugging. All development is done using this emulation.\\
|
|
||||||
\code{HW\_ENDPOINT\_ATMEGA128\_SD}& This endpoint is for the Atmel ATMega 128
|
|
||||||
with an SD card attached to the SPI pins of the device. Several settings
|
|
||||||
that are specific for this endpoint can be found in the AVR sample
|
|
||||||
configuration. A Makefile is also provided for compiling the EFSL library
|
|
||||||
using avr-gcc.\\
|
|
||||||
\code{HW\_ENDPOINT\_DSP\_TI6713\_SD}& This endpoint is for a TI DSP, it should
|
|
||||||
work with any McBSP port, due to the infinite amount of options, you should
|
|
||||||
refer to the source code of this endpoint for fine tuning, or selecting what
|
|
||||||
port to use (defaults to McBSP0).\\
|
|
||||||
\hline
|
|
||||||
\end{tabular}
|
|
||||||
|
|
||||||
\subsection{Memory configuration}
|
|
||||||
This section only has one option, called \code{BYTE\_ALIGNMENT}. If you define
|
|
||||||
this keyword the library will assume that your CPU is capable of accessing the
|
|
||||||
memory in any way it sees fit. This is the case on AVR, because they are 8 bit
|
|
||||||
processors, and it is also the case on Intel x86 hardware. Both architectures
|
|
||||||
can read and write words, or double words on any location in memory, be it
|
|
||||||
word aligned or not.
|
|
||||||
|
|
||||||
However, some CPU's, are not capable of doing this, and require that all double words
|
|
||||||
are aligned on a double word boundary, and all word are aligned on a word boundary.
|
|
||||||
This causes problems with some of the casts that are performed in EFSL. If you have such
|
|
||||||
a CPU, then you must comment this option out. The effect is that special functions
|
|
||||||
will be used to copy or cast memory. These functions work around the problem by
|
|
||||||
using memCpy, or manually copying elements of the structs that are normally cast when
|
|
||||||
\code{BYTE\_ALIGNMENT} is defined.
|
|
||||||
|
|
||||||
If you have an 8 bit architecture, or are running on PC, there is no need to turn this
|
|
||||||
off. If you do, the library will work fine, and maybe even without slowdown.
|
|
||||||
On architectures that do have the alignment problem, you should turn this flag off.
|
|
||||||
Failure to do so will result in undefined behavior.
|
|
||||||
|
|
||||||
\subsection{Cache configuration}
|
|
||||||
This section is dedicated to configuring the cache memory for the library. Caching
|
|
||||||
is performed by the IOMan object, see section \ref{ioman}.
|
|
||||||
\subsubsection*{IOMAN\_NUMBUFFER}
|
|
||||||
This number determines how much memory will be used for caching. Since this
|
|
||||||
is sector based one \code{IOMAN\_NUMBUFFER} equals to 512 byes of memory, plus
|
|
||||||
a small overhead in settings (approximately 8 bytes). This number is also affected
|
|
||||||
by \code{IOMAN\_NUMITERATIONS}.
|
|
||||||
|
|
||||||
You should carefully consider how much memory you will dedicate to caching. A too
|
|
||||||
low number will cause excessive data transfer to and from the disc, where a too high
|
|
||||||
number will simply be a waste of memory.
|
|
||||||
|
|
||||||
A good rule of thumb is to use 1 buffer per filesystem you create, and 2 buffers
|
|
||||||
per file you want to use simultaneously. So for a simple application with
|
|
||||||
one filesystem, and one file operation, 2 or 3 buffers will be fine. If you have memory
|
|
||||||
to spare, you can use 6 buffers. Using more buffers will have a minimal effect on
|
|
||||||
performance.
|
|
||||||
|
|
||||||
If you want to seek and rewrite portions of a file, add an extra buffer for that file.
|
|
||||||
Using the list function or creating directories will be disc intensive, try to smoothen
|
|
||||||
it by using an extra 3 buffer for either operation.
|
|
||||||
|
|
||||||
It is perfectly possible to have multiple files op for reading and writing, on different
|
|
||||||
filesystems, with listing etc and only using 1 buffer. It will be a tough blow on
|
|
||||||
performance though.
|
|
||||||
\subsubsection*{IOMAN\_NUMITERATION}
|
|
||||||
This number controls how many stack places each cache place gets. Refer to the IOMan
|
|
||||||
section for an explanation. In short, if you only have 1 buffer, leave it at 3. If you
|
|
||||||
use more than 4 buffers try decreasing the number to 2 or 1 for a small memory gain.
|
|
||||||
|
|
||||||
If you get errors, it means you have set it too low (see error support). It is best
|
|
||||||
to leave this at the default setting (do not increase it), unless you know what you
|
|
||||||
are doing.
|
|
||||||
\subsubsection*{IOMAN\_DOMEMALLOC}
|
|
||||||
This configures how IOMan will get it's memory. If you leave it enable, the memory
|
|
||||||
will be allocated by IOMan itself. That means that when you declare the IOMan object
|
|
||||||
it will have a member the size of $512 \cdot \mathrm{IOMAN\_NUMBUFFER}$.
|
|
||||||
That also means that that huge lump of memory will reside on the stack. On a true embedded platform with no malloc, this is your best option.
|
|
||||||
The last argument of \code{ioman\_init} will be ignored.
|
|
||||||
|
|
||||||
If you comment this out,IOMan will take a \code{euint8*} pointer as it's third
|
|
||||||
argument to \code{ioman\_init}. It will use the memory pointed to as cache.
|
|
||||||
You will have to make sure it's reserved and of the correct size.
|
|
||||||
This allows you to put the memory on the heap, or perform special tricks like
|
|
||||||
deallocating it without having to umount your filesystem and open files.
|
|
||||||
On systems with malloc, this is the recommended setting.
|
|
||||||
|
|
||||||
If you use the efs wrapper object, please look at the \code{efs\_init} documentation
|
|
||||||
on how to pass the ioman pointer.
|
|
||||||
|
|
||||||
\subsection{Pre-allocation}
|
|
||||||
Our VFAT module supports the concept of pre-allocation. When writing files, for
|
|
||||||
example log files, it is usually done with tiny bits a time. That is not the
|
|
||||||
most efficient way, but it is usually the only solution that works on embedded
|
|
||||||
systems. Every time you cross a cluster boundary with your write, the library
|
|
||||||
has to search a new cluster (reading the FAT), allocate it (write to the FAT).
|
|
||||||
|
|
||||||
Clearly, this is a waste. The solution we came up with was preallocating. This means
|
|
||||||
that when you write to a file, and fwrite sees that it needs to allocate more clusters,
|
|
||||||
it will allocate too many of them. Since this is done in one operation, it requires
|
|
||||||
usually only one read and one write to the FAT. This can save up to 50\% disc I/O
|
|
||||||
in some applications.
|
|
||||||
|
|
||||||
The drawback is that the allocation happens in larger chunks, if you do this with
|
|
||||||
many files, you might end up with larger than normal amounts of slackspace.
|
|
||||||
|
|
||||||
We have also implemented this feature for directories. This is very useful if you
|
|
||||||
have to create a lot of small files, since the directories grow by larger portions
|
|
||||||
then.
|
|
||||||
|
|
||||||
\subsubsection*{CLUSTER\_PREALLOC\_FILE}
|
|
||||||
This number determines the default value of extra clusters that will be allocated
|
|
||||||
with every sizeincrease. For example, if fwrite calculates that it needs 7 clusters,
|
|
||||||
and \code{CLUSTER\_PREALLOC\_FILE} is 30 then efsl will allocate 37 clusters.
|
|
||||||
This means (assuming every write needs 7 clusters) that the next 4 writes won't
|
|
||||||
require any write operation to the FAT (and due to the cluster cache the FAT will probably have to be read only once).
|
|
||||||
|
|
||||||
The value you put here will be the default value, it can be changed per file
|
|
||||||
object. (not yet implemented).
|
|
||||||
|
|
||||||
\subsubsection*{CLUSTER\_PREALLOC\_DIRECTORY}
|
|
||||||
The same explanation as above counts, only this value is used for directories.
|
|
||||||
Generally you should not put this above 10 (unless your speed tests prove otherwise
|
|
||||||
off course).
|
|
||||||
|
|
||||||
\subsection{Endianness}
|
|
||||||
The Microsoft FAT filesystem was originally created to be run on Intel compatible hardware.
|
|
||||||
Therefore the Microsoft programmers decided to record all data on the disc in little endian
|
|
||||||
format. Our library supports running on big endian devices. Here you can select whether your
|
|
||||||
target CPU is little or big endian.
|
|
||||||
|
|
||||||
Running on big endian will cause some performance lose because (rather simple) calculations have
|
|
||||||
to be made to all numbers that have to interpreted by the library. This does not apply to
|
|
||||||
data within the files off course.
|
|
||||||
|
|
||||||
If the flag \code{\#LITTLE\_ENDIAN} is set, efsl will assume that your hardware is little endian.
|
|
||||||
If you have a big endian system, you should comment this out. The function \code{fs\_checkEndian}
|
|
||||||
will tell you if you have selected the right endianness, this is a check you might want to use.
|
|
||||||
|
|
||||||
\subsection{Date and time}
|
|
||||||
This flag determines if you want to have date and time support. With date and time support we
|
|
||||||
mean that when you create or update a file the directory entry will receive the correct date and
|
|
||||||
time stamp.
|
|
||||||
|
|
||||||
Please refer to section \ref{dateandtime} to learn more about how this works.
|
|
||||||
|
|
||||||
If you disable date and time support by commenting the \code{\#DATE\_TIME\_SUPPORT} then
|
|
||||||
all dates and times that need to be created or updated will be set to zero, which in FAT land corresponds to the first of January of the year 1970.
|
|
||||||
|
|
||||||
\subsection{Errors}
|
|
||||||
When the library encounters an error, there be an error cascade moving from the error-causing object
|
|
||||||
to the topmost object where the request started. Seen from userland this gives you extremely little
|
|
||||||
information, usually nothing more than fail or success.
|
|
||||||
|
|
||||||
Every object in the library has an optional error field, that contains a unique number that
|
|
||||||
corresponds to a specific error. If you examine every error field you can see exactly where the
|
|
||||||
error was started and what the effect was on the higher level objects.
|
|
||||||
|
|
||||||
In a more practical sense you can display an error number or explanation to your users, giving
|
|
||||||
yourself or them a better chance to correct or avoid the problem.
|
|
||||||
Please see the section on error on what every value means.
|
|
||||||
|
|
||||||
\subsection{Debug}
|
|
||||||
This will turn debug support on or off. When enable (and your platform has a means of output that
|
|
||||||
is supported by EFSL) it you will see messages you have created yourself, or that are printed by the
|
|
||||||
library. By default the library is very silent, only very critical errors might get printed out.
|
|
||||||
|
|
||||||
This option is depreciated and is left in for backward compatibility.
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
\label{dateandtime}
|
|
||||||
The EFSL library supports setting and updating all date and time fields
|
|
||||||
supported by the filesystem. In order to do this the library must
|
|
||||||
know the current time and date at all times. Since it has to run everywhere,
|
|
||||||
there is no standard mechanism to get the date/time, and some systems do
|
|
||||||
not have a clock.
|
|
||||||
|
|
||||||
With default configuration there is no date or time support, you have to
|
|
||||||
turn it on manually in the configuration file \filename{config.h}.
|
|
||||||
You will have to uncomment the field named \code{\#define DATE\_TIME\_SUPPORT},
|
|
||||||
in order to activate date/time support.
|
|
||||||
|
|
||||||
Furthermore you will have to provide the library with date and time information.
|
|
||||||
A set of defines was used for this, when date/time support is not enabled,
|
|
||||||
the defines automatically return \code{0x0000} for all time and date fields,
|
|
||||||
so there is no performance suffer when you do not need date/time support.
|
|
||||||
If you do need it you will have to provide 6 functions to the library
|
|
||||||
that will tell it the time. Since these functions may get called often,
|
|
||||||
it is highly recommended that you cache the time result somewhere so
|
|
||||||
you can serve the library directly from ram. If you do not do this and
|
|
||||||
your RTC request take a lot of time, you may suffer large losses in read
|
|
||||||
or write operations depending on your hardware.
|
|
||||||
|
|
||||||
The six functions are:
|
|
||||||
\begin{itemize}
|
|
||||||
\item\code{euint16 efsl\_getYear(void)}
|
|
||||||
\item\code{euint8 efsl\_getMonth(void)}
|
|
||||||
\item\code{euint8 efsl\_getDay(void)}
|
|
||||||
\item\code{euint8 efsl\_getHour(void)}
|
|
||||||
\item\code{euint8 efsl\_getMinute(void)}
|
|
||||||
\item\code{euint8 efsl\_getSecond(void)}
|
|
||||||
\end{itemize}
|
|
||||||
Internally the library will recalculate these numbers to match the
|
|
||||||
filesystem that is currently in use.
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
Since debugging on every device is completely different, a DBG macro is
|
|
||||||
implemented. On Linux for example, this macro will print the string given
|
|
||||||
to the screen (using printf). On AVR, it will send debug strings through the
|
|
||||||
UART. For compatibility with other devices, it is necessary that you always use
|
|
||||||
the DBG-macro instead of a device-specific debugging commands.\newline
|
|
||||||
\newline
|
|
||||||
Because AVR-GCC puts strings in sram memory by default, every string should be
|
|
||||||
surrounded by the TXT-macro. On AVR, this macro will put the string in program
|
|
||||||
memory (flash), on any other device, this macro will be ignored.\newline
|
|
||||||
\newline
|
|
||||||
Example of a debug string:\\
|
|
||||||
\code{DBG((TXT("This is test nr \%d of \%d.$\backslash$n"),id,total));}
|
|
||||||
|
|
||||||
\subsubsection{Debugging on Linux}
|
|
||||||
On linux, debugging strings are sent to stdout using printf.\newline
|
|
||||||
\newline
|
|
||||||
To enable debugging, set DEBUG in \filename{config.h}.
|
|
||||||
\subsubsection{Debugging on AVR}
|
|
||||||
On AVR, debugging strings are sent through the UART and can be read using
|
|
||||||
a terminal like minicom (linux) or hyperterminal (windows). Standard, the
|
|
||||||
first UART is used, but this can be changed in \filename{debug.c} to the
|
|
||||||
second UART.\newline
|
|
||||||
\newline
|
|
||||||
To enable debugging:
|
|
||||||
\begin{itemize}
|
|
||||||
\item{Set DEBUG in \filename{config.h}}
|
|
||||||
\item{Set CLK to the clock speed of your AVR in \filename{config.h}}
|
|
||||||
\item{Set BAUDRATE to the baudrate you want in \filename{config.h}}
|
|
||||||
\item{Initialize debugging in your program by calling \code{debug\_init()}}
|
|
||||||
\end{itemize}
|
|
||||||
Remark: when you use the serial port in your main program, make sure you
|
|
||||||
use a different UART than the one efsl is using when sending debug string.
|
|
||||||
\subsubsection{Debugging on DSP}
|
|
||||||
On DSP, debugging strings are sent to Code Composer using the printf function.
|
|
||||||
\newline\newline
|
|
||||||
To enable debugging, set DEBUG in \filename{config.h}.\newline
|
|
||||||
\newline
|
|
||||||
Remark: this will only work when using a DSK-kit.
|
|
||||||
@@ -1,166 +0,0 @@
|
|||||||
\label{hwdriver}
|
|
||||||
This section will describe step by step how to write an hardware endpoint.
|
|
||||||
You will be required to write your own endpoint in case non of the existing endpoints
|
|
||||||
matches your hardware.
|
|
||||||
|
|
||||||
First let's have a look at how EFSL is structured internally.\\\\
|
|
||||||
\includegraphics[scale=0.4]{schematics/objectmodel.eps}\\
|
|
||||||
|
|
||||||
As you can see we have created a linear object model that is quite simple.
|
|
||||||
The file en filesystem object deal with handling the filesystem specific stuff.
|
|
||||||
Below that we find the Partition object that is responsible for translating partition
|
|
||||||
relative addressing into disc-based LBA addressing.
|
|
||||||
|
|
||||||
The Disc object hold the partition table, and has a direct link to a cache manager, IOMan.
|
|
||||||
In IOMan, all requests for disc sectors come together. IOMan will perform checks to see
|
|
||||||
if sectors have to be read from disc (or from memory), or written back to disc.
|
|
||||||
In the latter case (reading or writing to disc), a request is made to the hardware layer.
|
|
||||||
|
|
||||||
The hardware interface has 3 responsibilities :
|
|
||||||
\begin{itemize}
|
|
||||||
\item Initialize the hardware
|
|
||||||
\item Read sectors from disc
|
|
||||||
\item Write sectors to disc
|
|
||||||
\end{itemize}
|
|
||||||
|
|
||||||
All requests are \textsl{sector}based, a sector is a 512 byte piece from the disc, that is aligned to
|
|
||||||
a 512 byte boundary.\\\\
|
|
||||||
\includegraphics[scale=0.4]{schematics/sector.eps}
|
|
||||||
|
|
||||||
In this example we will create a new endpoint that will add support for data over pigeon carrier
|
|
||||||
for the EFSL. Initializing the hardware will require feeding the pigeon and telling it where the
|
|
||||||
data is. Reading/Writing will entail giving the bird the sector and letting it fly.
|
|
||||||
|
|
||||||
Perform the following steps:
|
|
||||||
\begin{enumerate}
|
|
||||||
|
|
||||||
\item Choose a name for your endpoint\\
|
|
||||||
You will need this name to create the required defines in the source code.
|
|
||||||
For our example I've chosen the name \code{PIGEON\_CARRIER}.
|
|
||||||
For consistency the final name is then \code{HW\_ENDPOINT\_PIGEON\_CARRIER}.
|
|
||||||
|
|
||||||
\item Verify the sizes of integers\\
|
|
||||||
Open \filename{inc/types.h} and create a new entry for pigeon carriers. Perhaps
|
|
||||||
one of the existing sets is identical to yours and you can copy-paste it.
|
|
||||||
|
|
||||||
\item Add your endpoint to \filename{interface.h}\\
|
|
||||||
Locate the file \filename{interface.h} located in the directory \filename{inc/}
|
|
||||||
Add a pigeon entry (located above the \code{\#else ... NO INTERFACE DEFINED})
|
|
||||||
\begin{lstlisting}
|
|
||||||
#if defined(HW_ENDPOINT_0)
|
|
||||||
#include "interfaces/0.h"
|
|
||||||
#elif defined(HW_ENDPOINT_1)
|
|
||||||
#include "interfaces/1.h"
|
|
||||||
#elif defined(HW_ENDPOINT_PIGEON_CARRIER)
|
|
||||||
#include "interfaces/pigeon.h"
|
|
||||||
#else
|
|
||||||
#error "NO INTERFACE DEFINED - see interface.h"
|
|
||||||
#endif
|
|
||||||
\end{lstlisting}
|
|
||||||
|
|
||||||
\item Select your endpoint in \filename{conf/config.h}
|
|
||||||
|
|
||||||
\item Create your sourcefiles\\
|
|
||||||
Create a header file in \filename{inc/} and a sourcefile in \filename {src/interfaces}.
|
|
||||||
In this example I'm using \filename{pigeon.h} and \filename{pigeon.c}.
|
|
||||||
|
|
||||||
\item Add your object file to the Makefile
|
|
||||||
Take the Makefile that works best on your platform (they should all work with
|
|
||||||
GNU/Make), or create a new one, using the existing one's as a template.
|
|
||||||
Make sure to include your new pigeon object to the library.
|
|
||||||
If you have an 'ar' like utility you can create a static library, else you may
|
|
||||||
have to create a new project containing all required source files.
|
|
||||||
|
|
||||||
\end{enumerate}
|
|
||||||
|
|
||||||
The basic framework is now complete, now all that's left to do is to write the code
|
|
||||||
that will perform the actual flying work.
|
|
||||||
|
|
||||||
\subsubsection{hwInterface}
|
|
||||||
This structure represents the underlying hardware. There are some field that are required
|
|
||||||
to be present (because EFSL uses them), but you may put in as much or a little as
|
|
||||||
your driver requires to access the hardware.
|
|
||||||
|
|
||||||
As always in embedded design it is recommended to keep this structure as small
|
|
||||||
as possible.
|
|
||||||
|
|
||||||
Example:
|
|
||||||
\begin{lstlisting}
|
|
||||||
struct hwInterface{
|
|
||||||
/* Field created for THIS hardware */
|
|
||||||
Pigeon pigeon;
|
|
||||||
|
|
||||||
/* Obligatory fields */
|
|
||||||
euint32 sectorCount;
|
|
||||||
};
|
|
||||||
typedef struct hwInterface hwInterface;
|
|
||||||
\end{lstlisting}
|
|
||||||
|
|
||||||
\subsubsection{if\_initInterface}
|
|
||||||
This function will be called one time, when the hardware object is initialized
|
|
||||||
by \code{efs\_init()}. This code should bring the hardware in a ready to use
|
|
||||||
state.
|
|
||||||
|
|
||||||
The function's prototype is\\
|
|
||||||
\code{esint16 if\_initInterface(hwInterface *hw, euint8* opts);}
|
|
||||||
|
|
||||||
Optionally but recommended you should fill in the hw->sectorCount field with the number
|
|
||||||
of sectors. This field is used to validate sectorrequests.
|
|
||||||
|
|
||||||
An example of a initInterface function :
|
|
||||||
\begin{lstlisting}
|
|
||||||
esint16 if_initInterface(hwInterface *hw, euint8* opts)
|
|
||||||
{
|
|
||||||
/* Parse options */
|
|
||||||
parse_options(opts); /* Your application may not need options */
|
|
||||||
|
|
||||||
/* Check hardware state */
|
|
||||||
if(!alive(hw->pigeon)){
|
|
||||||
//printf("Pigeon died! :-(\n");
|
|
||||||
return(DEAD_PIGEON); /* #define DEAD_PIGEON -1 */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Initialize hardware */
|
|
||||||
feed(hw->pigeon);
|
|
||||||
pet (hw->pigeon);
|
|
||||||
|
|
||||||
/* Get sectors count */
|
|
||||||
hw->numSectors = ask_pigeon_num_sectors(hw->pigeon);
|
|
||||||
|
|
||||||
return(0);
|
|
||||||
}
|
|
||||||
\end{lstlisting}
|
|
||||||
|
|
||||||
\subsubsection{if\_readBuf}
|
|
||||||
This function is responsible to read a sector from the disc and store it in a user supplied buffer. You will receive the hardware object, an address and a pointer to memory for storing
|
|
||||||
the buffer.
|
|
||||||
|
|
||||||
Please be very careful to respect the boundaries of the buffers, since it will usually be IOMan
|
|
||||||
calling this function, and if you have a buffer overflow you might corrupt the cache of the
|
|
||||||
the next buffer, which in turn may produce extremely rare and impossible to retrace behavior.
|
|
||||||
|
|
||||||
The function prototype is:\\
|
|
||||||
\code{esint16 if\_readBuf(hwInterface *hw,euint32 address, euint8* buf);}
|
|
||||||
|
|
||||||
The address is an LBA address, relative to the beginning of the disc. Should you be
|
|
||||||
accessing an old hard disc, or a device which uses some other form of addressing you will have to
|
|
||||||
recalculate the address to your own addressing scheme. Please note that there is no support
|
|
||||||
for sectors that are not 512 bytes large.
|
|
||||||
|
|
||||||
\begin{lstlisting}
|
|
||||||
esint8 if_readBuf(hwInterface* hw,euint32 address,euint8* buf)
|
|
||||||
{
|
|
||||||
Message new_message;
|
|
||||||
|
|
||||||
new_message.address = address;
|
|
||||||
new_message.command = READ;
|
|
||||||
|
|
||||||
pigeon_send(hw->pigeon,new_message); /* Launches the pigeon */
|
|
||||||
while(!pigeon_returned(hw->pigeon)); /* Wait until the bird is back */
|
|
||||||
memcpy(new_message.data,buf,512); /* Copy buffer */
|
|
||||||
return(0);
|
|
||||||
}
|
|
||||||
\end{lstlisting}
|
|
||||||
|
|
||||||
\subsubsection{if\_writeBuf}
|
|
||||||
The function \code{if\_writeBuf} works exactly the same as it's reading variant.
|
|
||||||
@@ -1,45 +0,0 @@
|
|||||||
\subsubsection*{Purpose}
|
|
||||||
Initializes the hardware and the software layer.
|
|
||||||
\subsubsection*{Prototype}
|
|
||||||
\code{esint8 efs\_init(EmbeddedFileSystem *efs, eint8* opts);}
|
|
||||||
\subsubsection*{Arguments}
|
|
||||||
Objects passed to \code{efs\_init}:
|
|
||||||
\begin{itemize}
|
|
||||||
\item{\code{efs}: empty EmbeddedFileSystem object}
|
|
||||||
\item
|
|
||||||
{
|
|
||||||
\code{opts}: character string containing options, depending on what
|
|
||||||
interface you are using:
|
|
||||||
\begin{itemize}
|
|
||||||
\item{Linux: opts points to the path to the device}
|
|
||||||
\item{AVR: opts points to the card enable pin (TODO)}
|
|
||||||
\item{DSP: opts points to the card enable memory address (TODO)}
|
|
||||||
\end{itemize}
|
|
||||||
}
|
|
||||||
\end{itemize}
|
|
||||||
\subsubsection*{Return value}
|
|
||||||
Returns 0 if no errors are detected.\\
|
|
||||||
\newline
|
|
||||||
Returns non-zero if a low-level error is detected:
|
|
||||||
\begin{itemize}
|
|
||||||
\item{Returns -1 if the interface could not be initialized.}
|
|
||||||
\item{Returns -2 if the filesystem could not be initialized.}
|
|
||||||
\end{itemize}
|
|
||||||
\subsubsection*{Example}
|
|
||||||
\lstset{numbers=left, stepnumber=1, numberstyle=\small, numbersep=5pt, tabsize=4}
|
|
||||||
\begin{lstlisting}
|
|
||||||
#include "efs.h"
|
|
||||||
|
|
||||||
void main(void)
|
|
||||||
{
|
|
||||||
EmbeddedFileSystem efsl;
|
|
||||||
esint8 ret;
|
|
||||||
|
|
||||||
DBG((TXT("Will init efsl now.\n")));
|
|
||||||
ret=efs_init(&efsl,"/dev/sda");
|
|
||||||
if(ret==0)
|
|
||||||
DBG((TXT("Filesystem correctly initialized.\n")));
|
|
||||||
else
|
|
||||||
DBG((TXT("Could not initialize filesystem (err \%d).\n"),ret));
|
|
||||||
}
|
|
||||||
\end{lstlisting}
|
|
||||||
@@ -1,43 +0,0 @@
|
|||||||
\subsubsection*{Purpose}
|
|
||||||
Updates file records and closes file object.
|
|
||||||
\subsubsection*{Prototype}
|
|
||||||
\code{esint8 file\_fclose(File *file);}
|
|
||||||
\subsubsection*{Arguments}
|
|
||||||
Objects passed to \code{file\_fopen}:
|
|
||||||
\begin{itemize}
|
|
||||||
\item{\code{file}: pointer to a File object}
|
|
||||||
\end{itemize}
|
|
||||||
\subsubsection*{Return value}
|
|
||||||
Returns 0 if no errors are detected.\\
|
|
||||||
\newline
|
|
||||||
Returns non-zero if an error is detected.
|
|
||||||
\subsubsection*{Example}
|
|
||||||
\lstset{numbers=left, stepnumber=1, numberstyle=\small, numbersep=5pt, tabsize=4}
|
|
||||||
\begin{lstlisting}
|
|
||||||
#include "efs.h"
|
|
||||||
|
|
||||||
void main(void)
|
|
||||||
{
|
|
||||||
EmbeddedFileSystem efsl;
|
|
||||||
File file;
|
|
||||||
|
|
||||||
/* Initialize efsl */
|
|
||||||
DBG((TXT("Will init efsl now.\n")));
|
|
||||||
if(efs_init(&efsl,"/dev/sda")!=0){
|
|
||||||
DBG((TXT("Could not initialize filesystem (err \%d).\n"),ret));
|
|
||||||
exit(-1);
|
|
||||||
}
|
|
||||||
DBG((TXT("Filesystem correctly initialized.\n")));
|
|
||||||
|
|
||||||
/* Open file for reading */
|
|
||||||
if(file_fopen(&file, &efsl.myFs, "read.txt", 'r')!=0){
|
|
||||||
DBG((TXT("Could not open file for reading.\n")));
|
|
||||||
exit(-1);
|
|
||||||
}
|
|
||||||
DBG((TXT("File opened for reading.\n")));
|
|
||||||
|
|
||||||
/* Close file & filesystem */
|
|
||||||
fclose(&file);
|
|
||||||
fs_umount(&efs.myFs);
|
|
||||||
}
|
|
||||||
\end{lstlisting}
|
|
||||||
@@ -1,70 +0,0 @@
|
|||||||
\subsubsection*{Purpose}
|
|
||||||
Searches for file and initializes the file object.
|
|
||||||
\subsubsection*{Prototype}
|
|
||||||
\code{esint8 file\_fopen(File *file, FileSystem *fs, eint8 *filename, eint8 mode);}
|
|
||||||
\subsubsection*{Arguments}
|
|
||||||
Objects passed to \code{file\_fopen}:
|
|
||||||
\begin{itemize}
|
|
||||||
\item{\code{file}: pointer to a File object}
|
|
||||||
\item{\code{fs}: pointer to the FileSystem object}
|
|
||||||
\item{\code{filename}: pointer to the path + filename}
|
|
||||||
\item
|
|
||||||
{
|
|
||||||
\code{mode}: mode of opening, this can be:
|
|
||||||
\begin{itemize}
|
|
||||||
\item{'r': open file for reading}
|
|
||||||
\item{'w': open file for writing}
|
|
||||||
\item{'a': open file for appending}
|
|
||||||
\end{itemize}
|
|
||||||
}
|
|
||||||
\end{itemize}
|
|
||||||
\subsubsection*{Return value}
|
|
||||||
Returns 0 if no errors are detected.\\
|
|
||||||
\newline
|
|
||||||
Returns non-zero if an error is detected:
|
|
||||||
\begin{itemize}
|
|
||||||
\item{Returns -1 if the file you are trying to open for reading could not
|
|
||||||
be found.}
|
|
||||||
\item{Returns -2 if the file you are trying to open for writing already
|
|
||||||
exists.}
|
|
||||||
\item{Returns -3 if no free spot could be found for writing or appending.}
|
|
||||||
\item{Returns -4 if mode is not correct (if it is not 'r', 'w' or 'a').}
|
|
||||||
\end{itemize}
|
|
||||||
\subsubsection*{Example}
|
|
||||||
\lstset{numbers=left, stepnumber=1, numberstyle=\small, numbersep=5pt, tabsize=4}
|
|
||||||
\begin{lstlisting}
|
|
||||||
#include "efs.h"
|
|
||||||
|
|
||||||
void main(void)
|
|
||||||
{
|
|
||||||
EmbeddedFileSystem efsl;
|
|
||||||
File file_read, file_write;
|
|
||||||
|
|
||||||
/* Initialize efsl */
|
|
||||||
DBG((TXT("Will init efsl now.\n")));
|
|
||||||
if(efs_init(&efsl,"/dev/sda")!=0){
|
|
||||||
DBG((TXT("Could not initialize filesystem (err \%d).\n"),ret));
|
|
||||||
exit(-1);
|
|
||||||
}
|
|
||||||
DBG((TXT("Filesystem correctly initialized.\n")));
|
|
||||||
|
|
||||||
/* Open file for reading */
|
|
||||||
if(file_fopen(&file_read, &efsl.myFs, "read.txt", 'r')!=0){
|
|
||||||
DBG((TXT("Could not open file for reading.\n")));
|
|
||||||
exit(-1);
|
|
||||||
}
|
|
||||||
DBG((TXT("File opened for reading.\n")));
|
|
||||||
|
|
||||||
/* Open file for writing */
|
|
||||||
if(file_fopen(&file_write, &efsl.myFs, "write.txt", 'w')!=0){
|
|
||||||
DBG((TXT("Could not open file for writing.\n")));
|
|
||||||
exit(-2);
|
|
||||||
}
|
|
||||||
DBG((TXT("File opened for writing.\n")));
|
|
||||||
|
|
||||||
/* Close files & filesystem */
|
|
||||||
fclose(&file_read);
|
|
||||||
fclose(&file_write);
|
|
||||||
fs_umount(&efs.myFs);
|
|
||||||
}
|
|
||||||
\end{lstlisting}
|
|
||||||
@@ -1,51 +0,0 @@
|
|||||||
\subsubsection*{Purpose}
|
|
||||||
Reads a file and puts it's content in a buffer.
|
|
||||||
\subsubsection*{Prototype}
|
|
||||||
\code{euint32 file\_read (File *file, euint32 size, euint8 *buf);}
|
|
||||||
\subsubsection*{Arguments}
|
|
||||||
Objects passed to \code{file\_read}:
|
|
||||||
\begin{itemize}
|
|
||||||
\item{\code{file}: pointer to a File object}
|
|
||||||
\item{\code{size}: amount of bytes you want to read / put in buf}
|
|
||||||
\item{\code{buf}: pointer to the buffer you want to store the data}
|
|
||||||
\end{itemize}
|
|
||||||
\subsubsection*{Return value}
|
|
||||||
Returns the amount of bytes read.
|
|
||||||
\subsubsection*{Example}
|
|
||||||
\lstset{numbers=left, stepnumber=1, numberstyle=\small, numbersep=5pt, tabsize=4}
|
|
||||||
\begin{lstlisting}
|
|
||||||
#include "efs.h"
|
|
||||||
|
|
||||||
void main(void)
|
|
||||||
{
|
|
||||||
EmbeddedFileSystem efsl;
|
|
||||||
euint8 buffer[512];
|
|
||||||
euint16 e, f;
|
|
||||||
File file;
|
|
||||||
|
|
||||||
/* Initialize efsl */
|
|
||||||
DBG((TXT("Will init efsl now.\n")));
|
|
||||||
if(efs_init(&efsl,"/dev/sda")!=0){
|
|
||||||
DBG((TXT("Could not initialize filesystem (err \%d).\n"),ret));
|
|
||||||
exit(-1);
|
|
||||||
}
|
|
||||||
DBG((TXT("Filesystem correctly initialized.\n")));
|
|
||||||
|
|
||||||
/* Open file for reading */
|
|
||||||
if(file_fopen(&file, &efsl.myFs, "read.txt", 'r')!=0){
|
|
||||||
DBG((TXT("Could not open file for reading.\n")));
|
|
||||||
exit(-1);
|
|
||||||
}
|
|
||||||
DBG((TXT("File opened for reading.\n")));
|
|
||||||
|
|
||||||
/* Read file and print content */
|
|
||||||
while((e=file_read(&file,512,buffer))){
|
|
||||||
for(f=0;f<e;f++)
|
|
||||||
DBG((TXT("\%c"),buffer[f]));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Close file & filesystem */
|
|
||||||
fclose(&file);
|
|
||||||
fs_umount(&efs.myFs);
|
|
||||||
}
|
|
||||||
\end{lstlisting}
|
|
||||||
@@ -1,52 +0,0 @@
|
|||||||
\subsubsection*{Purpose}
|
|
||||||
Reads a file and puts it's content in a buffer.
|
|
||||||
\subsubsection*{Prototype}
|
|
||||||
\code{euint32 file\_write(File *file, euint32 size, euint8 *buf)}
|
|
||||||
\subsubsection*{Arguments}
|
|
||||||
Objects passed to \code{file\_read}:
|
|
||||||
\begin{itemize}
|
|
||||||
\item{\code{file}: pointer to a File object}
|
|
||||||
\item{\code{size}: amount of bytes you want to write}
|
|
||||||
\item{\code{buf}: pointer to the buffer you want to write the data from}
|
|
||||||
\end{itemize}
|
|
||||||
\subsubsection*{Return value}
|
|
||||||
Returns the amount of bytes written.
|
|
||||||
\subsubsection*{Example}
|
|
||||||
\lstset{numbers=left, stepnumber=1, numberstyle=\small, numbersep=5pt, tabsize=4}
|
|
||||||
\begin{lstlisting}
|
|
||||||
#include <string.h>
|
|
||||||
#include "efs.h"
|
|
||||||
|
|
||||||
void main(void)
|
|
||||||
{
|
|
||||||
EmbeddedFileSystem efsl;
|
|
||||||
euint8 *buffer = "This is a test.\n";
|
|
||||||
euint16 e=0;
|
|
||||||
File file;
|
|
||||||
|
|
||||||
/* Initialize efsl */
|
|
||||||
DBG((TXT("Will init efsl now.\n")));
|
|
||||||
if(efs_init(&efsl,"/dev/sda")!=0){
|
|
||||||
DBG((TXT("Could not initialize filesystem (err \%d).\n"),ret));
|
|
||||||
exit(-1);
|
|
||||||
}
|
|
||||||
DBG((TXT("Filesystem correctly initialized.\n")));
|
|
||||||
|
|
||||||
/* Open file for writing */
|
|
||||||
if(file_fopen(&file, &efsl.myFs, "write.txt", 'w')!=0){
|
|
||||||
DBG((TXT("Could not open file for writing.\n")));
|
|
||||||
exit(-1);
|
|
||||||
}
|
|
||||||
DBG((TXT("File opened for reading.\n")));
|
|
||||||
|
|
||||||
/* Write buffer to file */
|
|
||||||
if( file_write(&file,strlen(buffer),buffer) == strlen(buffer) )
|
|
||||||
DBG((TXT("File written.\n")));
|
|
||||||
else
|
|
||||||
DBG((TXT("Could not write file.\n")));
|
|
||||||
|
|
||||||
/* Close file & filesystem */
|
|
||||||
fclose(&file);
|
|
||||||
fs_umount(&efs.myFs);
|
|
||||||
}
|
|
||||||
\end{lstlisting}
|
|
||||||
@@ -1,236 +0,0 @@
|
|||||||
\label{ioman}
|
|
||||||
The IOManager that is the second lowest layer of the embedded filesystems library is
|
|
||||||
responsible for coordinating disk input and output, as well as managing a caching
|
|
||||||
system. This documentation describes the second implementation of IOMan, which includes
|
|
||||||
features such as :
|
|
||||||
\begin{itemize}
|
|
||||||
\item Delayed write
|
|
||||||
\item Buffer reference statistics
|
|
||||||
\item Buffer exportable to users
|
|
||||||
\item Support for cached direct I/O as well as indirect I/O
|
|
||||||
\item Can allocate memory itself (on the stack), or you can do it yourself (heap)
|
|
||||||
\end{itemize}
|
|
||||||
|
|
||||||
\subsubsection{General operation}
|
|
||||||
Because of the limited memory nature of most embedded devices for which this library is
|
|
||||||
intended several design decisions were made to minimize memory usage. Some of these required
|
|
||||||
that some concessions be made. One of them is that there is no memory protection, since
|
|
||||||
most devices don't have the memory to support this, or lack the ability to protect memory.
|
|
||||||
|
|
||||||
When IOMan receives a request for a sector, it will make sure it has the sector in it's
|
|
||||||
own memory cache and then give the caller a \code{euint8*} pointer to that cache. The
|
|
||||||
user is then free to do operations on that memory, and when it is done it should tell
|
|
||||||
IOMan so. Several things can go wrong with this: you can request a sector for reading,
|
|
||||||
and then write in the cache, thereby corrupting it. Or you can request a sector, but never
|
|
||||||
release it (sort of a memory leak), which may result in very bad performance, and a deadlocked
|
|
||||||
I/O manager.
|
|
||||||
|
|
||||||
But, taking into account that very little memory is required for operation, if you follow the I/O man rules, you will get a pretty clever caching object that will make writing new filesystems
|
|
||||||
a simple job.
|
|
||||||
|
|
||||||
\subsubsection{Cache decisions}
|
|
||||||
Whenever ioman receives a request to fetch a sector, be it read or write, it will have to make sure
|
|
||||||
it has, or can get the sector you want. It follows a certain path to do this.\label{cachemethod}
|
|
||||||
\begin{enumerate}
|
|
||||||
\item First of all it will scan it's cache range to see if it already has the sector.
|
|
||||||
If it is found, and it was a write request, the cache is marked writable. Usage and
|
|
||||||
reference get incremented and a pointer is then returned to the requester. If the
|
|
||||||
buffer cannot be found, ioman proceeds to step 2.
|
|
||||||
\item When an item is not in cache, it has to be fetched from the disc, the best place to
|
|
||||||
store it is in memory that does not contain anything useful yet. Ioman will search for
|
|
||||||
a place that is currently not occupied by anything. If it is found, the sector will be
|
|
||||||
placed on that spot and a pointer returned. Else, ioman proceeds to step 3.
|
|
||||||
\item Since there is no other choice than to overwrite an already existing cache, ioman will
|
|
||||||
try to find one that is the least interesting. First it will search for caches that
|
|
||||||
are marked not writable, and have no users. Ioman will then select the one that has the
|
|
||||||
least references. If there are none, it will search for caches that don't have users and
|
|
||||||
are writable. Once again the one with the least references is returned. Since it is
|
|
||||||
writable ioman will flush it to disc first. After that the requested sector is put there
|
|
||||||
and a pointer returned. If it cannot find any caches that have no users it will go to
|
|
||||||
step 4.
|
|
||||||
\item Since every cache spot is in use ioman will have to select one for overallocation.
|
|
||||||
Since this selection depends on many factors and is rather complex, a points
|
|
||||||
system is used. The algorithm considers every cache place and allocated a certain number
|
|
||||||
of points to it, lower means that it is a better candidate for overallocation. Fifty
|
|
||||||
percent of the points goes to the cache being marked writable, since having to write
|
|
||||||
a sector is expensive. Another 35 percent goes to how many overallocations have
|
|
||||||
already been done on that spot. It doesn't make sense to always overalloc the same buffer,
|
|
||||||
it is better to spread this. The remaining 15 percent is determined by the number of
|
|
||||||
references to the sector.
|
|
||||||
|
|
||||||
After a function has selected the best candidate, ioman will overwrite that spot with
|
|
||||||
the new sector. It will also push the status and sectornumber onto that cache's
|
|
||||||
retrieval stack, so that when the sector is released, the older sector can be retrieved.
|
|
||||||
If this fails go to step 5.
|
|
||||||
\item When ioman gets here it will return a (nil) pointer and flag an error.
|
|
||||||
\end{enumerate}
|
|
||||||
|
|
||||||
\subsubsection{Functions}
|
|
||||||
|
|
||||||
\begin{longtable}{|p{0.35\textwidth}|p{0.65\textwidth}|}
|
|
||||||
|
|
||||||
\hline
|
|
||||||
\multicolumn{2}{|c|}{
|
|
||||||
\textbf{I/O Manager Functions}
|
|
||||||
} \\
|
|
||||||
\multicolumn{2}{|c|}{} \\
|
|
||||||
\hline
|
|
||||||
\hline
|
|
||||||
\endfirsthead
|
|
||||||
|
|
||||||
\hline
|
|
||||||
\multicolumn{2}{|c|}{\textbf{I/O Manager Functions (continued)}} \\
|
|
||||||
\hline
|
|
||||||
\endhead
|
|
||||||
|
|
||||||
\hline
|
|
||||||
\endfoot
|
|
||||||
|
|
||||||
\hline
|
|
||||||
\endlastfoot
|
|
||||||
|
|
||||||
\code{ioman\_init} & \code{esint8 (IOManager *ioman, hwInterface *iface, euint8* bufferarea)} \\
|
|
||||||
\hline
|
|
||||||
\multicolumn{2}{|p{\textwidth}|}{
|
|
||||||
This function is called to initialize the internal state of the I/O manager. It should be the
|
|
||||||
first function you call on an ioman object. Failure to do so will result in undefined behavior.
|
|
||||||
The function clears all internal variables to a default safe state, and sets up it's memory region.
|
|
||||||
|
|
||||||
There are two possibilities, if you supply a 0 pointer then a function will be called that contains
|
|
||||||
a static variable with a size of 512 * \code{IOMAN\_NUMBUFFERS}, else, it will be assumed that
|
|
||||||
you allocated that memory yourself and the pointer you provided will be used.
|
|
||||||
}\\
|
|
||||||
\hline
|
|
||||||
|
|
||||||
\code{\external{ioman\_reset}} & \code{void (IOManager *ioman)} \\
|
|
||||||
\hline
|
|
||||||
\multicolumn{2}{|p{\textwidth}|}{
|
|
||||||
This function is called from the initialization function, it does the actual reset of all variables.
|
|
||||||
}\\
|
|
||||||
\hline
|
|
||||||
|
|
||||||
\code{ioman\_pop} & \code{esint8 (IOManager *ioman,euint16 bufplace)} \\
|
|
||||||
\hline
|
|
||||||
\multicolumn{2}{|p{\textwidth}|}{
|
|
||||||
This function fetches settings (sector number, usage and status register) from stack \code{bufplace}
|
|
||||||
and puts it back on the main registers. It will return 0 on successful pop, and -1 on error, or when
|
|
||||||
there are no elements to pop.
|
|
||||||
}\\
|
|
||||||
\hline
|
|
||||||
|
|
||||||
\code{ioman\_push} & \code{esint8 (IOManager *ioman,euint16 bufplace)} \\
|
|
||||||
\hline
|
|
||||||
\multicolumn{2}{|p{\textwidth}|}{
|
|
||||||
This function pushes the settings of cache \code{bufplace} onto that cache's stack. It does not
|
|
||||||
destroy the data in the main registers. It will return 0 for a successful push, and -1 on error, or
|
|
||||||
when there is no more space to push a new element.
|
|
||||||
}\\
|
|
||||||
\hline
|
|
||||||
|
|
||||||
\code{ioman\_readSector} & \code{esint8 (IOManager *ioman,euint32 address,euint8* buf)} \\
|
|
||||||
\hline
|
|
||||||
\multicolumn{2}{|p{\textwidth}|}{
|
|
||||||
This function does the actual reading from the hardware, it is the one and only function that
|
|
||||||
calls \code{if\_readBuf()}, here a retry on failure policy could be implemented. This function
|
|
||||||
will correctly stream errors upwards. All calls made to this function in the iomanager are checked
|
|
||||||
for their return value, so errors propagate correctly upwards.
|
|
||||||
|
|
||||||
The address it receives is relative to the beginning of the disc, no assumptions about \code{buf}
|
|
||||||
may be made, it can be withing ioman's cache memory range, but it could also be a buffer from userspace.
|
|
||||||
|
|
||||||
The function will return 0 on success and -1 on failure.
|
|
||||||
}\\
|
|
||||||
\hline
|
|
||||||
|
|
||||||
\code{ioman\_writeSector} & \code{esint8 (IOManager *ioman, euint32 address, euint8* buf)} \\
|
|
||||||
\hline
|
|
||||||
\multicolumn{2}{|p{\textwidth}|}{
|
|
||||||
This function does the actual writing to the hardware, it is the one and only function that
|
|
||||||
calls \code{if\_writeBuf()}, here a retry on failure policy could be implemented. This function
|
|
||||||
will correctly stream errors upwards. All calls made to this function in the iomanager are checked
|
|
||||||
for their return value, so errors propagate correctly upwards.
|
|
||||||
|
|
||||||
The address it receives is relative to the beginning of the disc, no assumptions about \code{buf}
|
|
||||||
may be made, it can be withing ioman's cache memory range, but it could also be a buffer from userspace.
|
|
||||||
|
|
||||||
The function will return 0 on success and -1 on failure.
|
|
||||||
}\\
|
|
||||||
\hline
|
|
||||||
|
|
||||||
\code{\external{ioman\_getSector}} & \code{euint8* (IOManager *ioman,euint32 address, euint8 mode)} \\
|
|
||||||
\hline
|
|
||||||
\multicolumn{2}{|p{\textwidth}|}{
|
|
||||||
This function is the one that is called most from the higher library routines. It is the function
|
|
||||||
that will present you with a pointer to memory containing sector number \code{address}. There are
|
|
||||||
several modes that you can select or combine.\newline
|
|
||||||
\begin{tabular}{|l|p{.6\textwidth}|}
|
|
||||||
\hline
|
|
||||||
\code{IOM\_MODE\_READONLY} & This attribute says to ioman that it needs a buffer only for reading.
|
|
||||||
This does not mean that you are allowed to write to it, doing so results in undefined behavior.
|
|
||||||
You cannot combine this option with the \code{IOM\_MODE\_READWRITE} option.\\
|
|
||||||
\code{IOM\_MODE\_READWRITE} & This attribute says to ioman that it would like not only to read from
|
|
||||||
but also to write to that buffer. When you release the sector your changes will be written to disc.
|
|
||||||
This may not happen immediately though, if you want to force it take a look at the
|
|
||||||
\code{ioman\_flushRange()} function. This option cannot be combined with the
|
|
||||||
\code{IOM\_MODE\_READONLY} option.\\
|
|
||||||
\code{IOM\_MODE\_EXP\_REQ} & This option tell the iomanager that the request is exceptional, for
|
|
||||||
example that the request is unlikely to happen again. The library adds this flags to the options
|
|
||||||
when requesting the bootrecord, to prevent it from getting a high rating, which should prevent it
|
|
||||||
from being removed from the cache.\\
|
|
||||||
\hline
|
|
||||||
\end{tabular}\newline
|
|
||||||
These options can be combined by ORing them together.
|
|
||||||
}\\
|
|
||||||
\hline
|
|
||||||
|
|
||||||
\code{ioman\_releaseSector} & \code{esint8 (IOManager *ioman,euint8* buf)} \\
|
|
||||||
\hline
|
|
||||||
\multicolumn{2}{|p{\textwidth}|}{
|
|
||||||
This function tells ioman that you are done with one of the cache elements and that it can do
|
|
||||||
it's bidding with it. Forgetting to call this function may result in deadlocked iomanagers.
|
|
||||||
}\\
|
|
||||||
\hline
|
|
||||||
|
|
||||||
\code{ioman\_directSectorRead} & \code{esint8 (IOManager *ioman,euint32 address, euint8* buf)} \\
|
|
||||||
\hline
|
|
||||||
\multicolumn{2}{|p{\textwidth}|}{
|
|
||||||
This is a variant of the normal getsector. Sometimes you need a sector from the disc, but all
|
|
||||||
you want to do with it is export it directly to userbuffers. It would be foolish to force a
|
|
||||||
caching of that sector if there is external space available for it.
|
|
||||||
|
|
||||||
This function will fetch sector \code{address} from disc and place it in the memory pointed to
|
|
||||||
by \code{buf}. Should there be a free spot available the sector will be cached there, so that
|
|
||||||
it may be used in the future. If the sector was available from cache in the first place, it
|
|
||||||
will simply be \code{memCpy()}'d from the cache to the userspace buffer.
|
|
||||||
}\\
|
|
||||||
\hline
|
|
||||||
|
|
||||||
\code{ioman\_directSectorWrite} & \code{esint8 (IOManager *ioman,euint32 address, euint8* buf)} \\
|
|
||||||
\hline
|
|
||||||
\multicolumn{2}{|p{\textwidth}|}{
|
|
||||||
This function is based on the same philosophy as \code{ioman\_directSectorRead()}, however,
|
|
||||||
contrary to what the name may lead to believe it also passes through a caching layer. If
|
|
||||||
there is an unused spot (or the sector is in cache), the userbuffer will be copied to that
|
|
||||||
spot and will remain there until the space is needed or a flush is forced.
|
|
||||||
}\\
|
|
||||||
\hline
|
|
||||||
|
|
||||||
\code{ioman\_flushRange} & \code{esint8 (IOManager *ioman,euint32 address\_low, euint32 address\_high)} \\
|
|
||||||
\hline
|
|
||||||
\multicolumn{2}{|p{\textwidth}|}{
|
|
||||||
This function is used to ask ioman to flush all sectors to disc that are in a specific
|
|
||||||
range. For example you might want to flush a specific range of your filesystem without
|
|
||||||
needlessly disturb other parts. The range is \code{address\_low <= n => address\_high}.
|
|
||||||
Off course only sectors that are marked as writable are flushed to disc.
|
|
||||||
}\\
|
|
||||||
\hline
|
|
||||||
|
|
||||||
\code{ioman\_flushAll} & \code{esint8 (IOManager *ioman)} \\
|
|
||||||
\hline
|
|
||||||
\multicolumn{2}{|p{\textwidth}|}{
|
|
||||||
This function will cause ioman to flush out all cache units that are marked writable. If
|
|
||||||
they do not have any users, they will lose their writable mark.
|
|
||||||
}\\
|
|
||||||
\hline
|
|
||||||
\end{longtable}
|
|
||||||
|
|
||||||
@@ -1,489 +0,0 @@
|
|||||||
GNU LESSER GENERAL PUBLIC LICENSE
|
|
||||||
Version 2.1, February 1999
|
|
||||||
|
|
||||||
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
|
|
||||||
51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
Everyone is permitted to copy and distribute verbatim copies
|
|
||||||
of this license document, but changing it is not allowed.
|
|
||||||
|
|
||||||
[This is the first released version of the Lesser GPL. It also counts
|
|
||||||
as the successor of the GNU Library Public License, version 2, hence
|
|
||||||
the version number 2.1.]
|
|
||||||
|
|
||||||
Preamble
|
|
||||||
|
|
||||||
The licenses for most software are designed to take away your
|
|
||||||
freedom to share and change it. By contrast, the GNU General Public
|
|
||||||
Licenses are intended to guarantee your freedom to share and change
|
|
||||||
free software--to make sure the software is free for all its users.
|
|
||||||
|
|
||||||
This license, the Lesser General Public License, applies to some
|
|
||||||
specially designated software packages--typically libraries--of the
|
|
||||||
Free Software Foundation and other authors who decide to use it. You
|
|
||||||
can use it too, but we suggest you first think carefully about whether
|
|
||||||
this license or the ordinary General Public License is the better
|
|
||||||
strategy to use in any particular case, based on the explanations below.
|
|
||||||
|
|
||||||
When we speak of free software, we are referring to freedom of use,
|
|
||||||
not price. Our General Public Licenses are designed to make sure that
|
|
||||||
you have the freedom to distribute copies of free software (and charge
|
|
||||||
for this service if you wish); that you receive source code or can get
|
|
||||||
it if you want it; that you can change the software and use pieces of
|
|
||||||
it in new free programs; and that you are informed that you can do
|
|
||||||
these things.
|
|
||||||
|
|
||||||
To protect your rights, we need to make restrictions that forbid
|
|
||||||
distributors to deny you these rights or to ask you to surrender these
|
|
||||||
rights. These restrictions translate to certain responsibilities for
|
|
||||||
you if you distribute copies of the library or if you modify it.
|
|
||||||
|
|
||||||
For example, if you distribute copies of the library, whether gratis
|
|
||||||
or for a fee, you must give the recipients all the rights that we gave
|
|
||||||
you. You must make sure that they, too, receive or can get the source
|
|
||||||
code. If you link other code with the library, you must provide
|
|
||||||
complete object files to the recipients, so that they can relink them
|
|
||||||
with the library after making changes to the library and recompiling
|
|
||||||
it. And you must show them these terms so they know their rights.
|
|
||||||
|
|
||||||
We protect your rights with a two-step method: (1) we copyright the
|
|
||||||
library, and (2) we offer you this license, which gives you legal
|
|
||||||
permission to copy, distribute and/or modify the library.
|
|
||||||
|
|
||||||
To protect each distributor, we want to make it very clear that
|
|
||||||
there is no warranty for the free library. Also, if the library is
|
|
||||||
modified by someone else and passed on, the recipients should know
|
|
||||||
that what they have is not the original version, so that the original
|
|
||||||
author's reputation will not be affected by problems that might be
|
|
||||||
introduced by others.
|
|
||||||
|
|
||||||
Finally, software patents pose a constant threat to the existence of
|
|
||||||
any free program. We wish to make sure that a company cannot
|
|
||||||
effectively restrict the users of a free program by obtaining a
|
|
||||||
restrictive license from a patent holder. Therefore, we insist that
|
|
||||||
any patent license obtained for a version of the library must be
|
|
||||||
consistent with the full freedom of use specified in this license.
|
|
||||||
|
|
||||||
Most GNU software, including some libraries, is covered by the
|
|
||||||
ordinary GNU General Public License. This license, the GNU Lesser
|
|
||||||
General Public License, applies to certain designated libraries, and
|
|
||||||
is quite different from the ordinary General Public License. We use
|
|
||||||
this license for certain libraries in order to permit linking those
|
|
||||||
libraries into non-free programs.
|
|
||||||
|
|
||||||
When a program is linked with a library, whether statically or using
|
|
||||||
a shared library, the combination of the two is legally speaking a
|
|
||||||
combined work, a derivative of the original library. The ordinary
|
|
||||||
General Public License therefore permits such linking only if the
|
|
||||||
entire combination fits its criteria of freedom. The Lesser General
|
|
||||||
Public License permits more lax criteria for linking other code with
|
|
||||||
the library.
|
|
||||||
|
|
||||||
We call this license the "Lesser" General Public License because it
|
|
||||||
does Less to protect the user's freedom than the ordinary General
|
|
||||||
Public License. It also provides other free software developers Less
|
|
||||||
of an advantage over competing non-free programs. These disadvantages
|
|
||||||
are the reason we use the ordinary General Public License for many
|
|
||||||
libraries. However, the Lesser license provides advantages in certain
|
|
||||||
special circumstances.
|
|
||||||
|
|
||||||
For example, on rare occasions, there may be a special need to
|
|
||||||
encourage the widest possible use of a certain library, so that it becomes
|
|
||||||
a de-facto standard. To achieve this, non-free programs must be
|
|
||||||
allowed to use the library. A more frequent case is that a free
|
|
||||||
library does the same job as widely used non-free libraries. In this
|
|
||||||
case, there is little to gain by limiting the free library to free
|
|
||||||
software only, so we use the Lesser General Public License.
|
|
||||||
|
|
||||||
In other cases, permission to use a particular library in non-free
|
|
||||||
programs enables a greater number of people to use a large body of
|
|
||||||
free software. For example, permission to use the GNU C Library in
|
|
||||||
non-free programs enables many more people to use the whole GNU
|
|
||||||
operating system, as well as its variant, the GNU/Linux operating
|
|
||||||
system.
|
|
||||||
|
|
||||||
Although the Lesser General Public License is Less protective of the
|
|
||||||
users' freedom, it does ensure that the user of a program that is
|
|
||||||
linked with the Library has the freedom and the wherewithal to run
|
|
||||||
that program using a modified version of the Library.
|
|
||||||
|
|
||||||
The precise terms and conditions for copying, distribution and
|
|
||||||
modification follow. Pay close attention to the difference between a
|
|
||||||
"work based on the library" and a "work that uses the library". The
|
|
||||||
former contains code derived from the library, whereas the latter must
|
|
||||||
be combined with the library in order to run.
|
|
||||||
|
|
||||||
GNU LESSER GENERAL PUBLIC LICENSE
|
|
||||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
|
||||||
|
|
||||||
0. This License Agreement applies to any software library or other
|
|
||||||
program which contains a notice placed by the copyright holder or
|
|
||||||
other authorized party saying it may be distributed under the terms of
|
|
||||||
this Lesser General Public License (also called "this License").
|
|
||||||
Each licensee is addressed as "you".
|
|
||||||
|
|
||||||
A "library" means a collection of software functions and/or data
|
|
||||||
prepared so as to be conveniently linked with application programs
|
|
||||||
(which use some of those functions and data) to form executables.
|
|
||||||
|
|
||||||
The "Library", below, refers to any such software library or work
|
|
||||||
which has been distributed under these terms. A "work based on the
|
|
||||||
Library" means either the Library or any derivative work under
|
|
||||||
copyright law: that is to say, a work containing the Library or a
|
|
||||||
portion of it, either verbatim or with modifications and/or translated
|
|
||||||
straightforwardly into another language. (Hereinafter, translation is
|
|
||||||
included without limitation in the term "modification".)
|
|
||||||
|
|
||||||
"Source code" for a work means the preferred form of the work for
|
|
||||||
making modifications to it. For a library, complete source code means
|
|
||||||
all the source code for all modules it contains, plus any associated
|
|
||||||
interface definition files, plus the scripts used to control compilation
|
|
||||||
and installation of the library.
|
|
||||||
|
|
||||||
Activities other than copying, distribution and modification are not
|
|
||||||
covered by this License; they are outside its scope. The act of
|
|
||||||
running a program using the Library is not restricted, and output from
|
|
||||||
such a program is covered only if its contents constitute a work based
|
|
||||||
on the Library (independent of the use of the Library in a tool for
|
|
||||||
writing it). Whether that is true depends on what the Library does
|
|
||||||
and what the program that uses the Library does.
|
|
||||||
|
|
||||||
1. You may copy and distribute verbatim copies of the Library's
|
|
||||||
complete source code as you receive it, in any medium, provided that
|
|
||||||
you conspicuously and appropriately publish on each copy an
|
|
||||||
appropriate copyright notice and disclaimer of warranty; keep intact
|
|
||||||
all the notices that refer to this License and to the absence of any
|
|
||||||
warranty; and distribute a copy of this License along with the
|
|
||||||
Library.
|
|
||||||
|
|
||||||
You may charge a fee for the physical act of transferring a copy,
|
|
||||||
and you may at your option offer warranty protection in exchange for a
|
|
||||||
fee.
|
|
||||||
|
|
||||||
2. You may modify your copy or copies of the Library or any portion
|
|
||||||
of it, thus forming a work based on the Library, and copy and
|
|
||||||
distribute such modifications or work under the terms of Section 1
|
|
||||||
above, provided that you also meet all of these conditions:
|
|
||||||
|
|
||||||
a) The modified work must itself be a software library.
|
|
||||||
|
|
||||||
b) You must cause the files modified to carry prominent notices
|
|
||||||
stating that you changed the files and the date of any change.
|
|
||||||
|
|
||||||
c) You must cause the whole of the work to be licensed at no
|
|
||||||
charge to all third parties under the terms of this License.
|
|
||||||
|
|
||||||
d) If a facility in the modified Library refers to a function or a
|
|
||||||
table of data to be supplied by an application program that uses
|
|
||||||
the facility, other than as an argument passed when the facility
|
|
||||||
is invoked, then you must make a good faith effort to ensure that,
|
|
||||||
in the event an application does not supply such function or
|
|
||||||
table, the facility still operates, and performs whatever part of
|
|
||||||
its purpose remains meaningful.
|
|
||||||
|
|
||||||
(For example, a function in a library to compute square roots has
|
|
||||||
a purpose that is entirely well-defined independent of the
|
|
||||||
application. Therefore, Subsection 2d requires that any
|
|
||||||
application-supplied function or table used by this function must
|
|
||||||
be optional: if the application does not supply it, the square
|
|
||||||
root function must still compute square roots.)
|
|
||||||
|
|
||||||
These requirements apply to the modified work as a whole. If
|
|
||||||
identifiable sections of that work are not derived from the Library,
|
|
||||||
and can be reasonably considered independent and separate works in
|
|
||||||
themselves, then this License, and its terms, do not apply to those
|
|
||||||
sections when you distribute them as separate works. But when you
|
|
||||||
distribute the same sections as part of a whole which is a work based
|
|
||||||
on the Library, the distribution of the whole must be on the terms of
|
|
||||||
this License, whose permissions for other licensees extend to the
|
|
||||||
entire whole, and thus to each and every part regardless of who wrote
|
|
||||||
it.
|
|
||||||
|
|
||||||
Thus, it is not the intent of this section to claim rights or contest
|
|
||||||
your rights to work written entirely by you; rather, the intent is to
|
|
||||||
exercise the right to control the distribution of derivative or
|
|
||||||
collective works based on the Library.
|
|
||||||
|
|
||||||
In addition, mere aggregation of another work not based on the Library
|
|
||||||
with the Library (or with a work based on the Library) on a volume of
|
|
||||||
a storage or distribution medium does not bring the other work under
|
|
||||||
the scope of this License.
|
|
||||||
|
|
||||||
3. You may opt to apply the terms of the ordinary GNU General Public
|
|
||||||
License instead of this License to a given copy of the Library. To do
|
|
||||||
this, you must alter all the notices that refer to this License, so
|
|
||||||
that they refer to the ordinary GNU General Public License, version 2,
|
|
||||||
instead of to this License. (If a newer version than version 2 of the
|
|
||||||
ordinary GNU General Public License has appeared, then you can specify
|
|
||||||
that version instead if you wish.) Do not make any other change in
|
|
||||||
these notices.
|
|
||||||
|
|
||||||
Once this change is made in a given copy, it is irreversible for
|
|
||||||
that copy, so the ordinary GNU General Public License applies to all
|
|
||||||
subsequent copies and derivative works made from that copy.
|
|
||||||
|
|
||||||
This option is useful when you wish to copy part of the code of
|
|
||||||
the Library into a program that is not a library.
|
|
||||||
|
|
||||||
4. You may copy and distribute the Library (or a portion or
|
|
||||||
derivative of it, under Section 2) in object code or executable form
|
|
||||||
under the terms of Sections 1 and 2 above provided that you accompany
|
|
||||||
it with the complete corresponding machine-readable source code, which
|
|
||||||
must be distributed under the terms of Sections 1 and 2 above on a
|
|
||||||
medium customarily used for software interchange.
|
|
||||||
|
|
||||||
If distribution of object code is made by offering access to copy
|
|
||||||
from a designated place, then offering equivalent access to copy the
|
|
||||||
source code from the same place satisfies the requirement to
|
|
||||||
distribute the source code, even though third parties are not
|
|
||||||
compelled to copy the source along with the object code.
|
|
||||||
|
|
||||||
5. A program that contains no derivative of any portion of the
|
|
||||||
Library, but is designed to work with the Library by being compiled or
|
|
||||||
linked with it, is called a "work that uses the Library". Such a
|
|
||||||
work, in isolation, is not a derivative work of the Library, and
|
|
||||||
therefore falls outside the scope of this License.
|
|
||||||
|
|
||||||
However, linking a "work that uses the Library" with the Library
|
|
||||||
creates an executable that is a derivative of the Library (because it
|
|
||||||
contains portions of the Library), rather than a "work that uses the
|
|
||||||
library". The executable is therefore covered by this License.
|
|
||||||
Section 6 states terms for distribution of such executables.
|
|
||||||
|
|
||||||
When a "work that uses the Library" uses material from a header file
|
|
||||||
that is part of the Library, the object code for the work may be a
|
|
||||||
derivative work of the Library even though the source code is not.
|
|
||||||
Whether this is true is especially significant if the work can be
|
|
||||||
linked without the Library, or if the work is itself a library. The
|
|
||||||
threshold for this to be true is not precisely defined by law.
|
|
||||||
|
|
||||||
If such an object file uses only numerical parameters, data
|
|
||||||
structure layouts and accessors, and small macros and small inline
|
|
||||||
functions (ten lines or less in length), then the use of the object
|
|
||||||
file is unrestricted, regardless of whether it is legally a derivative
|
|
||||||
work. (Executables containing this object code plus portions of the
|
|
||||||
Library will still fall under Section 6.)
|
|
||||||
|
|
||||||
Otherwise, if the work is a derivative of the Library, you may
|
|
||||||
distribute the object code for the work under the terms of Section 6.
|
|
||||||
Any executables containing that work also fall under Section 6,
|
|
||||||
whether or not they are linked directly with the Library itself.
|
|
||||||
|
|
||||||
6. As an exception to the Sections above, you may also combine or
|
|
||||||
link a "work that uses the Library" with the Library to produce a
|
|
||||||
work containing portions of the Library, and distribute that work
|
|
||||||
under terms of your choice, provided that the terms permit
|
|
||||||
modification of the work for the customer's own use and reverse
|
|
||||||
engineering for debugging such modifications.
|
|
||||||
|
|
||||||
You must give prominent notice with each copy of the work that the
|
|
||||||
Library is used in it and that the Library and its use are covered by
|
|
||||||
this License. You must supply a copy of this License. If the work
|
|
||||||
during execution displays copyright notices, you must include the
|
|
||||||
copyright notice for the Library among them, as well as a reference
|
|
||||||
directing the user to the copy of this License. Also, you must do one
|
|
||||||
of these things:
|
|
||||||
|
|
||||||
a) Accompany the work with the complete corresponding
|
|
||||||
machine-readable source code for the Library including whatever
|
|
||||||
changes were used in the work (which must be distributed under
|
|
||||||
Sections 1 and 2 above); and, if the work is an executable linked
|
|
||||||
with the Library, with the complete machine-readable "work that
|
|
||||||
uses the Library", as object code and/or source code, so that the
|
|
||||||
user can modify the Library and then relink to produce a modified
|
|
||||||
executable containing the modified Library. (It is understood
|
|
||||||
that the user who changes the contents of definitions files in the
|
|
||||||
Library will not necessarily be able to recompile the application
|
|
||||||
to use the modified definitions.)
|
|
||||||
|
|
||||||
b) Use a suitable shared library mechanism for linking with the
|
|
||||||
Library. A suitable mechanism is one that (1) uses at run time a
|
|
||||||
copy of the library already present on the user's computer system,
|
|
||||||
rather than copying library functions into the executable, and (2)
|
|
||||||
will operate properly with a modified version of the library, if
|
|
||||||
the user installs one, as long as the modified version is
|
|
||||||
interface-compatible with the version that the work was made with.
|
|
||||||
|
|
||||||
c) Accompany the work with a written offer, valid for at
|
|
||||||
least three years, to give the same user the materials
|
|
||||||
specified in Subsection 6a, above, for a charge no more
|
|
||||||
than the cost of performing this distribution.
|
|
||||||
|
|
||||||
d) If distribution of the work is made by offering access to copy
|
|
||||||
from a designated place, offer equivalent access to copy the above
|
|
||||||
specified materials from the same place.
|
|
||||||
|
|
||||||
e) Verify that the user has already received a copy of these
|
|
||||||
materials or that you have already sent this user a copy.
|
|
||||||
|
|
||||||
For an executable, the required form of the "work that uses the
|
|
||||||
Library" must include any data and utility programs needed for
|
|
||||||
reproducing the executable from it. However, as a special exception,
|
|
||||||
the materials to be distributed need not include anything that is
|
|
||||||
normally distributed (in either source or binary form) with the major
|
|
||||||
components (compiler, kernel, and so on) of the operating system on
|
|
||||||
which the executable runs, unless that component itself accompanies
|
|
||||||
the executable.
|
|
||||||
|
|
||||||
It may happen that this requirement contradicts the license
|
|
||||||
restrictions of other proprietary libraries that do not normally
|
|
||||||
accompany the operating system. Such a contradiction means you cannot
|
|
||||||
use both them and the Library together in an executable that you
|
|
||||||
distribute.
|
|
||||||
|
|
||||||
7. You may place library facilities that are a work based on the
|
|
||||||
Library side-by-side in a single library together with other library
|
|
||||||
facilities not covered by this License, and distribute such a combined
|
|
||||||
library, provided that the separate distribution of the work based on
|
|
||||||
the Library and of the other library facilities is otherwise
|
|
||||||
permitted, and provided that you do these two things:
|
|
||||||
|
|
||||||
a) Accompany the combined library with a copy of the same work
|
|
||||||
based on the Library, uncombined with any other library
|
|
||||||
facilities. This must be distributed under the terms of the
|
|
||||||
Sections above.
|
|
||||||
|
|
||||||
b) Give prominent notice with the combined library of the fact
|
|
||||||
that part of it is a work based on the Library, and explaining
|
|
||||||
where to find the accompanying uncombined form of the same work.
|
|
||||||
|
|
||||||
8. You may not copy, modify, sublicense, link with, or distribute
|
|
||||||
the Library except as expressly provided under this License. Any
|
|
||||||
attempt otherwise to copy, modify, sublicense, link with, or
|
|
||||||
distribute the Library is void, and will automatically terminate your
|
|
||||||
rights under this License. However, parties who have received copies,
|
|
||||||
or rights, from you under this License will not have their licenses
|
|
||||||
terminated so long as such parties remain in full compliance.
|
|
||||||
|
|
||||||
9. You are not required to accept this License, since you have not
|
|
||||||
signed it. However, nothing else grants you permission to modify or
|
|
||||||
distribute the Library or its derivative works. These actions are
|
|
||||||
prohibited by law if you do not accept this License. Therefore, by
|
|
||||||
modifying or distributing the Library (or any work based on the
|
|
||||||
Library), you indicate your acceptance of this License to do so, and
|
|
||||||
all its terms and conditions for copying, distributing or modifying
|
|
||||||
the Library or works based on it.
|
|
||||||
|
|
||||||
10. Each time you redistribute the Library (or any work based on the
|
|
||||||
Library), the recipient automatically receives a license from the
|
|
||||||
original licensor to copy, distribute, link with or modify the Library
|
|
||||||
subject to these terms and conditions. You may not impose any further
|
|
||||||
restrictions on the recipients' exercise of the rights granted herein.
|
|
||||||
You are not responsible for enforcing compliance by third parties with
|
|
||||||
this License.
|
|
||||||
|
|
||||||
11. If, as a consequence of a court judgment or allegation of patent
|
|
||||||
infringement or for any other reason (not limited to patent issues),
|
|
||||||
conditions are imposed on you (whether by court order, agreement or
|
|
||||||
otherwise) that contradict the conditions of this License, they do not
|
|
||||||
excuse you from the conditions of this License. If you cannot
|
|
||||||
distribute so as to satisfy simultaneously your obligations under this
|
|
||||||
License and any other pertinent obligations, then as a consequence you
|
|
||||||
may not distribute the Library at all. For example, if a patent
|
|
||||||
license would not permit royalty-free redistribution of the Library by
|
|
||||||
all those who receive copies directly or indirectly through you, then
|
|
||||||
the only way you could satisfy both it and this License would be to
|
|
||||||
refrain entirely from distribution of the Library.
|
|
||||||
|
|
||||||
If any portion of this section is held invalid or unenforceable under any
|
|
||||||
particular circumstance, the balance of the section is intended to apply,
|
|
||||||
and the section as a whole is intended to apply in other circumstances.
|
|
||||||
|
|
||||||
It is not the purpose of this section to induce you to infringe any
|
|
||||||
patents or other property right claims or to contest validity of any
|
|
||||||
such claims; this section has the sole purpose of protecting the
|
|
||||||
integrity of the free software distribution system which is
|
|
||||||
implemented by public license practices. Many people have made
|
|
||||||
generous contributions to the wide range of software distributed
|
|
||||||
through that system in reliance on consistent application of that
|
|
||||||
system; it is up to the author/donor to decide if he or she is willing
|
|
||||||
to distribute software through any other system and a licensee cannot
|
|
||||||
impose that choice.
|
|
||||||
|
|
||||||
This section is intended to make thoroughly clear what is believed to
|
|
||||||
be a consequence of the rest of this License.
|
|
||||||
|
|
||||||
12. If the distribution and/or use of the Library is restricted in
|
|
||||||
certain countries either by patents or by copyrighted interfaces, the
|
|
||||||
original copyright holder who places the Library under this License may add
|
|
||||||
an explicit geographical distribution limitation excluding those countries,
|
|
||||||
so that distribution is permitted only in or among countries not thus
|
|
||||||
excluded. In such case, this License incorporates the limitation as if
|
|
||||||
written in the body of this License.
|
|
||||||
|
|
||||||
13. The Free Software Foundation may publish revised and/or new
|
|
||||||
versions of the Lesser General Public License from time to time.
|
|
||||||
Such new versions will be similar in spirit to the present version,
|
|
||||||
but may differ in detail to address new problems or concerns.
|
|
||||||
|
|
||||||
Each version is given a distinguishing version number. If the Library
|
|
||||||
specifies a version number of this License which applies to it and
|
|
||||||
"any later version", you have the option of following the terms and
|
|
||||||
conditions either of that version or of any later version published by
|
|
||||||
the Free Software Foundation. If the Library does not specify a
|
|
||||||
license version number, you may choose any version ever published by
|
|
||||||
the Free Software Foundation.
|
|
||||||
|
|
||||||
14. If you wish to incorporate parts of the Library into other free
|
|
||||||
programs whose distribution conditions are incompatible with these,
|
|
||||||
write to the author to ask for permission. For software which is
|
|
||||||
copyrighted by the Free Software Foundation, write to the Free
|
|
||||||
Software Foundation; we sometimes make exceptions for this. Our
|
|
||||||
decision will be guided by the two goals of preserving the free status
|
|
||||||
of all derivatives of our free software and of promoting the sharing
|
|
||||||
and reuse of software generally.
|
|
||||||
|
|
||||||
NO WARRANTY
|
|
||||||
|
|
||||||
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
|
|
||||||
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
|
|
||||||
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
|
|
||||||
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
|
|
||||||
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
|
|
||||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
|
||||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
|
|
||||||
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
|
|
||||||
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
|
||||||
|
|
||||||
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
|
|
||||||
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
|
|
||||||
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
|
|
||||||
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
|
|
||||||
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
|
|
||||||
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
|
|
||||||
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
|
|
||||||
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
|
|
||||||
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
|
||||||
DAMAGES.
|
|
||||||
|
|
||||||
END OF TERMS AND CONDITIONS
|
|
||||||
|
|
||||||
How to Apply These Terms to Your New Libraries
|
|
||||||
|
|
||||||
If you develop a new library, and you want it to be of the greatest
|
|
||||||
possible use to the public, we recommend making it free software that
|
|
||||||
everyone can redistribute and change. You can do so by permitting
|
|
||||||
redistribution under these terms (or, alternatively, under the terms of the
|
|
||||||
ordinary General Public License).
|
|
||||||
|
|
||||||
To apply these terms, attach the following notices to the library. It is
|
|
||||||
safest to attach them to the start of each source file to most effectively
|
|
||||||
convey the exclusion of warranty; and each file should have at least the
|
|
||||||
"copyright" line and a pointer to where the full notice is found.
|
|
||||||
|
|
||||||
<one line to give the library's name and a brief idea of what it does.>
|
|
||||||
Copyright (C) <year> <name of author>
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library 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
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with this library; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
This library is subject to the Lesser General Public License version 2.1.
|
|
||||||
We have chosen this license in stead of the BSD license because we feel strongly
|
|
||||||
that more effort was needed in the field of quality software in the embedded field.
|
|
||||||
|
|
||||||
Please note that if you make changes to the library itself, those modifications must be
|
|
||||||
made public, but that writing support for new hardware and linking it into the library,
|
|
||||||
does not fall under this category. However, we would off course appreciate it tremendously
|
|
||||||
if you would send us in code to support new hardware.
|
|
||||||
|
|
||||||
\subsection{GNU Lesser General Public License}
|
|
||||||
\verbatiminput{pages/lgpl.txt}
|
|
||||||
|
|
||||||
@@ -1,138 +0,0 @@
|
|||||||
Debugging efsl on embedded devices is a rather hard job, because
|
|
||||||
you can't just printf debug strings or watch memory maps easily.
|
|
||||||
Because of that, core development has been performed under the
|
|
||||||
Linux operating system. Under Linux, efsl can be compiled as
|
|
||||||
library and used as a userspace filesystem handler. On Unix-
|
|
||||||
style operating system (like Linux), all devices (usb stick, disc, \ldots)
|
|
||||||
can be seen as a file, and as such been opened by efsl.\newline
|
|
||||||
\newline
|
|
||||||
In the following section, we will explain how to get started using
|
|
||||||
efsl as userspace filesystem handler. However, please note that the main
|
|
||||||
focus for efsl is to support embedded systems, which usually don't even
|
|
||||||
have 1\% of the memory you have on a PC. Accessing files on a FAT-filesystem
|
|
||||||
with efsl will be much slower than when accessing these files with the Linux
|
|
||||||
FAT kernel modules.
|
|
||||||
\subsubsection{Download \& Compile}
|
|
||||||
Let's get started:
|
|
||||||
\begin{enumerate}
|
|
||||||
\item{Get the latest release of efsl on http://www.sf.net/projects/efsl/
|
|
||||||
and put it in your homedir}
|
|
||||||
\item{Unpack the library (tar xvfj efsl-version.tar.bz2)}
|
|
||||||
\item{Get inside the directory (cd $\sim$/efsl)}
|
|
||||||
\item{Create a symlink from \filename{Makefile-LINUX} to \filename{Makefile}
|
|
||||||
(ln -s Makefile-LINUX Makefile)}
|
|
||||||
\item{Copy \filename{conf/config-sample-linux.h} to \filename{conf/config.h}
|
|
||||||
(cp conf/config-sample-linux.h conf/config.h)}
|
|
||||||
\item{Compile the library (make lib)}
|
|
||||||
\item{Find the compiled filesystem library (libefsl.a) in the current
|
|
||||||
directory}
|
|
||||||
\end{enumerate}
|
|
||||||
If you got any errors with the steps above, please check that that you have
|
|
||||||
the following packages installed: tar, gcc, libgcc, binutils \& make.
|
|
||||||
\subsubsection{Example}
|
|
||||||
Since efsl itself is only a library, it's not supposed to do anything
|
|
||||||
out of the box, than just compile. To get started, we'll show here a small
|
|
||||||
example program that opens a file on a disc/usb-stick/floppy that contains
|
|
||||||
a FAT-filesystem and prints it's content to stdout.\newline
|
|
||||||
\newline
|
|
||||||
First, create a new directory in which you put the compiled efsl-library
|
|
||||||
(\filename{libefsl.a}) and create a new file called \filename{linuxtest.c} containing:
|
|
||||||
\lstset{numbers=left, stepnumber=1, numberstyle=\small, numbersep=5pt, tabsize=4}
|
|
||||||
\begin{lstlisting}
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <efs.h>
|
|
||||||
|
|
||||||
int main(void)
|
|
||||||
{
|
|
||||||
EmbeddedFileSystem efs;
|
|
||||||
EmbeddedFile file;
|
|
||||||
unsigned short i,e;
|
|
||||||
char buf[512];
|
|
||||||
|
|
||||||
if(efs_init(&efs,"/dev/sda")!=0){
|
|
||||||
printf("Could not open filesystem.\n");
|
|
||||||
return(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(file_fopen(&file,&efs.myFs,"group",'r')!=0){
|
|
||||||
printf("Could not open file.\n");
|
|
||||||
return(-2);
|
|
||||||
}
|
|
||||||
|
|
||||||
while(e=file_read(&file,512,buf)){
|
|
||||||
for(i=0;i<e;i++)
|
|
||||||
printf("\%c",buf[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return(0);
|
|
||||||
}
|
|
||||||
\end{lstlisting}
|
|
||||||
$ $\newline
|
|
||||||
Some extra information on the code above:
|
|
||||||
\begin{itemize}
|
|
||||||
\item{Line 1-2: The header files for stdio (used for printf) and efsl
|
|
||||||
are included. When using the basic efsl functions, \filename{efs.h} is
|
|
||||||
the only header file of the efsl library that needs to be included.}
|
|
||||||
\item{Line 6: The object efs is created, this object will contain
|
|
||||||
information about the hardware layer, the partition table and
|
|
||||||
the disc.}
|
|
||||||
\item{Line 7: The object file is created, this object will contain
|
|
||||||
information about the file that we will open on the efs-object.}
|
|
||||||
\item{Line 9: A buffer of 512 bytes is allocated. This buffer will
|
|
||||||
be filled by fread with data.}
|
|
||||||
\item{Line 11-14: Call of \code{efs\_init}, which will initialize the efs-object.
|
|
||||||
To this function we pass:
|
|
||||||
\begin{enumerate}
|
|
||||||
\item{A pointer to the efs-object.}
|
|
||||||
\item{A pointer to the file that contains the partition table /
|
|
||||||
file system (in this example, we select a device as file).}
|
|
||||||
\end{enumerate}
|
|
||||||
If this function returns 0, it means that a valid fat partition is
|
|
||||||
found on the device given.
|
|
||||||
If no valid fat-filesystem is found, or the file does not exist, the
|
|
||||||
function returns a negative value. In this example we then print an
|
|
||||||
error message and quit.}
|
|
||||||
\item{Line 16-19: Call of \code{file\_fopen()}, which will initialize the
|
|
||||||
file-object. To this function we pass:
|
|
||||||
\begin{enumerate}
|
|
||||||
\item{A pointer to the file-object.}
|
|
||||||
\item{A pointer to the filesystem-object.}
|
|
||||||
\item{A pointer to the filename.}
|
|
||||||
\item{A char containing the the mode (read, write, append).}
|
|
||||||
\end{enumerate}
|
|
||||||
If this function returns 0, it means the file has successfully been
|
|
||||||
opened for reading / writing / appending.
|
|
||||||
If the file could not be opened, a negative value is returned.
|
|
||||||
}
|
|
||||||
\item{Line 21-24: Call of \code{file\_read()}, which will read a given value of
|
|
||||||
bytes (in this example 512) from a file and put it's content into
|
|
||||||
the buffer passed (in this example called buf). This function returns
|
|
||||||
the amount of bytes read, so the while-loop will be executed as long
|
|
||||||
as there are bytes left in the file. The code inside the while-loop
|
|
||||||
will print all characters in the buffer.}
|
|
||||||
\end{itemize}
|
|
||||||
\subsubsection{Testing}
|
|
||||||
So now let's test the program:
|
|
||||||
\begin{enumerate}
|
|
||||||
\item{Compile the program
|
|
||||||
(gcc -I/home/user/efsl/inc/ -I/home/user/efsl/conf -o linuxtest
|
|
||||||
linuxtest.c -L./ -lefsl).}
|
|
||||||
\item{Insert a usb-disc, floppy, mp3-stick, \ldots with a valid
|
|
||||||
fat-filesystem on it.}
|
|
||||||
\item{Mount the device, copy the file /etc/group on it's root dir \& umount
|
|
||||||
it.}
|
|
||||||
\item{Check that you have permission to access the device
|
|
||||||
(chown username /dev/sda*)}
|
|
||||||
\item{Run the program (./linuxtest)}
|
|
||||||
\end{enumerate}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,52 +0,0 @@
|
|||||||
\subsubsection*{Purpose}
|
|
||||||
This function fetches the next valid file in the current directory and copies
|
|
||||||
all relevant information to \code{dirlist->currentEntry}.
|
|
||||||
\subsubsection*{Prototype}
|
|
||||||
\code{esint8 ls\_getNext(DirList *dlist);}
|
|
||||||
\subsubsection*{Arguments}
|
|
||||||
Objects passed to \code{ls\_getNext}:
|
|
||||||
\begin{itemize}
|
|
||||||
\item{\code{dlist}: pointer to a DirList object}
|
|
||||||
\end{itemize}
|
|
||||||
\subsubsection*{Return value}
|
|
||||||
This function will return 0 when it has found a next file in the directory, and
|
|
||||||
was successful in copying it to \code{dirlist->currentEntry}. It will return -1
|
|
||||||
when there are no more files in the directory.
|
|
||||||
|
|
||||||
\subsubsection*{Example}
|
|
||||||
To browse through a directory you should first open it with \code{ls\_openDir} and
|
|
||||||
then you can call \code{ls\_getNext} in a loop to iterate through the files. Please
|
|
||||||
note that they are unsorted.
|
|
||||||
\lstset{numbers=left, stepnumber=1, numberstyle=\small, numbersep=5pt, tabsize=4}
|
|
||||||
\begin{lstlisting}
|
|
||||||
#include "efs.h"
|
|
||||||
#include "ls.h"
|
|
||||||
|
|
||||||
void main(void)
|
|
||||||
{
|
|
||||||
EmbeddedFileSystem efsl;
|
|
||||||
DirList list;
|
|
||||||
|
|
||||||
/* Initialize efsl */
|
|
||||||
if(efs_init(&efsl,"/dev/sda")!=0){
|
|
||||||
DBG((TXT("Could not initialize filesystem (err \%d).\n"),ret));
|
|
||||||
exit(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Open the directory */
|
|
||||||
ls_openDir(list,&(efsl.myFs),"/usr/bin/");
|
|
||||||
|
|
||||||
/* Print a list of all files and their filesize */
|
|
||||||
while(ls_getNext(list)==0){
|
|
||||||
DBG((TXT("%s (%li bytes)\n"),
|
|
||||||
list->currentEntry.FileName,
|
|
||||||
list->currentEntry.FileSize));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Correctly close the filesystem */
|
|
||||||
fs_umount(&efs.myFs);
|
|
||||||
}
|
|
||||||
\end{lstlisting}
|
|
||||||
|
|
||||||
Please note that it is not required to close this object, if you wish to switch
|
|
||||||
to another directory you can just call \code{ls\_openDir} on the object again.
|
|
||||||
@@ -1,42 +0,0 @@
|
|||||||
\subsubsection*{Purpose}
|
|
||||||
This function opens a directory for viewing, allowing you to iterate through
|
|
||||||
it's contents.
|
|
||||||
\subsubsection*{Prototype}
|
|
||||||
\code{esint8 ls\_openDir(DirList *dlist,FileSystem *fs,eint8* dirname);}
|
|
||||||
\subsubsection*{Arguments}
|
|
||||||
Objects passed to \code{ls\_openDir}:
|
|
||||||
\begin{itemize}
|
|
||||||
\item{\code{dlist}: pointer to a DirList object}
|
|
||||||
\item{\code{fs}: pointer to the FileSystem object}
|
|
||||||
\item{\code{dirname}: C string containing the directorypath}
|
|
||||||
\end{itemize}
|
|
||||||
\subsubsection*{Return value}
|
|
||||||
This function will return 0 when it has opened the directory, and -1 on error.\\
|
|
||||||
|
|
||||||
\subsubsection*{Example}
|
|
||||||
\lstset{numbers=left, stepnumber=1, numberstyle=\small, numbersep=5pt, tabsize=4}
|
|
||||||
\begin{lstlisting}
|
|
||||||
#include "efs.h"
|
|
||||||
#include "ls.h"
|
|
||||||
|
|
||||||
void main(void)
|
|
||||||
{
|
|
||||||
EmbeddedFileSystem efsl;
|
|
||||||
DirList list;
|
|
||||||
|
|
||||||
/* Initialize efsl */
|
|
||||||
if(efs_init(&efsl,"/dev/sda")!=0){
|
|
||||||
DBG((TXT("Could not initialize filesystem (err \%d).\n"),ret));
|
|
||||||
exit(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Open the directory */
|
|
||||||
ls_openDir(list,&(efsl.myFs),"/usr/bin/");
|
|
||||||
|
|
||||||
/* Correctly close the filesystem */
|
|
||||||
fs_umount(&efs.myFs);
|
|
||||||
}
|
|
||||||
\end{lstlisting}
|
|
||||||
|
|
||||||
Please note that it is not required to close this object, if you wish to switch
|
|
||||||
to another directory you can just call \code{ls\_openDir} on the object again.
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user