Compare commits
176 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e3cc6f41e2 | ||
|
|
5a439f56bb | ||
|
|
7a8ae11ce1 | ||
|
|
e177b17ad8 | ||
|
|
54acc416b0 | ||
|
|
185b833929 | ||
|
|
97137ed993 | ||
|
|
e13b124e93 | ||
|
|
76254835ca | ||
|
|
1adabc080f | ||
|
|
6eead3e37d | ||
|
|
05bb485495 | ||
|
|
3c39e11784 | ||
|
|
2ad1d63ca6 | ||
|
|
53376edc09 | ||
|
|
ef82981d42 | ||
|
|
697742d59f | ||
|
|
6935aa9693 | ||
|
|
67e02fb38e | ||
|
|
a9a366895a | ||
|
|
596a26323a | ||
|
|
13c71760c8 | ||
|
|
f027b93a1a | ||
|
|
5b6e62a428 | ||
|
|
ea3113142e | ||
|
|
08a1c0b3e0 | ||
|
|
2e59b07d7d | ||
|
|
ec555efafd | ||
|
|
cfceee4db3 | ||
|
|
1d0eae3aec | ||
|
|
650b182ab4 | ||
|
|
b092b3e182 | ||
|
|
ab3f7704f0 | ||
|
|
859dcadbac | ||
|
|
c897497e24 | ||
|
|
ba64d2a683 | ||
|
|
65a852ebb4 | ||
|
|
2e99c42510 | ||
|
|
d777415549 | ||
|
|
3f91df1af6 | ||
|
|
1bbc73c363 | ||
|
|
a019317b6e | ||
|
|
243658c0d3 | ||
|
|
080598cb97 | ||
|
|
51087abaa2 | ||
|
|
7671a35127 | ||
|
|
1a7fb2487e | ||
|
|
a341e10efc | ||
|
|
b7cc7ea935 | ||
|
|
55aa99c4d3 | ||
|
|
2e432cd7a7 | ||
|
|
d3a48efb0b | ||
|
|
7c9aca48c9 | ||
|
|
440c24ad78 | ||
|
|
0d7fc524f2 | ||
|
|
b2e13a54eb | ||
|
|
850d1790cb | ||
|
|
9b3dcc844f | ||
|
|
5767b13385 | ||
|
|
ec68a9a1a1 | ||
|
|
54ac4204ed | ||
|
|
8a8b21615c | ||
|
|
49df405d14 | ||
|
|
7f0a9f9285 | ||
|
|
e7e5cfd126 | ||
|
|
6c702b9a68 | ||
|
|
2bdc53bd21 | ||
|
|
415b79751d | ||
|
|
b9425b1da5 | ||
|
|
9c4c880b0b | ||
|
|
c6b9c57e6d | ||
|
|
0295c8c385 | ||
|
|
2e01e2bfb3 | ||
|
|
07a0296886 | ||
|
|
0d473fd0dd | ||
|
|
5451aeb39b | ||
|
|
fa27d73167 | ||
|
|
4b0bec820e | ||
|
|
105575bc37 | ||
|
|
8beb0bbb4f | ||
|
|
6db781d12d | ||
|
|
a86d9d26bd | ||
|
|
d86f0ad5a9 | ||
|
|
d9b729754c | ||
|
|
f5cdf71fb1 | ||
|
|
d008551968 | ||
|
|
0d2c2c274b | ||
|
|
a28a7e928a | ||
|
|
8650109879 | ||
|
|
c30ca4ca54 | ||
|
|
2d601dac17 | ||
|
|
f8599fb60a | ||
|
|
db616a1637 | ||
|
|
935c1d6f7f | ||
|
|
325a09eff2 | ||
|
|
dab671a5da | ||
|
|
485a7831db | ||
|
|
99cee555c1 | ||
|
|
dc67d91c4f | ||
|
|
90d4a0d019 | ||
|
|
9be841521f | ||
|
|
e3067c7256 | ||
|
|
3a1f58ce18 | ||
|
|
a6e8d7e033 | ||
|
|
1fb3cfdfd9 | ||
|
|
04b2b9a02a | ||
|
|
58b422771a | ||
|
|
6256cab7ef | ||
|
|
c60d2f92fa | ||
|
|
aeb3638e1f | ||
|
|
0b81db48e3 | ||
|
|
5e31bc1946 | ||
|
|
9e1fec1ec6 | ||
|
|
87b5936c02 | ||
|
|
9efca9e242 | ||
|
|
f9e1a7a151 | ||
|
|
68b882acfb | ||
|
|
3928f5548e | ||
|
|
b8a45b6a38 | ||
|
|
bc08b4a71a | ||
|
|
9469398c04 | ||
|
|
bb1367c243 | ||
|
|
710aa2d53a | ||
|
|
9908f32103 | ||
|
|
2a143d3d9f | ||
|
|
72678f3ed5 | ||
|
|
3381998d0f | ||
|
|
98c470dbc0 | ||
|
|
cd948a94d1 | ||
|
|
346216ceb8 | ||
|
|
4bd3876adc | ||
|
|
c6e27c7c1f | ||
|
|
44df97f81a | ||
|
|
b1db3f6ae0 | ||
|
|
f273b986c1 | ||
|
|
bb209bb464 | ||
|
|
507957f7cc | ||
|
|
a741a2ff3a | ||
|
|
ba7f2dd94b | ||
|
|
4fa167a61d | ||
|
|
b375b0d510 | ||
|
|
ced4b73075 | ||
|
|
0887e64266 | ||
|
|
34ed695dee | ||
|
|
d8eb1eb4a4 | ||
|
|
d67158f523 | ||
|
|
ce327a382e | ||
|
|
ba27b79bb3 | ||
|
|
fb86f7ba7b | ||
|
|
0981d9fd3c | ||
|
|
982c56e426 | ||
|
|
d8f6f8f748 | ||
|
|
096227ca98 | ||
|
|
d8b23614d7 | ||
|
|
d1415c6283 | ||
|
|
ee9b377698 | ||
|
|
98ac61c91d | ||
|
|
752a16fd07 | ||
|
|
b47af2c376 | ||
|
|
07086b2a3c | ||
|
|
bfc795d35b | ||
|
|
dbff180a91 | ||
|
|
df167b285e | ||
|
|
cd7ac81a2d | ||
|
|
f7dc5b3bd8 | ||
|
|
1f68465dc6 | ||
|
|
5e5df7e275 | ||
|
|
ba2ac254a7 | ||
|
|
1282e93334 | ||
|
|
decb810bcc | ||
|
|
b6d5d1b571 | ||
|
|
406c884cfe | ||
|
|
6ef9989320 | ||
|
|
97962b8e89 | ||
|
|
cf95b95723 | ||
|
|
af45ed720b |
@@ -1,4 +0,0 @@
|
||||
--- !ditz.rubyforge.org,2008-03-06/config
|
||||
name: David
|
||||
email: david@optixx.org
|
||||
issue_dir: bugs
|
||||
9
.gitignore
vendored
9
.gitignore
vendored
@@ -27,3 +27,12 @@
|
||||
*.vfat
|
||||
*.wla*
|
||||
*.rcc
|
||||
*.log
|
||||
bootloader
|
||||
snesuploader
|
||||
tmtags
|
||||
bsnes
|
||||
web
|
||||
ucon64.exe
|
||||
|
||||
|
||||
|
||||
8
README
8
README
@@ -0,0 +1,8 @@
|
||||
________ .__ __ ________ ____ ________
|
||||
\_____ \ __ __|__| ____ | | __\______ \ _______ _/_ |/ _____/
|
||||
/ / \ \| | \ |/ ___\| |/ / | | \_/ __ \ \/ /| / __ \
|
||||
/ \_/. \ | / \ \___| < | ` \ ___/\ / | \ |__\ \
|
||||
\_____\ \_/____/|__|\___ >__|_ \/_______ /\___ >\_/ |___|\_____ /
|
||||
\__> \/ \/ \/ \/ \/
|
||||
|
||||
www.optixx.org
|
||||
@@ -67,7 +67,7 @@ clean:
|
||||
|
||||
.PHONY: all clean interactive-isp interactive-serial launch-bootloader
|
||||
|
||||
flash:
|
||||
flash: bootloader.hex
|
||||
$(AVRDUDE) $(AVRDUDE_FLAGS) -c $(ISP_PROG) -U flash:w:$<
|
||||
|
||||
flash-eeprom-%: %.eep.hex
|
||||
|
||||
@@ -33,6 +33,10 @@
|
||||
#include "config.h"
|
||||
#include "usbdrv/usbdrv.c"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* USBasp requests, taken from the original USBasp sourcecode
|
||||
*/
|
||||
@@ -74,8 +78,12 @@
|
||||
(LED_DIR ^= (1 << LED_PIN)));}
|
||||
|
||||
|
||||
#define AVR_BTLDR_EN_PORT PORTC
|
||||
#define AVR_BTLDR_EN_DIR DDRC
|
||||
#define AVR_BTLDR_EN_PIN PC1
|
||||
#define AVR_BTLDR_EN_IN PINC
|
||||
|
||||
|
||||
#undef AVR_BTLDR_SWITCH
|
||||
/*
|
||||
* some predefined signatures, taken from the original USBasp sourcecode
|
||||
*/
|
||||
@@ -286,7 +294,7 @@ usbMsgLen_t usbFunctionSetup(uchar data[8])
|
||||
boot_page_erase(flash_address.word);
|
||||
sei();
|
||||
}
|
||||
uart_puts("\n\r");
|
||||
uart_puts("\n\rWrite Flash");
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -406,9 +414,10 @@ void leave_bootloader(void)
|
||||
* disconnect usb
|
||||
*/
|
||||
usbDeviceDisconnect();
|
||||
#if 0
|
||||
for (uint8_t i = 0; i < 50; i++)
|
||||
_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
|
||||
*/
|
||||
@@ -421,6 +430,13 @@ 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)
|
||||
{
|
||||
@@ -441,32 +457,40 @@ int __attribute__ ((noreturn, OS_main)) main(void)
|
||||
uint16_t delay = 0;
|
||||
timeout = TIMEOUT;
|
||||
|
||||
uart_puts("Snesram Bootloader v0.1\n\r");
|
||||
DDRC &= ~(1 << AVR_BTLDR_EN_PIN);
|
||||
PORTC &= ~(1 << AVR_BTLDR_EN_PIN);
|
||||
|
||||
/*
|
||||
* if watchdog reset, disable watchdog and jump to app
|
||||
*/
|
||||
if (reset & _BV(WDRF)) {
|
||||
uart_puts("Found watchdog reset\n\r");
|
||||
MCUSR = 0;
|
||||
wdt_disable();
|
||||
uart_puts("Jump to 0x0000\n\r");
|
||||
jump_to_app();
|
||||
}
|
||||
|
||||
#ifdef AVR_BTLDR_SWITCH ENABLE
|
||||
if ((AVR_BTLDR_EN_IN & ( 1 << AVR_BTLDR_EN_PIN)) == 0){
|
||||
banner();
|
||||
uart_puts("Bootloader flashing is disabled\n\r");
|
||||
MCUSR = 0;
|
||||
leave_bootloader();
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* if power-on reset, quit bootloader via watchdog reset
|
||||
*/
|
||||
if (reset & _BV(PORF)) {
|
||||
banner();
|
||||
uart_puts("Found power on reset\n\r");
|
||||
MCUSR = 0;
|
||||
leave_bootloader();
|
||||
}
|
||||
/*
|
||||
* if watchdog reset, disable watchdog and jump to app
|
||||
*/
|
||||
else if (reset & _BV(WDRF)) {
|
||||
uart_puts("Found watchdog reset\n\r");
|
||||
MCUSR = 0;
|
||||
wdt_disable();
|
||||
DLED_TGL;
|
||||
_delay_ms(500);
|
||||
DLED_TGL;
|
||||
_delay_ms(500);
|
||||
uart_puts("Jump to main\n\r");
|
||||
jump_to_app();
|
||||
}
|
||||
|
||||
|
||||
banner();
|
||||
uart_puts("Enter programming mode\n\r");
|
||||
/*
|
||||
* else: enter programming mode
|
||||
|
||||
@@ -19,22 +19,31 @@
|
||||
DEBUG = 1
|
||||
TTY = /dev/tty.PL2303-00002126
|
||||
DEVICE = atmega644
|
||||
F_CPU = 20000000 # in Hz
|
||||
F_CPU = 20000000
|
||||
TARGET = main
|
||||
AVRDUDE = avrdude -c usbasp -p $(DEVICE)
|
||||
SIZE = avr-size
|
||||
|
||||
BOOT_ROM01 = ../../roms/qd16boot01.smc
|
||||
BOOT_ROM02 = ../../roms/qd16boot02.smc
|
||||
CONVERT_RLE = ../../scripts/conv_rle.py
|
||||
CONVERT_ZIP = ../../scripts/conv_zip.py
|
||||
|
||||
|
||||
|
||||
ifeq ($(DEBUG),1)
|
||||
LDFLAGS = -Wl,-u,vfprintf -lprintf_flt
|
||||
CFLAGS = -Iusbdrv -I. -DDEBUG_LEVEL=0
|
||||
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 huffman-decode.o rle.c loader.o info.o shared_memory.o
|
||||
LDFLAGS =-Wl,-u,vfprintf
|
||||
CFLAGS =-Iusbdrv -I. -DDEBUG_LEVEL=0
|
||||
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 info.o shared_memory.o \
|
||||
system.o pwm.o util.o shell.o irq.o command.o testing.o inflate.o neginf/neginf.o
|
||||
else
|
||||
LDFLAGS = -Wl,-u
|
||||
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 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
|
||||
LDFLAGS =-Wl,-u
|
||||
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 \
|
||||
sram.o crc.o debug.o dump.o rle.c loader.o \
|
||||
system.o util.o info.o shared_memory.o command.o irq.o \
|
||||
pwm.o inflate.o neginf/neginf.o
|
||||
endif
|
||||
|
||||
COMPILE = avr-gcc -Wall -Os -DF_CPU=$(F_CPU) $(CFLAGS) -mmcu=$(DEVICE)
|
||||
@@ -57,11 +66,8 @@ help:
|
||||
@echo "make clean ..... to delete objects and hex file"
|
||||
|
||||
hex: main.hex
|
||||
@echo "==============================="
|
||||
@echo "$(TARGET) compiled for: $(DEVICE)"
|
||||
@echo -n "size is: "
|
||||
@$(SIZE) -A $(TARGET).hex | grep "\.sec1" | tr -s " " | cut -d" " -f2
|
||||
@echo "==============================="
|
||||
@./checksize $(TARGET).elf
|
||||
|
||||
program: flash fuse
|
||||
|
||||
@@ -74,6 +80,11 @@ fuse:
|
||||
flash: main.hex
|
||||
$(AVRDUDE) -U flash:w:main.hex:i
|
||||
|
||||
loader01:
|
||||
python $(CONVERT_RLE) $(BOOT_ROM01)
|
||||
|
||||
loader02:
|
||||
python $(CONVERT_ZIP) $(BOOT_ROM02)
|
||||
|
||||
.c.o:
|
||||
$(COMPILE) -c $< -o $@
|
||||
@@ -103,4 +114,4 @@ cpp:
|
||||
$(COMPILE) -E main.c
|
||||
|
||||
clean:
|
||||
rm -f main.hex main.lst main.obj main.cof main.list main.map main.eep.hex main.elf *.o usbdrv/*.o main.s usbdrv/oddebug.s usbdrv/usbdrv.s
|
||||
rm -f main.hex main.lst main.obj main.cof main.list main.map main.eep.hex main.elf *.o usbdrv/*.o main.s usbdrv/oddebug.s usbdrv/usbdrv.s neginf/*.o
|
||||
|
||||
19
avr/usbload/Makefile.test
Normal file
19
avr/usbload/Makefile.test
Normal file
@@ -0,0 +1,19 @@
|
||||
|
||||
MD5=md5
|
||||
|
||||
all:
|
||||
gcc -c loader_test.c
|
||||
gcc -c inflate.c
|
||||
gcc -c neginf/neginf.c
|
||||
gcc -c inflate_test.c
|
||||
gcc -c ringbuffer.c
|
||||
gcc -o inflate_test inflate.o neginf.o inflate_test.o loader_test.o ringbuffer.o
|
||||
loader:
|
||||
python ../../scripts/conv_zip_test.py ../../roms/qd16boot02_half.smc
|
||||
|
||||
test:
|
||||
./inflate_test
|
||||
@$(MD5) out.smc
|
||||
@$(MD5) out_ref.smc
|
||||
@$(MD5) ../../roms/qd16boot02_half.smc
|
||||
|
||||
6
avr/usbload/checksize
Normal file → Executable file
6
avr/usbload/checksize
Normal file → Executable file
@@ -5,11 +5,11 @@
|
||||
# Creation Date: 2004-12-29
|
||||
# Tabsize: 4
|
||||
# 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
|
||||
codelimit=16384 # default value
|
||||
datalimit=992 # default value; leave 32 bytes for stack
|
||||
codelimit=61440 # default value
|
||||
datalimit=4064 # default value; leave 32 bytes for stack
|
||||
|
||||
if [ $# -gt 1 ]; then
|
||||
codelimit="$2"
|
||||
|
||||
120
avr/usbload/command.c
Normal file
120
avr/usbload/command.c
Normal file
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
* =====================================================================================
|
||||
*
|
||||
* ________ .__ __ ________ ____ ________
|
||||
* \_____ \ __ __|__| ____ | | __\______ \ _______ _/_ |/ _____/
|
||||
* / / \ \| | \ |/ ___\| |/ / | | \_/ __ \ \/ /| / __ \
|
||||
* / \_/. \ | / \ \___| < | ` \ ___/\ / | \ |__\ \
|
||||
* \_____\ \_/____/|__|\___ >__|_ \/_______ /\___ >\_/ |___|\_____ /
|
||||
* \__> \/ \/ \/ \/ \/
|
||||
*
|
||||
* www.optixx.org
|
||||
*
|
||||
*
|
||||
* Version: 1.0
|
||||
* Created: 07/21/2009 03:32:16 PM
|
||||
* Author: david@optixx.org
|
||||
*
|
||||
* =====================================================================================
|
||||
*/
|
||||
|
||||
#include <avr/io.h>
|
||||
#include <avr/interrupt.h>
|
||||
#include <util/delay.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "requests.h"
|
||||
#include "sram.h"
|
||||
#include "info.h"
|
||||
#include "irq.h"
|
||||
#include "usbdrv.h"
|
||||
#include "rle.h"
|
||||
#include "loader.h"
|
||||
#include "system.h"
|
||||
|
||||
#include "neginf/neginf.h"
|
||||
#include "inflate.h"
|
||||
|
||||
|
||||
extern usb_transaction_t usb_trans;
|
||||
extern system_t system;
|
||||
|
||||
extern const char *_rom[];
|
||||
extern const char _rom01[];
|
||||
extern const int _rom_size[];
|
||||
|
||||
void usb_connect()
|
||||
{
|
||||
uint8_t i = 0;
|
||||
info_P(PSTR("USB init\n"));
|
||||
usbDeviceDisconnect(); /* enforce re-enumeration, do this while */
|
||||
cli();
|
||||
info_P(PSTR("USB disconnect\n"));
|
||||
i = 10;
|
||||
while (--i) { /* fake USB disconnect for > 250 ms */
|
||||
_delay_ms(50);
|
||||
}
|
||||
led_on();
|
||||
usbDeviceConnect();
|
||||
info_P(PSTR("USB connect\n"));
|
||||
}
|
||||
|
||||
|
||||
|
||||
void boot_startup_rom(uint16_t init_delay)
|
||||
{
|
||||
uint8_t i;
|
||||
uint8_t c;
|
||||
uint16_t j;
|
||||
uint32_t addr = 0x000000;
|
||||
PGM_VOID_P p_addr;
|
||||
|
||||
info_P(PSTR("Fetch loader rom\n"));
|
||||
|
||||
system_set_bus_avr();
|
||||
snes_irq_lo();
|
||||
system_snes_irq_off();
|
||||
system_set_rom_lorom();
|
||||
|
||||
|
||||
inflate_init();
|
||||
for (i=0; i<ROM_BUFFER_CNT; i++){
|
||||
p_addr = _rom[i];
|
||||
printf("idx: %i %lx\n",i,p_addr);
|
||||
for (j=0; j<_rom_size[i]; j++){
|
||||
//rle_decode(_rom[i], _rom_size[i], addr);
|
||||
c = pgm_read_byte((PGM_VOID_P)p_addr++);
|
||||
printf("%02x ",c);
|
||||
neginf_process_byte(c);
|
||||
|
||||
}
|
||||
}
|
||||
info_P(PSTR("\n"));
|
||||
|
||||
#if DO_CRC_CHECK_LOADER
|
||||
dump_memory(0x010000 - 0x100, 0x010000);
|
||||
uint16_t crc;
|
||||
crc = crc_check_bulk_memory((uint32_t)0x000000,0x010000, 0x010000);
|
||||
info(PSTR("crc=%x\n"),crc);
|
||||
#endif
|
||||
|
||||
|
||||
snes_irq_lo();
|
||||
system_snes_irq_off();
|
||||
system_set_rom_hirom();
|
||||
system_set_wr_disable();
|
||||
system_set_bus_snes();
|
||||
|
||||
|
||||
system_send_snes_reset();
|
||||
_delay_ms(init_delay);
|
||||
}
|
||||
|
||||
void banner(){
|
||||
|
||||
}
|
||||
|
||||
void transaction_status(){
|
||||
}
|
||||
|
||||
31
avr/usbload/command.h
Normal file
31
avr/usbload/command.h
Normal file
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* =====================================================================================
|
||||
*
|
||||
* ________ .__ __ ________ ____ ________
|
||||
* \_____ \ __ __|__| ____ | | __\______ \ _______ _/_ |/ _____/
|
||||
* / / \ \| | \ |/ ___\| |/ / | | \_/ __ \ \/ /| / __ \
|
||||
* / \_/. \ | / \ \___| < | ` \ ___/\ / | \ |__\ \
|
||||
* \_____\ \_/____/|__|\___ >__|_ \/_______ /\___ >\_/ |___|\_____ /
|
||||
* \__> \/ \/ \/ \/ \/
|
||||
*
|
||||
* www.optixx.org
|
||||
*
|
||||
*
|
||||
* Version: 1.0
|
||||
* Created: 07/21/2009 03:32:16 PM
|
||||
* Author: david@optixx.org
|
||||
*
|
||||
* =====================================================================================
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __COMMAND_H__
|
||||
#define __COMMAND_H__
|
||||
|
||||
void usb_connect();
|
||||
void boot_startup_rom(uint16_t init_delay);
|
||||
void banner();
|
||||
void transaction_status();
|
||||
|
||||
|
||||
#endif
|
||||
@@ -29,6 +29,7 @@
|
||||
#define DEBUG_SRAM_RAW 16
|
||||
#define DEBUG_SREG 32
|
||||
#define DEBUG_CRC 64
|
||||
#define DEBUG_SHM 128
|
||||
|
||||
#define REQ_STATUS_IDLE 0x01
|
||||
#define REQ_STATUS_UPLOAD 0x02
|
||||
@@ -41,7 +42,16 @@
|
||||
#define USB_MAX_TRANS 0xff
|
||||
#define USB_CRC_CHECK 0x01
|
||||
|
||||
#define TRANSFER_BUFFER_SIZE 0x200
|
||||
#define TRANSFER_BUFFER_SIZE 0x000
|
||||
#define FORMAT_BUFFER_LEN 0x080
|
||||
#define RECEIVE_BUF_LEN 0x030
|
||||
#define HW_VERSION "2.6"
|
||||
#define SW_VERSION "1.0"
|
||||
|
||||
#define DO_CRC_CHECK_LOADER 0
|
||||
#define DO_CRC_CHECK 0
|
||||
#define DO_SHM_SCRATCHPAD 0
|
||||
#define DO_SHM 0
|
||||
#define DO_TIMER 0
|
||||
|
||||
#endif
|
||||
|
||||
@@ -71,10 +71,12 @@ uint16_t crc_check_bulk_memory(uint32_t bottom_addr, uint32_t top_addr, uint32_t
|
||||
uint32_t addr = 0;
|
||||
uint8_t req_bank = 0;
|
||||
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++) {
|
||||
if (addr && addr % bank_size == 0) {
|
||||
debug(DEBUG_CRC,"crc_check_bulk_memory: bank=0x%02x addr=0x%08lx crc=0x%04x\n",
|
||||
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"),
|
||||
req_bank,addr,crc);
|
||||
req_bank++;
|
||||
crc = 0;
|
||||
@@ -83,7 +85,7 @@ uint16_t crc_check_bulk_memory(uint32_t bottom_addr, uint32_t top_addr, uint32_t
|
||||
sram_bulk_read_next();
|
||||
}
|
||||
if (addr % 0x8000 == 0)
|
||||
debug(DEBUG_CRC,"crc_check_bulk_memory: bank=0x%02x addr=0x%08lx crc=0x%04x\n",
|
||||
debug_P(DEBUG_CRC, PSTR("crc_check_bulk_memory: bank=0x%02x addr=0x%08lx crc=0x%04x\n"),
|
||||
req_bank,addr,crc);
|
||||
sram_bulk_read_end();
|
||||
return crc;
|
||||
@@ -91,31 +93,13 @@ uint16_t crc_check_bulk_memory(uint32_t bottom_addr, uint32_t top_addr, uint32_t
|
||||
|
||||
|
||||
|
||||
void crc_check_memory(uint32_t bottom_addr,uint32_t top_addr,uint32_t bank_size,uint8_t *buffer)
|
||||
{
|
||||
uint16_t crc = 0;
|
||||
uint32_t addr;
|
||||
uint8_t req_bank = 0;
|
||||
for (addr = bottom_addr; addr < top_addr; addr += TRANSFER_BUFFER_SIZE) {
|
||||
if (addr && addr % bank_size == 0) {
|
||||
debug(DEBUG_CRC,"crc_check_memory: bank=0x%02x addr=0x%08lx crc=0x%04x\n",
|
||||
req_bank,addr,crc);
|
||||
req_bank++;
|
||||
crc = 0;
|
||||
}
|
||||
sram_read_buffer(addr, buffer, TRANSFER_BUFFER_SIZE);
|
||||
crc = do_crc_update(crc, buffer, TRANSFER_BUFFER_SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
uint16_t crc_check_memory_range(uint32_t start_addr, uint32_t size,uint8_t *buffer)
|
||||
{
|
||||
uint16_t crc = 0;
|
||||
uint32_t addr;
|
||||
for (addr = start_addr; addr < start_addr + size; addr += TRANSFER_BUFFER_SIZE) {
|
||||
sram_read_buffer(addr, buffer, TRANSFER_BUFFER_SIZE);
|
||||
sram_bulk_copy_into_buffer(addr, buffer, TRANSFER_BUFFER_SIZE);
|
||||
crc = do_crc_update(crc, buffer, TRANSFER_BUFFER_SIZE);
|
||||
}
|
||||
return crc;
|
||||
|
||||
@@ -29,7 +29,6 @@
|
||||
uint16_t crc_xmodem_update(uint16_t crc, uint8_t data);
|
||||
uint16_t do_crc(uint8_t * data,uint16_t size);
|
||||
uint16_t do_crc_update(uint16_t crc,uint8_t * data,uint16_t size);
|
||||
void crc_check_memory(uint32_t bottom_addr,uint32_t top_addr,uint32_t bank_size,uint8_t *buffer);
|
||||
uint16_t crc_check_memory_range(uint32_t start_addr, uint32_t size,uint8_t *buffer);
|
||||
uint16_t crc_check_bulk_memory(uint32_t bottom_addr, uint32_t bank_size,uint32_t top_addr);
|
||||
|
||||
|
||||
@@ -20,30 +20,35 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <avr/pgmspace.h>
|
||||
|
||||
#include "debug.h"
|
||||
#include "uart.h"
|
||||
|
||||
|
||||
#include "config.h"
|
||||
|
||||
extern FILE uart_stdout;
|
||||
|
||||
extern int debug_level; /* the higher, the more messages... */
|
||||
|
||||
|
||||
#ifndef NO_INFO
|
||||
uint8_t buffer_debug[FORMAT_BUFFER_LEN];
|
||||
#endif
|
||||
|
||||
#if defined(NO_DEBUG) && defined(__GNUC__)
|
||||
#else
|
||||
void debug(int level, char* format, ...) {
|
||||
void debug_P(int level, PGM_P format, ...) {
|
||||
#ifdef NO_DEBUG
|
||||
|
||||
#else
|
||||
va_list args;
|
||||
if (!(debug_level & level))
|
||||
return;
|
||||
strlcpy_P((char*)buffer_debug,format,FORMAT_BUFFER_LEN);
|
||||
va_start(args, format);
|
||||
vprintf(format, args);
|
||||
vprintf((char*)buffer_debug, args);
|
||||
va_end(args);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include <avr/pgmspace.h>
|
||||
|
||||
#if defined(NO_DEBUG) && defined(__GNUC__)
|
||||
/* gcc's cpp has extensions; it allows for macros with a variable number of
|
||||
@@ -39,5 +39,17 @@ void debug(int level, char *format, ...);
|
||||
#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 */
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include "info.h"
|
||||
#include "uart.h"
|
||||
#include "sram.h"
|
||||
#include "dump.h"
|
||||
|
||||
|
||||
extern FILE uart_stdout;
|
||||
@@ -47,21 +48,21 @@ void dump_packet(uint32_t addr, uint32_t len, uint8_t * packet)
|
||||
continue;
|
||||
}
|
||||
if (clear) {
|
||||
info("*\n");
|
||||
info_P(PSTR("*\n"));
|
||||
clear = 0;
|
||||
}
|
||||
info("%08lx:", addr + i);
|
||||
info_P(PSTR("%08lx:"), addr + i);
|
||||
for (j = 0; j < 16; j++) {
|
||||
info(" %02x", packet[i + j]);
|
||||
info_P(PSTR(" %02x"), packet[i + j]);
|
||||
}
|
||||
info(" |");
|
||||
info_P(PSTR(" |"));
|
||||
for (j = 0; j < 16; j++) {
|
||||
if (packet[i + j] >= 33 && packet[i + j] <= 126)
|
||||
info("%c", packet[i + j]);
|
||||
info_P(PSTR("%c"), packet[i + j]);
|
||||
else
|
||||
info(".");
|
||||
info_P(PSTR("."));
|
||||
}
|
||||
info("|\n");
|
||||
info_P(PSTR("|\n"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -72,11 +73,11 @@ void dump_memory(uint32_t bottom_addr, uint32_t top_addr)
|
||||
sram_bulk_read_start(bottom_addr);
|
||||
for ( addr = bottom_addr; addr < top_addr; addr++) {
|
||||
if (addr%0x10 == 0)
|
||||
info("\n%08lx:", addr);
|
||||
info_P(PSTR("\n%08lx:"), addr);
|
||||
byte = sram_bulk_read();
|
||||
sram_bulk_read_next();
|
||||
info(" %02x", byte);
|
||||
info_P(PSTR(" %02x"), byte);
|
||||
}
|
||||
info("\n");
|
||||
info_P(PSTR("\n"));
|
||||
sram_bulk_read_end();
|
||||
}
|
||||
|
||||
@@ -31,4 +31,4 @@ void dump_memory(uint32_t bottom_addr, uint32_t top_addr);
|
||||
void dump_packet(uint32_t addr,uint32_t len,uint8_t *packet);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
@@ -1,267 +0,0 @@
|
||||
/*
|
||||
* =====================================================================================
|
||||
*
|
||||
* ________ .__ __ ________ ____ ________
|
||||
* \_____ \ __ __|__| ____ | | __\______ \ _______ _/_ |/ _____/
|
||||
* / / \ \| | \ |/ ___\| |/ / | | \_/ __ \ \/ /| / __ \
|
||||
* / \_/. \ | / \ \___| < | ` \ ___/\ / | \ |__\ \
|
||||
* \_____\ \_/____/|__|\___ >__|_ \/_______ /\___ >\_/ |___|\_____ /
|
||||
* \__> \/ \/ \/ \/ \/
|
||||
*
|
||||
* www.optixx.org
|
||||
*
|
||||
*
|
||||
* Version: 1.0
|
||||
* Created: 07/21/2009 03:32:16 PM
|
||||
*
|
||||
* =====================================================================================
|
||||
*/
|
||||
|
||||
|
||||
#include "huffman-decode.h"
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "info.h"
|
||||
#include "debug.h"
|
||||
|
||||
#ifdef DEBUG
|
||||
#undef DEBUG
|
||||
#endif
|
||||
|
||||
#define DEBUG 1
|
||||
|
||||
#if DEBUG
|
||||
#include <avr/pgmspace.h>
|
||||
#endif
|
||||
|
||||
#define V_NODE (-2)
|
||||
#define V_EOF (-1)
|
||||
|
||||
#define PREFIX_SIZE_B 32
|
||||
|
||||
#define ALLOC_ERROR {}
|
||||
|
||||
#undef BLOCK_ALLOC
|
||||
|
||||
typedef struct {
|
||||
int16_t value;
|
||||
void* left;
|
||||
void* right;
|
||||
} node_t;
|
||||
|
||||
#if HUFFMAN_USE_ADDR_16
|
||||
void huffman_dec_init(huffman_dec_ctx_t* ctx, uint16_t(*rb_func)(uint16_t)){
|
||||
#else
|
||||
void huffman_dec_init(huffman_dec_ctx_t* ctx, uint16_t(*rb_func)(uint32_t)){
|
||||
#endif
|
||||
ctx->tree = NULL;
|
||||
ctx->addr = 0;
|
||||
ctx->read_byte = rb_func;
|
||||
ctx->rbuffer_index = 8;
|
||||
}
|
||||
|
||||
#if HUFFMAN_USE_ADDR_16
|
||||
void huffman_dec_set_addr(huffman_dec_ctx_t* ctx, uint16_t addr){
|
||||
#else
|
||||
void huffman_dec_set_addr(huffman_dec_ctx_t* ctx, uint32_t addr){
|
||||
#endif
|
||||
ctx->addr = addr;
|
||||
}
|
||||
|
||||
static inline void prefix_increment(uint8_t* prefix){
|
||||
uint8_t i;
|
||||
for(i=0; i<PREFIX_SIZE_B; ++i){
|
||||
prefix[i] += 1;
|
||||
if(prefix[i]!=0)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void prefix_shiftleft(uint8_t* prefix){
|
||||
uint8_t i;
|
||||
uint8_t c[2]={0,0};
|
||||
uint8_t ci=0;
|
||||
for(i=0; i<PREFIX_SIZE_B; ++i){
|
||||
c[ci] = (prefix[i])>>7;
|
||||
prefix[i]<<=1;
|
||||
ci ^= 1;
|
||||
prefix[i]|=c[ci];
|
||||
}
|
||||
}
|
||||
|
||||
static inline void set_last_to_eof(node_t* start){
|
||||
node_t* current = start;
|
||||
while(current->value==V_NODE){
|
||||
current=current->right;
|
||||
}
|
||||
current->value=V_EOF;
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
void print_tree(node_t* node){
|
||||
if(node->value==V_NODE){
|
||||
info("\n%p --> node->left=%p node->right=%p",node,node->left, node->right);
|
||||
print_tree(node->left);
|
||||
print_tree(node->right);
|
||||
}else{
|
||||
info("\n%p => %i",node,node->value);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
uint8_t build_tree(huffman_dec_ctx_t* ctx){
|
||||
uint16_t treesize;
|
||||
uint16_t treeindex=1;
|
||||
int8_t i,t;
|
||||
if(ctx->read_byte(ctx->addr++)!=0xC0)
|
||||
return 1;
|
||||
if(((treesize=ctx->read_byte(ctx->addr++))&0xFE)!=0xDE)
|
||||
return 1;
|
||||
treesize = (treesize&1)<<8;
|
||||
treesize += ctx->read_byte(ctx->addr++);
|
||||
if(treesize>0x1ff)
|
||||
return 2;
|
||||
#if BLOCK_ALLOC
|
||||
ctx->tree = malloc((2*treesize-1) * sizeof(node_t));
|
||||
#else
|
||||
ctx->tree = malloc(sizeof(node_t));
|
||||
#endif
|
||||
((node_t*)(ctx->tree))->value = V_NODE;
|
||||
uint16_t depth=0;
|
||||
uint16_t count=0;
|
||||
uint16_t v;
|
||||
uint8_t prefix[PREFIX_SIZE_B];
|
||||
uint8_t cdepth=0;
|
||||
node_t* current=ctx->tree;
|
||||
current->value = V_NODE;
|
||||
memset(prefix, 0, PREFIX_SIZE_B);
|
||||
do{
|
||||
while(count==0){
|
||||
depth++;
|
||||
count= ctx->read_byte(ctx->addr++);
|
||||
if(count==255)
|
||||
count += ctx->read_byte(ctx->addr++);
|
||||
}
|
||||
v = ctx->read_byte(ctx->addr++);
|
||||
if(v>0xff)
|
||||
return 3;
|
||||
--count;
|
||||
for(;cdepth<depth;++cdepth){
|
||||
prefix_shiftleft(prefix);
|
||||
}
|
||||
#if DEBUG
|
||||
printf("\n value %x => ",v);
|
||||
#endif
|
||||
current=ctx->tree;
|
||||
for(i=depth-1; i>=0; --i){
|
||||
t=(prefix[i/8])&(1<<(i%8));
|
||||
if(t==0){
|
||||
#if DEBUG
|
||||
printf("0");
|
||||
#endif
|
||||
if(current->left==NULL){
|
||||
#if BLOCK_ALLOC
|
||||
current->left=&(((node_t*)(ctx->tree))[treeindex++]);
|
||||
#else
|
||||
current->left=malloc(sizeof(node_t));
|
||||
#endif
|
||||
((node_t*)(current->left))->value = V_NODE;
|
||||
}
|
||||
current = current->left;
|
||||
} else {
|
||||
#if DEBUG
|
||||
printf("1");
|
||||
#endif
|
||||
if(current->right==NULL){
|
||||
#if BLOCK_ALLOC
|
||||
current->right=&(((node_t*)(ctx->tree))[treeindex++]);
|
||||
#else
|
||||
current->right=malloc( sizeof(node_t));
|
||||
#endif
|
||||
((node_t*)(current->right))->value=V_NODE;
|
||||
}
|
||||
current = current->right;
|
||||
}
|
||||
}
|
||||
#if !BLOCK_ALLOC
|
||||
if(current==NULL)
|
||||
ALLOC_ERROR
|
||||
#endif
|
||||
current->value=v;
|
||||
prefix_increment(prefix);
|
||||
}while(!(prefix[depth/8]&(1<<(depth%8))));
|
||||
#if DEBUG
|
||||
print_tree(ctx->tree);
|
||||
#endif
|
||||
set_last_to_eof(ctx->tree);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void free_tree(node_t* node){
|
||||
#if !BLOCK_ALLOC
|
||||
if(node->value==V_NODE){
|
||||
free_tree(node->left);
|
||||
free_tree(node->right);
|
||||
}
|
||||
#endif
|
||||
free(node);
|
||||
|
||||
}
|
||||
|
||||
static uint8_t read_bit(huffman_dec_ctx_t* ctx){
|
||||
uint16_t x;
|
||||
uint8_t t;
|
||||
if(ctx->rbuffer_index==8){
|
||||
x=ctx->read_byte(ctx->addr);
|
||||
ctx->addr++;
|
||||
if(t>0xff)
|
||||
return 0xFF;
|
||||
ctx->rbuffer = (uint8_t)x;
|
||||
ctx->rbuffer_index=0;
|
||||
}
|
||||
t=(ctx->rbuffer)>>7;
|
||||
ctx->rbuffer<<=1;
|
||||
ctx->rbuffer_index++;
|
||||
return t;
|
||||
}
|
||||
|
||||
uint16_t huffman_dec_byte(huffman_dec_ctx_t* ctx){
|
||||
node_t* current=ctx->tree;
|
||||
uint8_t t;
|
||||
if(current==NULL){
|
||||
#if DEBUG
|
||||
printf("\nbuild tree");
|
||||
#endif
|
||||
t=build_tree(ctx);
|
||||
if(t!=0){
|
||||
#if DEBUG
|
||||
printf("\n!!! building tree failed !!!\r\n");
|
||||
#endif
|
||||
return 0xFFFF;
|
||||
}
|
||||
#if DEBUG
|
||||
printf("\ntree build successful");
|
||||
#endif
|
||||
current=ctx->tree;
|
||||
}
|
||||
while(current->value==V_NODE){
|
||||
t=read_bit(ctx);
|
||||
if(t==0xFF)
|
||||
goto eof_detected;
|
||||
if(t==0){
|
||||
current=current->left;
|
||||
} else {
|
||||
current=current->right;
|
||||
}
|
||||
}
|
||||
if(current->value!=V_EOF){
|
||||
return current->value;
|
||||
}
|
||||
eof_detected:
|
||||
free_tree(ctx->tree);
|
||||
ctx->tree = NULL;
|
||||
return 0xFFFF;
|
||||
}
|
||||
85
avr/usbload/inflate.c
Normal file
85
avr/usbload/inflate.c
Normal file
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* =====================================================================================
|
||||
*
|
||||
* ________ .__ __ ________ ____ ________
|
||||
* \_____ \ __ __|__| ____ | | __\______ \ _______ _/_ |/ _____/
|
||||
* / / \ \| | \ |/ ___\| |/ / | | \_/ __ \ \/ /| / __ \
|
||||
* / \_/. \ | / \ \___| < | ` \ ___/\ / | \ |__\ \
|
||||
* \_____\ \_/____/|__|\___ >__|_ \/_______ /\___ >\_/ |___|\_____ /
|
||||
* \__> \/ \/ \/ \/ \/
|
||||
*
|
||||
* www.optixx.org
|
||||
*
|
||||
*
|
||||
* Version: 1.0
|
||||
* Created: 09/22/2009
|
||||
* Author: jannis@harderweb.de
|
||||
*
|
||||
* =====================================================================================
|
||||
*/
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "neginf/neginf.h"
|
||||
#include "inflate.h"
|
||||
#include "assert.h"
|
||||
#include "ringbuffer.h"
|
||||
|
||||
char inflate_done = 0;
|
||||
char *mem_ref;
|
||||
|
||||
int addr_ref = 0;
|
||||
|
||||
int cnt_hit = 0;
|
||||
int cnt = 0;
|
||||
|
||||
|
||||
void inflate_init()
|
||||
{
|
||||
neginf_init(0);
|
||||
mem_ref = (char*)malloc(2<<15);
|
||||
addr_ref = 0;
|
||||
rb_init();
|
||||
}
|
||||
|
||||
void inflate_flush()
|
||||
{
|
||||
|
||||
rb_flush();
|
||||
FILE *file;
|
||||
printf("write out_ref.smc\n");
|
||||
file = fopen("out_ref.smc","w");
|
||||
fwrite(mem_ref,2<<15,1,file);
|
||||
fclose(file);
|
||||
printf("cnt=%i cnt_hit=%i\n",cnt,cnt_hit);
|
||||
}
|
||||
|
||||
void neginf_cb_completed()
|
||||
{
|
||||
inflate_done = 1;
|
||||
}
|
||||
|
||||
void neginf_cb_seq_byte(nbyte byte)
|
||||
{
|
||||
mem_ref[addr_ref++] = byte;
|
||||
rb_put(byte);
|
||||
}
|
||||
|
||||
void neginf_cb_copy(nsize from, nsize to, nint length)
|
||||
{
|
||||
int i;
|
||||
cnt++;
|
||||
if ((to - from) < ( 1024 * 2 ) ){
|
||||
cnt_hit++;
|
||||
}
|
||||
printf("neginf_cb_copy from=0x%06x to=0x%06x dist=%i len=%i\n",(int)from, (int)to, (int)(to - from), (int)length);
|
||||
for (i=0; i<length;i++){
|
||||
mem_ref[to+i] = mem_ref[from+i];
|
||||
}
|
||||
addr_ref = to + length;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
28
avr/usbload/inflate.h
Normal file
28
avr/usbload/inflate.h
Normal file
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* =====================================================================================
|
||||
*
|
||||
* ________ .__ __ ________ ____ ________
|
||||
* \_____ \ __ __|__| ____ | | __\______ \ _______ _/_ |/ _____/
|
||||
* / / \ \| | \ |/ ___\| |/ / | | \_/ __ \ \/ /| / __ \
|
||||
* / \_/. \ | / \ \___| < | ` \ ___/\ / | \ |__\ \
|
||||
* \_____\ \_/____/|__|\___ >__|_ \/_______ /\___ >\_/ |___|\_____ /
|
||||
* \__> \/ \/ \/ \/ \/
|
||||
*
|
||||
* www.optixx.org
|
||||
*
|
||||
*
|
||||
* Version: 1.0
|
||||
* Created: 09/22/2009
|
||||
* Author: jannis@harderweb.de
|
||||
*
|
||||
* =====================================================================================
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#ifndef __INFLATE_H__
|
||||
#define __INFLATE_H__
|
||||
|
||||
extern char inflate_done;
|
||||
|
||||
#endif
|
||||
44
avr/usbload/inflate_test.c
Normal file
44
avr/usbload/inflate_test.c
Normal file
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* =====================================================================================
|
||||
*
|
||||
* ________ .__ __ ________ ____ ________
|
||||
* \_____ \ __ __|__| ____ | | __\______ \ _______ _/_ |/ _____/
|
||||
* / / \ \| | \ |/ ___\| |/ / | | \_/ __ \ \/ /| / __ \
|
||||
* / \_/. \ | / \ \___| < | ` \ ___/\ / | \ |__\ \
|
||||
* \_____\ \_/____/|__|\___ >__|_ \/_______ /\___ >\_/ |___|\_____ /
|
||||
* \__> \/ \/ \/ \/ \/
|
||||
*
|
||||
* www.optixx.org
|
||||
*
|
||||
*
|
||||
* Version: 1.0
|
||||
* Created: 07/21/2009 03:32:16 PM
|
||||
* Author: david@optixx.org
|
||||
*
|
||||
* =====================================================================================
|
||||
*/
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "neginf/neginf.h"
|
||||
#include "inflate.h"
|
||||
#include "loader_test.h"
|
||||
|
||||
extern const char _rom[];
|
||||
extern char inflate_done;
|
||||
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
|
||||
int j;
|
||||
char c;
|
||||
inflate_init();
|
||||
for (j=0; j< ROM_ZIP_SIZE; j++){
|
||||
neginf_process_byte(_rom[j]);
|
||||
}
|
||||
while(!inflate_done)
|
||||
neginf_process_byte(0x00);
|
||||
inflate_flush();
|
||||
return 0;
|
||||
}
|
||||
@@ -20,30 +20,37 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <avr/pgmspace.h>
|
||||
|
||||
#include "info.h"
|
||||
#include "uart.h"
|
||||
#include "config.h"
|
||||
|
||||
|
||||
|
||||
|
||||
extern FILE uart_stdout;
|
||||
|
||||
|
||||
#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(char* format, ...) {
|
||||
void info_P(PGM_P format, ...) {
|
||||
#ifdef NO_INFO
|
||||
|
||||
#else
|
||||
strlcpy_P((char*)buffer_info,format,FORMAT_BUFFER_LEN);
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
vprintf(format, args);
|
||||
vprintf((char*)buffer_info, args);
|
||||
va_end(args);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include <avr/pgmspace.h>
|
||||
|
||||
#if defined(NO_INFO) && defined(__GNUC__)
|
||||
/* gcc's cpp has extensions; it allows for macros with a variable number of
|
||||
@@ -39,4 +39,15 @@ void info(char *format, ...);
|
||||
#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
|
||||
|
||||
76
avr/usbload/irq.c
Normal file
76
avr/usbload/irq.c
Normal file
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* =====================================================================================
|
||||
*
|
||||
* ________ .__ __ ________ ____ ________
|
||||
* \_____ \ __ __|__| ____ | | __\______ \ _______ _/_ |/ _____/
|
||||
* / / \ \| | \ |/ ___\| |/ / | | \_/ __ \ \/ /| / __ \
|
||||
* / \_/. \ | / \ \___| < | ` \ ___/\ / | \ |__\ \
|
||||
* \_____\ \_/____/|__|\___ >__|_ \/_______ /\___ >\_/ |___|\_____ /
|
||||
* \__> \/ \/ \/ \/ \/
|
||||
*
|
||||
* 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"
|
||||
#include "system.h"
|
||||
|
||||
extern system_t system;
|
||||
|
||||
void (*jump_to_app) (void) = 0x0000;
|
||||
|
||||
void irq_init(){
|
||||
cli();
|
||||
PCMSK3 |=(1<<PCINT27);
|
||||
PCICR |= (1<<PCIE3);
|
||||
sei();
|
||||
system.reset_irq = RESET_IRQ_ON;
|
||||
}
|
||||
|
||||
void irq_stop(){
|
||||
cli();
|
||||
PCMSK3 &=~(1<<PCINT27);
|
||||
sei();
|
||||
system.reset_irq = RESET_IRQ_OFF;
|
||||
}
|
||||
|
||||
void leave_application(void)
|
||||
{
|
||||
cli();
|
||||
usbDeviceDisconnect();
|
||||
system.avr_reset_count++;
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,39 +13,16 @@
|
||||
*
|
||||
* Version: 1.0
|
||||
* Created: 07/21/2009 03:32:16 PM
|
||||
* Author: david@optixx.org
|
||||
*
|
||||
* =====================================================================================
|
||||
*/
|
||||
|
||||
#ifndef AVR_HUFFMAN_DECODE_H_
|
||||
#define AVR_HUFFMAN_DECODE_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#ifndef __IRQ_H__
|
||||
#define __IRQ_H__
|
||||
|
||||
#define HUFFMAN_USE_ADDR_16 1
|
||||
|
||||
typedef struct {
|
||||
void* tree;
|
||||
uint8_t rbuffer;
|
||||
uint8_t rbuffer_index;
|
||||
#if HUFFMAN_USE_ADDR_16
|
||||
uint16_t(*read_byte)(uint16_t addr);
|
||||
uint16_t addr;
|
||||
#else
|
||||
uint16_t(*read_byte)(uint32_t addr);
|
||||
uint32_t addr;
|
||||
void irq_init();
|
||||
void irq_stop();
|
||||
void leave_application(void);
|
||||
#endif
|
||||
} huffman_dec_ctx_t;
|
||||
|
||||
#if HUFFMAN_USE_ADDR_16
|
||||
void huffman_dec_init(huffman_dec_ctx_t* ctx, uint16_t(*rb_func)(uint16_t));
|
||||
void huffman_dec_set_addr(huffman_dec_ctx_t* ctx,uint16_t addr);
|
||||
#else
|
||||
void huffman_dec_init(huffman_dec_ctx_t* ctx, uint16_t(*rb_func)(uint32_t));
|
||||
void huffman_dec_set_addr(huffman_dec_ctx_t* ctx,uint32_t addr);
|
||||
#endif
|
||||
|
||||
|
||||
uint16_t huffman_dec_byte(huffman_dec_ctx_t* ctx);
|
||||
|
||||
#endif /* AVR_HUFFMAN_DECODE_H_ */
|
||||
3823
avr/usbload/loader.c
3823
avr/usbload/loader.c
File diff suppressed because it is too large
Load Diff
@@ -1,9 +1,14 @@
|
||||
|
||||
/*
|
||||
File: qd16boot02.smc
|
||||
Time: Sat, 24 Oct 2009 19:05:36
|
||||
*/
|
||||
#ifndef __FIFO_H__
|
||||
#define __FIFO_H__
|
||||
|
||||
#define ROM_BUFFER_SIZE 27288
|
||||
#define ROM_HUFFMAN_SIZE 27288
|
||||
#define ROM_RLE_SIZE 30344
|
||||
#define ROM_ZIP_SIZE 33654
|
||||
#define ROM_BUFFER_CNT 2
|
||||
|
||||
#define ROM_BUFFER_SIZE01 32767
|
||||
#define ROM_BUFFER_SIZE02 887
|
||||
|
||||
#endif
|
||||
|
||||
2229
avr/usbload/loader_test.c
Normal file
2229
avr/usbload/loader_test.c
Normal file
File diff suppressed because it is too large
Load Diff
7
avr/usbload/loader_test.h
Normal file
7
avr/usbload/loader_test.h
Normal file
@@ -0,0 +1,7 @@
|
||||
|
||||
#ifndef __FIFO_H__
|
||||
#define __FIFO_H__
|
||||
|
||||
#define ROM_ZIP_SIZE 35543
|
||||
|
||||
#endif
|
||||
@@ -21,17 +21,17 @@
|
||||
|
||||
|
||||
#include <avr/io.h>
|
||||
#include <avr/interrupt.h> /* for sei() */
|
||||
#include <util/delay.h> /* for _delay_ms() */
|
||||
#include <avr/interrupt.h>
|
||||
#include <util/delay.h>
|
||||
#include <stdlib.h>
|
||||
#include <avr/pgmspace.h> /* required by usbdrv.h */
|
||||
#include <avr/eeprom.h>
|
||||
#include <avr/pgmspace.h>
|
||||
#include <avr/eeprom.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "usbdrv.h"
|
||||
#include "oddebug.h" /* This is also an example for using debug
|
||||
* macros */
|
||||
#include "oddebug.h"
|
||||
#include "config.h"
|
||||
#include "requests.h" /* The custom request numbers we use */
|
||||
#include "requests.h"
|
||||
#include "uart.h"
|
||||
#include "sram.h"
|
||||
#include "debug.h"
|
||||
@@ -41,549 +41,284 @@
|
||||
#include "usb_bulk.h"
|
||||
#include "timer.h"
|
||||
#include "watchdog.h"
|
||||
#include "huffman-decode.h"
|
||||
#include "rle.h"
|
||||
#include "loader.h"
|
||||
#include "command.h"
|
||||
#include "shared_memory.h"
|
||||
#include "irq.h"
|
||||
#include "pwm.h"
|
||||
#include "testing.h"
|
||||
#include "shell.h"
|
||||
#include "system.h"
|
||||
|
||||
|
||||
extern const char _rom[] PROGMEM;
|
||||
#ifndef NO_DEBUG
|
||||
extern FILE uart_stdout;
|
||||
#endif
|
||||
extern system_t system;
|
||||
|
||||
uint8_t debug_level = ( DEBUG | DEBUG_USB | DEBUG_CRC );
|
||||
|
||||
uint8_t read_buffer[TRANSFER_BUFFER_SIZE];
|
||||
uint32_t req_addr = 0;
|
||||
uint32_t req_addr_end = 0;
|
||||
uint32_t req_size;
|
||||
uint8_t req_bank;
|
||||
uint32_t req_bank_size;
|
||||
uint16_t req_bank_cnt;
|
||||
uint8_t req_state = REQ_STATUS_IDLE;
|
||||
uint8_t rx_remaining = 0;
|
||||
uint8_t tx_remaining = 0;
|
||||
uint16_t sync_errors = 0;
|
||||
uint8_t tx_buffer[32];
|
||||
uint8_t data_buffer[4];
|
||||
uint32_t addr;
|
||||
uint16_t crc = 0;
|
||||
|
||||
uint8_t debug_level = (DEBUG | DEBUG_CRC);
|
||||
|
||||
|
||||
usb_transaction_t usb_trans;
|
||||
|
||||
usbMsgLen_t usbFunctionSetup(uchar data[8])
|
||||
{
|
||||
|
||||
usbRequest_t *rq = (void *) data;
|
||||
uint8_t ret_len = 0;
|
||||
/*
|
||||
* -------------------------------------------------------------------------
|
||||
*/
|
||||
if (rq->bRequest == USB_UPLOAD_INIT) {
|
||||
|
||||
if (req_state != REQ_STATUS_IDLE){
|
||||
debug(DEBUG_USB,"USB_UPLOAD_INIT: ERROR state is not REQ_STATUS_IDLE\n");
|
||||
return 0;
|
||||
}
|
||||
if (rq->bRequest == USB_BULK_UPLOAD_INIT) {
|
||||
|
||||
req_bank = 0;
|
||||
rx_remaining = 0;
|
||||
req_bank_size = (uint32_t)1 << rq->wValue.word;
|
||||
sync_errors = 0;
|
||||
crc = 0;
|
||||
debug(DEBUG_USB,"USB_UPLOAD_INIT: bank_size=0x%08lx\n", req_bank_size);
|
||||
usb_trans.req_bank = 0;
|
||||
usb_trans.rx_remaining = 0;
|
||||
debug_P(DEBUG_USB, PSTR("USB_BULK_UPLOAD_INIT: %i %i\n"), rq->wValue.word,
|
||||
rq->wIndex.word);
|
||||
usb_trans.req_bank_size = (uint32_t) (1L << rq->wValue.word);
|
||||
usb_trans.req_bank_cnt = rq->wIndex.word;
|
||||
usb_trans.req_addr_end = (uint32_t) usb_trans.req_bank_size * usb_trans.req_bank_cnt;
|
||||
usb_trans.req_percent = 0;
|
||||
usb_trans.req_percent_last = 0;
|
||||
usb_trans.sync_errors = 0;
|
||||
debug_P(DEBUG_USB,
|
||||
PSTR("USB_BULK_UPLOAD_INIT: bank_size=0x%08lx bank_cnt=0x%x end_addr=0x%08lx\n"),
|
||||
usb_trans.req_bank_size, usb_trans.req_bank_cnt, usb_trans.req_addr_end);
|
||||
|
||||
/*
|
||||
* -------------------------------------------------------------------------
|
||||
*/
|
||||
} else if (rq->bRequest == USB_UPLOAD_ADDR) {
|
||||
|
||||
req_state = REQ_STATUS_UPLOAD;
|
||||
req_addr = rq->wValue.word;
|
||||
req_addr = req_addr << 16;
|
||||
req_addr = req_addr | rq->wIndex.word;
|
||||
if (rx_remaining) {
|
||||
sync_errors++;
|
||||
debug
|
||||
(DEBUG_USB,"USB_UPLOAD_ADDR: Out of sync addr=0x%lx remain=%i packet=%i sync_error=%i\n",
|
||||
req_addr, rx_remaining, rq->wLength.word, sync_errors);
|
||||
ret_len = 0;
|
||||
}
|
||||
rx_remaining = rq->wLength.word;
|
||||
ret_len = USB_MAX_TRANS;
|
||||
|
||||
|
||||
if (req_addr && (req_addr % 0x1000) == 0) {
|
||||
debug(DEBUG_USB,"USB_UPLOAD_ADDR: bank=0x%02x addr=0x%08lx crc=%04x\n",
|
||||
req_bank, req_addr,crc_check_bulk_memory(req_addr - 0x1000,req_addr,req_bank_size));
|
||||
|
||||
}
|
||||
if (req_addr && req_addr % req_bank_size == 0) {
|
||||
debug(DEBUG_USB,"USB_UPLOAD_ADDR: req_bank=0x%02x addr=0x%08lx\n",
|
||||
req_bank, req_addr);
|
||||
|
||||
req_bank++;
|
||||
//shared_memory_put(SHARED_MEM_CMD_UPLOAD_PROGESS,req_bank);
|
||||
}
|
||||
ret_len = USB_MAX_TRANS;
|
||||
/*
|
||||
* -------------------------------------------------------------------------
|
||||
*/
|
||||
} else if (rq->bRequest == USB_DOWNLOAD_INIT) {
|
||||
debug(DEBUG_USB,"USB_DOWNLOAD_INIT\n");
|
||||
|
||||
/*
|
||||
* -------------------------------------------------------------------------
|
||||
*/
|
||||
} else if (rq->bRequest == USB_DOWNLOAD_ADDR) {
|
||||
debug(DEBUG_USB,"USB_DOWNLOAD_ADDR\n");
|
||||
/*
|
||||
* -------------------------------------------------------------------------
|
||||
*/
|
||||
} else if (rq->bRequest == USB_BULK_UPLOAD_INIT) {
|
||||
|
||||
req_bank = 0;
|
||||
rx_remaining = 0;
|
||||
debug(DEBUG_USB,"USB_BULK_UPLOAD_INIT: %i %i\n",rq->wValue.word, rq->wIndex.word);
|
||||
req_bank_size = (uint32_t)(1L << rq->wValue.word);
|
||||
req_bank_cnt = rq->wIndex.word;
|
||||
req_addr_end = (uint32_t)req_bank_size * req_bank_cnt;
|
||||
|
||||
sync_errors = 0;
|
||||
debug(DEBUG_USB,"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);
|
||||
|
||||
shared_memory_put(SHARED_MEM_CMD_BANK_COUNT,req_bank_cnt);
|
||||
if (req_addr == 0x000000){
|
||||
shared_memory_write(SHARED_MEM_TX_CMD_UPLOAD_START, 0);
|
||||
shared_memory_write(SHARED_MEM_TX_CMD_BANK_COUNT, usb_trans.req_bank_cnt);
|
||||
#if DO_TIMER
|
||||
if (usb_trans.req_addr == 0x000000) {
|
||||
#ifndef NO_DEBUG
|
||||
timer_start();
|
||||
#endif
|
||||
}
|
||||
/*
|
||||
* -------------------------------------------------------------------------
|
||||
*/
|
||||
#endif
|
||||
/*
|
||||
* -------------------------------------------------------------------------
|
||||
*/
|
||||
} else if (rq->bRequest == USB_BULK_UPLOAD_ADDR) {
|
||||
|
||||
req_state = REQ_STATUS_BULK_UPLOAD;
|
||||
req_addr = rq->wValue.word;
|
||||
req_addr = req_addr << 16;
|
||||
req_addr = req_addr | rq->wIndex.word;
|
||||
rx_remaining = rq->wLength.word;
|
||||
|
||||
if (req_addr && req_addr % req_bank_size == 0) {
|
||||
#ifdef FLT_DEBUG
|
||||
debug(DEBUG_USB,"USB_BULK_UPLOAD_ADDR: req_bank=0x%02x addr=0x%08lx time=%.4f\n",
|
||||
req_bank, req_addr,timer_stop());
|
||||
#else
|
||||
debug(DEBUG_USB,"USB_BULK_UPLOAD_ADDR: req_bank=0x%02x addr=0x%08lx time=%i\n",
|
||||
req_bank, req_addr,timer_stop_int());
|
||||
#endif
|
||||
req_bank++;
|
||||
shared_memory_put(SHARED_MEM_CMD_UPLOAD_PROGESS,req_bank);
|
||||
sram_bulk_write_start(req_addr);
|
||||
timer_start();
|
||||
|
||||
} else {
|
||||
sram_bulk_write_start(req_addr);
|
||||
}
|
||||
ret_len = USB_MAX_TRANS;
|
||||
|
||||
/*
|
||||
* -------------------------------------------------------------------------
|
||||
*/
|
||||
} else if (rq->bRequest == USB_BULK_UPLOAD_NEXT) {
|
||||
usb_trans.req_state = REQ_STATUS_BULK_UPLOAD;
|
||||
usb_trans.req_addr = rq->wValue.word;
|
||||
usb_trans.req_addr = usb_trans.req_addr << 16;
|
||||
usb_trans.req_addr = usb_trans.req_addr | rq->wIndex.word;
|
||||
usb_trans.rx_remaining = rq->wLength.word;
|
||||
|
||||
req_state = REQ_STATUS_BULK_UPLOAD;
|
||||
req_addr = rq->wValue.word;
|
||||
req_addr = req_addr << 16;
|
||||
req_addr = req_addr | rq->wIndex.word;
|
||||
rx_remaining = rq->wLength.word;
|
||||
#if 0
|
||||
if (req_addr && (req_addr % 0x1000) == 0) {
|
||||
debug(DEBUG_USB,"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_addr,req_bank_size));
|
||||
|
||||
}
|
||||
sram_bulk_write_start(req_addr);
|
||||
|
||||
if (usb_trans.req_addr && usb_trans.req_addr % usb_trans.req_bank_size == 0) {
|
||||
#if DO_TIMER
|
||||
#ifndef NO_DEBUG
|
||||
#ifdef FLT_DEBUG
|
||||
debug_P(DEBUG_USB,
|
||||
PSTR("USB_BULK_UPLOAD_ADDR: req_bank=0x%02x addr=0x%08lx time=%.4f\n"),
|
||||
usb_trans.req_bank, usb_trans.req_addr, timer_stop());
|
||||
#else
|
||||
debug_P(DEBUG_USB,
|
||||
PSTR("USB_BULK_UPLOAD_ADDR: req_bank=0x%02x addr=0x%08lx time=%i\n"),
|
||||
usb_trans.req_bank, usb_trans.req_addr, timer_stop_int());
|
||||
#endif
|
||||
if (req_addr && ( req_addr % req_bank_size) == 0) {
|
||||
#ifdef FLT_DEBUG
|
||||
debug(DEBUG_USB,"USB_BULK_UPLOAD_NEXT: req_bank=0x%02x addr=0x%08lx time=%.4f\n",
|
||||
req_bank, req_addr,timer_stop());
|
||||
#else
|
||||
debug(DEBUG_USB,"USB_BULK_UPLOAD_NEXT: req_bank=0x%02x addr=0x%08lx time=%i\n",
|
||||
req_bank, req_addr,timer_stop_int());
|
||||
#endif
|
||||
req_bank++;
|
||||
timer_start();
|
||||
shared_memory_put(SHARED_MEM_CMD_BANK_CURRENT,req_bank);
|
||||
sram_bulk_write_start(req_addr);
|
||||
|
||||
timer_start();
|
||||
#endif
|
||||
#endif
|
||||
usb_trans.req_bank++;
|
||||
|
||||
} else {
|
||||
sram_bulk_write_start(usb_trans.req_addr);
|
||||
}
|
||||
ret_len = USB_MAX_TRANS;
|
||||
/*
|
||||
* -------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/*
|
||||
* -------------------------------------------------------------------------
|
||||
*/
|
||||
} else if (rq->bRequest == USB_BULK_UPLOAD_NEXT) {
|
||||
usb_trans.req_state = REQ_STATUS_BULK_UPLOAD;
|
||||
usb_trans.req_addr = rq->wValue.word;
|
||||
usb_trans.req_addr = usb_trans.req_addr << 16;
|
||||
usb_trans.req_addr = usb_trans.req_addr | rq->wIndex.word;
|
||||
usb_trans.rx_remaining = rq->wLength.word;
|
||||
|
||||
#if DO_SHM
|
||||
usb_trans.req_percent = (uint32_t)( 100 * usb_trans.req_addr ) / usb_trans.req_addr_end;
|
||||
if (usb_trans.req_percent!=usb_trans.req_percent_last){
|
||||
shared_memory_write(SHARED_MEM_TX_CMD_UPLOAD_PROGESS, usb_trans.req_percent);
|
||||
}
|
||||
usb_trans.req_percent_last = usb_trans.req_percent;
|
||||
shared_memory_scratchpad_region_save_helper(usb_trans.req_addr);
|
||||
#endif
|
||||
if (usb_trans.req_addr && (usb_trans.req_addr % usb_trans.req_bank_size) == 0) {
|
||||
#if DO_TIMER
|
||||
#ifndef NO_DEBUG
|
||||
#ifdef FLT_DEBUG
|
||||
debug_P(DEBUG_USB,
|
||||
PSTR("USB_BULK_UPLOAD_NEXT: req_bank=0x%02x addr=0x%08lx time=%.4f\n"),
|
||||
usb_trans.req_bank, usb_trans.req_addr, timer_stop());
|
||||
#else
|
||||
debug_P(DEBUG_USB,
|
||||
PSTR("USB_BULK_UPLOAD_NEXT: req_bank=0x%02x addr=0x%08lx time=%i\n"),
|
||||
usb_trans.req_bank, usb_trans.req_addr, timer_stop_int());
|
||||
#endif
|
||||
timer_start();
|
||||
#endif
|
||||
#endif
|
||||
usb_trans.req_bank++;
|
||||
#if DO_SHM
|
||||
shared_memory_write(SHARED_MEM_TX_CMD_BANK_CURRENT, usb_trans.req_bank);
|
||||
#endif
|
||||
}
|
||||
ret_len = USB_MAX_TRANS;
|
||||
/*
|
||||
* -------------------------------------------------------------------------
|
||||
*/
|
||||
} else if (rq->bRequest == USB_BULK_UPLOAD_END) {
|
||||
if (req_state != REQ_STATUS_BULK_UPLOAD){
|
||||
debug(DEBUG_USB,"USB_BULK_UPLOAD_END: ERROR state is not REQ_STATUS_BULK_UPLOAD\n");
|
||||
if (usb_trans.req_state != REQ_STATUS_BULK_UPLOAD) {
|
||||
debug_P(DEBUG_USB,
|
||||
PSTR("USB_BULK_UPLOAD_END: ERROR state is not REQ_STATUS_BULK_UPLOAD\n"));
|
||||
return 0;
|
||||
}
|
||||
debug(DEBUG_USB,"USB_BULK_UPLOAD_END:\n");
|
||||
req_state = REQ_STATUS_IDLE;
|
||||
debug_P(DEBUG_USB, PSTR("USB_BULK_UPLOAD_END:\n"));
|
||||
usb_trans.req_state = REQ_STATUS_IDLE;
|
||||
sram_bulk_write_end();
|
||||
shared_memory_put(SHARED_MEM_CMD_UPLOAD_END,0);
|
||||
#if DO_SHM
|
||||
shared_memory_write(SHARED_MEM_TX_CMD_UPLOAD_END, 0);
|
||||
#endif
|
||||
ret_len = 0;
|
||||
|
||||
/*
|
||||
* -------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/*
|
||||
* -------------------------------------------------------------------------
|
||||
*/
|
||||
} else if (rq->bRequest == USB_CRC) {
|
||||
req_addr = rq->wValue.word;
|
||||
req_addr = req_addr << 16;
|
||||
req_addr = req_addr | rq->wIndex.word;
|
||||
debug(DEBUG_USB,"USB_CRC: addr=0x%08lx \n", req_addr);
|
||||
crc_check_bulk_memory(0x000000, req_addr, req_bank_size);
|
||||
usb_trans.req_addr = rq->wValue.word;
|
||||
usb_trans.req_addr = usb_trans.req_addr << 16;
|
||||
usb_trans.req_addr = usb_trans.req_addr | rq->wIndex.word;
|
||||
debug_P(DEBUG_USB, PSTR("USB_CRC: addr=0x%08lx \n"), usb_trans.req_addr);
|
||||
crc_check_bulk_memory(0x000000, usb_trans.req_addr, usb_trans.req_bank_size);
|
||||
ret_len = 0;
|
||||
/*
|
||||
* -------------------------------------------------------------------------
|
||||
*/
|
||||
} else if (rq->bRequest == USB_MODE_SNES) {
|
||||
req_state = REQ_STATUS_SNES;
|
||||
debug(DEBUG_USB,"USB_MODE_SNES:\n");
|
||||
ret_len = 0;
|
||||
/*
|
||||
* -------------------------------------------------------------------------
|
||||
*/
|
||||
/*
|
||||
* -------------------------------------------------------------------------
|
||||
*/
|
||||
} else if (rq->bRequest == USB_MODE_AVR) {
|
||||
req_state = REQ_STATUS_AVR;
|
||||
debug(DEBUG_USB,"USB_MODE_AVR:\n");
|
||||
usb_trans.req_state = REQ_STATUS_AVR;
|
||||
debug_P(DEBUG_USB, PSTR("USB_MODE_AVR:\n"));
|
||||
ret_len = 0;
|
||||
/*
|
||||
* -------------------------------------------------------------------------
|
||||
*/
|
||||
/*
|
||||
* -------------------------------------------------------------------------
|
||||
*/
|
||||
} else if (rq->bRequest == USB_AVR_RESET) {
|
||||
debug(DEBUG_USB,"USB_AVR_RESET:\n");
|
||||
debug_P(DEBUG_USB, PSTR("USB_AVR_RESET:\n"));
|
||||
soft_reset();
|
||||
ret_len = 0;
|
||||
/*
|
||||
* -------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
} else if (rq->bRequest == USB_CRC_ADDR) {
|
||||
req_state = REQ_STATUS_CRC;
|
||||
req_addr = rq->wValue.word;
|
||||
req_addr = req_addr << 16;
|
||||
req_addr = req_addr | rq->wIndex.word;
|
||||
debug(DEBUG_USB,"USB_CRC_ADDR: addr=0x%lx size=%i\n", req_addr,
|
||||
rq->wLength.word);
|
||||
req_size = rq->wLength.word;
|
||||
req_size = req_size << 2;
|
||||
tx_remaining = 2;
|
||||
debug(DEBUG_USB,"USB_CRC_ADDR: addr=0x%lx size=%li\n", req_addr, req_size);
|
||||
|
||||
crc = crc_check_memory_range(req_addr, req_size, read_buffer);
|
||||
tx_buffer[0] = crc & 0xff;
|
||||
tx_buffer[1] = (crc >> 8) & 0xff;
|
||||
ret_len = 2;
|
||||
req_state = REQ_STATUS_IDLE;
|
||||
/*
|
||||
* -------------------------------------------------------------------------
|
||||
*/
|
||||
} else if (rq->bRequest == USB_SET_LAODER) {
|
||||
usb_trans.loader_enabled = rq->wValue.word;
|
||||
ret_len = 0;
|
||||
}
|
||||
|
||||
usbMsgPtr = data_buffer;
|
||||
return ret_len; /* default for not implemented requests: return
|
||||
* no data back to host */
|
||||
usbMsgPtr = usb_trans.rx_buffer;
|
||||
return ret_len;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* -------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
void test_read_write(){
|
||||
|
||||
void globals_init(){
|
||||
memset(&usb_trans,0,sizeof(usb_transaction_t));
|
||||
|
||||
uint8_t i;
|
||||
uint32_t addr;
|
||||
avr_bus_active();
|
||||
addr = 0x000000;
|
||||
i = 1;
|
||||
while (addr++ <= 0x0000ff){
|
||||
sram_write(addr,i++);
|
||||
}
|
||||
addr = 0x000000;
|
||||
while (addr++ <= 0x0000ff){
|
||||
info("read addr=0x%08lx %x\n",addr,sram_read(addr));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void test_bulk_read_write(){
|
||||
|
||||
uint8_t i;
|
||||
uint32_t addr;
|
||||
avr_bus_active();
|
||||
addr = 0x000000;
|
||||
i = 0;
|
||||
sram_bulk_write_start(addr);
|
||||
while (addr++ <= 0x8000){
|
||||
sram_bulk_write(i++);
|
||||
sram_bulk_write_next();
|
||||
}
|
||||
sram_bulk_write_end();
|
||||
|
||||
addr = 0x000000;
|
||||
sram_bulk_read_start(addr);
|
||||
while (addr <= 0x8000){
|
||||
info("addr=0x%08lx %x\n",addr,sram_bulk_read());
|
||||
sram_bulk_read_next();
|
||||
addr++;
|
||||
}
|
||||
sram_bulk_read_end();
|
||||
}
|
||||
|
||||
|
||||
void test_non_zero_memory(uint32_t bottom_addr,uint32_t top_addr)
|
||||
{
|
||||
uint32_t addr = 0;
|
||||
uint8_t c;
|
||||
sram_bulk_read_start(bottom_addr);
|
||||
for (addr = bottom_addr; addr < top_addr; addr++) {
|
||||
c = sram_bulk_read();
|
||||
if (c!=0xff)
|
||||
info("addr=0x%08lx c=0x%x\n",addr,c);
|
||||
sram_bulk_read_next();
|
||||
}
|
||||
sram_bulk_read_end();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void test_crc(){
|
||||
info("test_crc: clear\n");
|
||||
avr_bus_active();
|
||||
sram_bulk_set(0x000000,0x10000,0xff);
|
||||
info("test_crc: crc\n");
|
||||
crc_check_bulk_memory(0x000000,0x10000,0x8000);
|
||||
info("test_crc: check\n");
|
||||
test_non_zero_memory(0x000000,0x10000);
|
||||
}
|
||||
|
||||
uint16_t read_byte_pgm(uint16_t addr){
|
||||
return pgm_read_byte((PGM_VOID_P)addr);
|
||||
}
|
||||
|
||||
void decompress_huffman(PGM_VOID_P addr, uint16_t(*fp)(uint16_t)){
|
||||
uint16_t c;
|
||||
uint32_t i = 0;
|
||||
huffman_dec_ctx_t ctx;
|
||||
info("ok1\n");
|
||||
huffman_dec_init(&ctx, fp);
|
||||
info("ok2\n");
|
||||
huffman_dec_set_addr(&ctx, (uint16_t)addr);
|
||||
info("ok3\n");
|
||||
while(1){
|
||||
info("ok4\n");
|
||||
i++;
|
||||
c=huffman_dec_byte(&ctx);
|
||||
if (i%1024==0)
|
||||
info(".");
|
||||
if(c>0xff){
|
||||
return;
|
||||
}
|
||||
c&=0xff;
|
||||
sram_bulk_write(c);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void send_reset(){
|
||||
info("Reset Snes\n");
|
||||
snes_reset_on();
|
||||
snes_reset_lo();
|
||||
_delay_ms(2);
|
||||
snes_reset_hi();
|
||||
snes_reset_off();
|
||||
}
|
||||
|
||||
void send_irq(){
|
||||
snes_irq_on();
|
||||
snes_irq_lo();
|
||||
_delay_us(20);
|
||||
snes_irq_hi();
|
||||
snes_irq_off();
|
||||
}
|
||||
|
||||
void set_rom_mode(){
|
||||
if (req_bank_size == 0x8000){
|
||||
snes_lorom();
|
||||
info("Set Snes lowrom \n");
|
||||
} else {
|
||||
snes_hirom();
|
||||
info("Set Snes hirom \n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void usb_connect(){
|
||||
uint8_t i = 0;
|
||||
info("USB init\n");
|
||||
usbDeviceDisconnect(); /* enforce re-enumeration, do this while */
|
||||
cli();
|
||||
info("USB disconnect\n");
|
||||
i = 10;
|
||||
while (--i) { /* fake USB disconnect for > 250 ms */
|
||||
led_on();
|
||||
_delay_ms(35);
|
||||
led_off();
|
||||
_delay_ms(65);
|
||||
}
|
||||
led_on();
|
||||
usbDeviceConnect();
|
||||
info("USB connect\n");
|
||||
}
|
||||
|
||||
|
||||
void boot_startup_rom(){
|
||||
|
||||
|
||||
info("Activate AVR bus\n");
|
||||
avr_bus_active();
|
||||
|
||||
info("IRQ off\n");
|
||||
snes_irq_lo();
|
||||
snes_irq_off();
|
||||
|
||||
snes_lorom();
|
||||
info("Set Snes lowrom \n");
|
||||
|
||||
|
||||
info("Huffman decompress to 0x010000\n",(void*)_rom);
|
||||
sram_bulk_write_start(0x010000);
|
||||
decompress_huffman(&_rom,read_byte_pgm);
|
||||
sram_bulk_write_end();
|
||||
info("RLE decompress to 0x000000\n",(void*)_rom);
|
||||
rle_decode_sram(0x010000, ROM_RLE_SIZE, 0x000000);
|
||||
dump_memory(0x10000 - 0x100, 0x10000);
|
||||
|
||||
snes_reset_hi();
|
||||
snes_reset_off();
|
||||
snes_irq_lo();
|
||||
snes_irq_off();
|
||||
info("IRQ off\n");
|
||||
snes_hirom();
|
||||
snes_wr_disable();
|
||||
info("Disable snes WR\n");
|
||||
snes_bus_active();
|
||||
info("Activate Snes bus\n");
|
||||
_delay_ms(100);
|
||||
info("Reset Snes\n");
|
||||
send_reset();
|
||||
_delay_ms(100);
|
||||
#if 0
|
||||
uint8_t i = 0;
|
||||
i = 20;
|
||||
info("Wait");
|
||||
while (--i){
|
||||
_delay_ms(500);
|
||||
info(".");
|
||||
}
|
||||
info("\n");
|
||||
#endif
|
||||
usb_trans.req_addr = 0;
|
||||
usb_trans.req_addr_end = 0;
|
||||
usb_trans.req_state = REQ_STATUS_IDLE;
|
||||
usb_trans.rx_remaining = 0;
|
||||
usb_trans.tx_remaining = 0;
|
||||
usb_trans.sync_errors = 0;
|
||||
usb_trans.loader_enabled = 1;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
|
||||
#ifndef NO_DEBUG
|
||||
uart_init();
|
||||
stdout = &uart_stdout;
|
||||
|
||||
info("Sytem start\n");
|
||||
system_init();
|
||||
|
||||
#if 0
|
||||
test_read_write();
|
||||
test_bulk_read_write();
|
||||
test_crc();
|
||||
while(1);
|
||||
banner();
|
||||
#endif
|
||||
|
||||
info("Boot startup rom\n");
|
||||
boot_startup_rom();
|
||||
|
||||
shared_memory_init();
|
||||
system_init();
|
||||
sram_init();
|
||||
//pwm_init();
|
||||
irq_init();
|
||||
boot_startup_rom(50);
|
||||
globals_init();
|
||||
//pwm_stop();
|
||||
usbInit();
|
||||
usb_connect();
|
||||
|
||||
while (1){
|
||||
avr_bus_active();
|
||||
info("Activate AVR bus\n");
|
||||
info("IRQ off\n");
|
||||
snes_irq_lo();
|
||||
snes_irq_off();
|
||||
info("Set Snes lowrom\n");
|
||||
snes_lorom();
|
||||
info("Disable snes WR\n");
|
||||
snes_wr_disable();
|
||||
sei();
|
||||
info("USB poll\n");
|
||||
while (req_state != REQ_STATUS_SNES){
|
||||
sei();
|
||||
while (1) {
|
||||
|
||||
system_set_bus_avr();
|
||||
system_set_wr_disable();
|
||||
info_P(PSTR("USB poll\n"));
|
||||
while (usb_trans.req_state != REQ_STATUS_SNES) {
|
||||
usbPoll();
|
||||
#ifdef DO_SHELL
|
||||
#ifndef NO_DEBUG
|
||||
shell_run();
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
shared_memory_put(SHARED_MEM_CMD_TERMINATE,0);
|
||||
info("USB poll done\n");
|
||||
snes_reset_hi();
|
||||
snes_reset_off();
|
||||
snes_irq_lo();
|
||||
snes_irq_off();
|
||||
info("IRQ off\n");
|
||||
|
||||
#if DO_SHM
|
||||
shared_memory_write(SHARED_MEM_TX_CMD_TERMINATE, 0);
|
||||
#endif
|
||||
|
||||
#if DO_SHM_SCRATCHPAD
|
||||
shared_memory_scratchpad_region_tx_restore();
|
||||
shared_memory_scratchpad_region_rx_restore();
|
||||
#endif
|
||||
|
||||
#if DO_CRC_CHECK
|
||||
info_P(PSTR("-->CRC Check\n"));
|
||||
crc_check_bulk_memory(0x000000, usb_trans.req_bank_size * usb_trans.req_bank_cnt, usb_trans.req_bank_size);
|
||||
#endif
|
||||
|
||||
system_set_rom_mode(&usb_trans);
|
||||
system_set_wr_disable();
|
||||
system_set_bus_snes();
|
||||
system_send_snes_reset();
|
||||
irq_stop();
|
||||
/*
|
||||
info_P(PSTR("-->Switch TO SNES\n"));
|
||||
set_rom_mode();
|
||||
snes_wr_disable();
|
||||
info("Disable snes WR\n");
|
||||
snes_wr_disable();
|
||||
info_P(PSTR("Disable SNES WR\n"));
|
||||
snes_bus_active();
|
||||
info("Activate Snes bus\n");
|
||||
_delay_ms(100);
|
||||
info("Reset Snes\n");
|
||||
info_P(PSTR("Activate SNES bus\n"));
|
||||
irq_stop();
|
||||
send_reset();
|
||||
|
||||
info("Poll\n");
|
||||
while (req_state != REQ_STATUS_AVR){
|
||||
|
||||
*/
|
||||
info_P(PSTR("Poll USB\n"));
|
||||
while ((usb_trans.req_state != REQ_STATUS_AVR)) {
|
||||
usbPoll();
|
||||
#ifdef DO_SHELL
|
||||
#ifndef NO_DEBUG
|
||||
shell_run();
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef DO_IRQ
|
||||
uint8_t i;
|
||||
uint16_t irq_count = 0;
|
||||
i = 10;
|
||||
while (--i) {
|
||||
_delay_ms(100);
|
||||
}
|
||||
info("Send IRQ %i\n",++irq_count);
|
||||
send_irq();
|
||||
#endif
|
||||
|
||||
#ifdef DO_BUS_STEALING
|
||||
avr_bus_active();
|
||||
sram_bulk_read_start(0x003000);
|
||||
c = sram_bulk_read();
|
||||
i = 5;
|
||||
while (--i) {
|
||||
_delay_ms(500);
|
||||
info("Wait to switch to snes mode %i\n", i);
|
||||
}
|
||||
|
||||
if (req_bank_size == 0x8000){
|
||||
snes_lorom();
|
||||
info("Set Snes lowrom \n");
|
||||
} else {
|
||||
snes_hirom();
|
||||
info("Set Snes hirom \n");
|
||||
}
|
||||
snes_wr_disable();
|
||||
info("Disable snes WR\n");
|
||||
snes_bus_active();
|
||||
info("Activate Snes bus\n");
|
||||
info("Read 0x3000=%c\n",c);
|
||||
#endif
|
||||
}
|
||||
//info_P(PSTR("-->Switch TO AVR\n"));
|
||||
shared_memory_init();
|
||||
if(usb_trans.loader_enabled) {
|
||||
boot_startup_rom(500);
|
||||
} else {
|
||||
system_set_bus_avr();
|
||||
system_send_snes_reset();
|
||||
//avr_bus_active();
|
||||
//send_reset();
|
||||
|
||||
}
|
||||
irq_init();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
30
avr/usbload/memmory.txt
Normal file
30
avr/usbload/memmory.txt
Normal file
@@ -0,0 +1,30 @@
|
||||
|
||||
Loader Version 1
|
||||
|
||||
DEBUG:
|
||||
Bootloader: 4096
|
||||
CODE: 24984
|
||||
RAM: 742
|
||||
LOADER: 31091
|
||||
|
||||
NO_DEBUG:
|
||||
Bootloader: 4096
|
||||
CODE: 7532
|
||||
RAM: 344
|
||||
LOADER: 31091
|
||||
|
||||
|
||||
Loader Version 2
|
||||
|
||||
DEBUG:
|
||||
Bootloader: 4096
|
||||
CODE: 24984
|
||||
RAM: 742
|
||||
LOADER: 58046
|
||||
|
||||
NO_DEBUG:
|
||||
Bootloader: 4096
|
||||
CODE: 7532
|
||||
RAM: 344
|
||||
LOADER: 58046
|
||||
|
||||
466
avr/usbload/neginf/neginf.c
Normal file
466
avr/usbload/neginf/neginf.c
Normal file
@@ -0,0 +1,466 @@
|
||||
/*
|
||||
* neginf.c
|
||||
* neginf -- embedded inflate lib
|
||||
*
|
||||
* inflate routines
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "neginf.h"
|
||||
#include "neginf_priv.h"
|
||||
|
||||
typedef void(*mode_fun)() ;
|
||||
|
||||
static neginf_state state;
|
||||
static const mode_fun mode_tab[mode_count] = {
|
||||
&await_block,
|
||||
&raw_block_begin,
|
||||
&raw_block_begin2,
|
||||
&raw_block,
|
||||
&fixed_block_begin,
|
||||
&huff_block,
|
||||
&huff_len_addbits,
|
||||
&huff_dist,
|
||||
&huff_dist_addbits,
|
||||
&dynamic_block_begin,
|
||||
&dynamic_read_lc,
|
||||
&dynamic_read_lit_len,
|
||||
&dynamic_read_dist
|
||||
};
|
||||
|
||||
void neginf_init(nsize start_pos)
|
||||
{
|
||||
state.queue_size = 0;
|
||||
state.mode = mode_await_block;
|
||||
state.last_block = 0;
|
||||
#ifdef NEGINF_POS_TRACKING
|
||||
state.output_pos = start_pos;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void neginf_process_byte(nbyte byte)
|
||||
{
|
||||
assert(state.queue_size <= 16);
|
||||
state.input_queue |= (byte << state.queue_size);
|
||||
state.queue_size += 8;
|
||||
|
||||
while(state.queue_size >= 16)
|
||||
{
|
||||
//printf("qsize=%i mode=%i\n",state.queue_size,state.mode);
|
||||
mode_tab[state.mode]();
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef NEGINF_POS_TRACKING
|
||||
nsize neginf_output_position()
|
||||
{
|
||||
return state.output_pos;
|
||||
}
|
||||
#endif
|
||||
|
||||
nint lookahead()
|
||||
{
|
||||
//printf("lookahead\n");
|
||||
return state.input_queue;
|
||||
}
|
||||
|
||||
void consume(ntiny amount)
|
||||
{
|
||||
//printf("consume %i %i\n",state.queue_size,amount);
|
||||
assert(state.queue_size > amount);
|
||||
state.input_queue >>= amount;
|
||||
state.queue_size -= amount;
|
||||
}
|
||||
|
||||
void await_block()
|
||||
{
|
||||
//printf("wait block\n");
|
||||
if(state.last_block)
|
||||
{
|
||||
neginf_cb_completed();
|
||||
consume(16);
|
||||
}
|
||||
else
|
||||
{
|
||||
nint la = lookahead();
|
||||
state.last_block = la & 1;
|
||||
consume(3);
|
||||
switch(la & 6)
|
||||
{
|
||||
case 0: // 00 uncompressed
|
||||
consume((state.queue_size) & 7); // align to byte
|
||||
state.mode = mode_raw_block_begin;
|
||||
break;
|
||||
case 2: // 01 fixed huffman
|
||||
state.mode = mode_fixed_block_begin;
|
||||
break;
|
||||
case 4: // 10 dynamic huffman
|
||||
state.mode = mode_dynamic_block_begin;
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void raw_block_begin()
|
||||
{
|
||||
//printf("raw block begin\n");
|
||||
state.raw_size = lookahead() & 0xFFFF; // size of raw block
|
||||
consume(16);
|
||||
state.mode = mode_raw_block_begin2;
|
||||
}
|
||||
|
||||
void raw_block_begin2()
|
||||
{
|
||||
//printf("raw block begin2\n");
|
||||
consume(16); // we ignore the inverted size
|
||||
state.mode = mode_raw_block;
|
||||
}
|
||||
|
||||
void raw_block()
|
||||
{
|
||||
//printf("raw block\n");
|
||||
if(state.raw_size == 0)
|
||||
{
|
||||
state.mode = mode_await_block;
|
||||
}
|
||||
else
|
||||
{
|
||||
state.raw_size--;
|
||||
neginf_cb_seq_byte(lookahead() & 0xFF);
|
||||
#ifdef NEGINF_POS_TRACKING
|
||||
state.output_pos++;
|
||||
#endif
|
||||
consume(8);
|
||||
}
|
||||
}
|
||||
|
||||
void fixed_block_begin()
|
||||
{
|
||||
//printf("fixed block begin\n");
|
||||
|
||||
nint i = 0;
|
||||
for(; i < 144; i++)
|
||||
state.lit_len_lengths[i] = 8;
|
||||
for(; i < 256; i++)
|
||||
state.lit_len_lengths[i] = 9;
|
||||
for(; i < 280; i++)
|
||||
state.lit_len_lengths[i] = 7;
|
||||
for(; i < 288; i++)
|
||||
state.lit_len_lengths[i] = 8;
|
||||
|
||||
ntiny j;
|
||||
for(j = 0; i < 32; i++)
|
||||
state.dist_lengths[i] = 5;
|
||||
|
||||
compute_begins();
|
||||
state.mode = mode_huff_block;
|
||||
}
|
||||
|
||||
void huff_block()
|
||||
{
|
||||
//printf("huff block\n");
|
||||
nint code = lit_len_read();
|
||||
if(code == 256)
|
||||
{
|
||||
state.mode = mode_await_block;
|
||||
}
|
||||
else if(code < 256)
|
||||
{
|
||||
neginf_cb_seq_byte(code);
|
||||
#ifdef NEGINF_POS_TRACKING
|
||||
state.output_pos++;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
state.code = code;
|
||||
state.mode = mode_huff_len_addbits;
|
||||
}
|
||||
}
|
||||
|
||||
void huff_len_addbits()
|
||||
{
|
||||
//printf("huff len addbits\n");
|
||||
nint len;
|
||||
nint code = state.code;
|
||||
nint la = lookahead();
|
||||
if(code < 265)
|
||||
len = code - 257 + 3;
|
||||
else if(code < 269)
|
||||
{
|
||||
len = (code - 265) * 2 + 11 + (la & 1);
|
||||
consume(1);
|
||||
}
|
||||
else if(code < 273)
|
||||
{
|
||||
len = (code - 269) * 4 + 19 + (la & 3);
|
||||
consume(2);
|
||||
}
|
||||
else if(code < 277)
|
||||
{
|
||||
len = (code - 273) * 8 + 35 + (la & 7);
|
||||
consume(3);
|
||||
}
|
||||
else if(code < 281)
|
||||
{
|
||||
len = (code - 277) * 16 + 67 + (la & 15);
|
||||
consume(4);
|
||||
}
|
||||
else if(code < 285)
|
||||
{
|
||||
len = (code - 281) * 32 + 131 + (la & 31);
|
||||
consume(5);
|
||||
}
|
||||
else
|
||||
{
|
||||
len = 258;
|
||||
}
|
||||
state.match_len = len;
|
||||
state.mode = mode_huff_dist;
|
||||
}
|
||||
|
||||
void huff_dist()
|
||||
{
|
||||
//printf("huff dist\n");
|
||||
state.tcode = dist_read();
|
||||
state.mode = mode_huff_dist_addbits;
|
||||
}
|
||||
|
||||
void huff_dist_addbits()
|
||||
{
|
||||
//printf("huff addbits\n");
|
||||
nint dist;
|
||||
ntiny code = state.tcode;
|
||||
|
||||
if(code < 4)
|
||||
{
|
||||
dist = code+1;
|
||||
}
|
||||
else if(code > 29)
|
||||
{
|
||||
assert(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
nint la = lookahead();
|
||||
ntiny len = (code - 2) / 2;
|
||||
dist = ((2 + (code & 1)) << len) + 1 + (((1 << len) - 1) & la);
|
||||
consume(len);
|
||||
}
|
||||
neginf_cb_rel_copy(dist, state.match_len);
|
||||
#ifdef NEGINF_POS_TRACKING
|
||||
state.output_pos += state.match_len;
|
||||
#endif
|
||||
|
||||
state.mode = mode_huff_block;
|
||||
}
|
||||
|
||||
void dynamic_block_begin()
|
||||
{
|
||||
nint j;
|
||||
ntiny i;
|
||||
//printf("dynamic block begin\n");
|
||||
for(j = 0; j < 288; j++)
|
||||
state.lit_len_lengths[j] = 0;
|
||||
for(i = 0; i < 32; i++)
|
||||
state.dist_lengths[i] = 0;
|
||||
for(i = 0; i < 19; i++)
|
||||
state.hc_lengths[i] = 0;
|
||||
|
||||
nint la = lookahead();
|
||||
state.hlit = (la & 31) + 257;
|
||||
state.hdist = ((la >> 5) & 31) + 1;
|
||||
state.hclen = ((la >> 10) & 15) + 4;
|
||||
state.torder = 0;
|
||||
consume(5+5+4);
|
||||
state.mode = mode_dynamic_read_lc;
|
||||
}
|
||||
|
||||
void dynamic_read_lc()
|
||||
{
|
||||
//printf("dynamic read lc\n");
|
||||
if(state.hclen == 0)
|
||||
{
|
||||
compute_begin(state.hc_lengths, state.hc_begins, 19);
|
||||
state.mode = mode_dynamic_read_lit_len;
|
||||
state.order = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
static const ntiny order[19] = {
|
||||
16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15
|
||||
};
|
||||
ntiny i = lookahead() & 7;
|
||||
state.hc_lengths[order[state.torder]] = i;
|
||||
consume(3);
|
||||
|
||||
state.torder++;
|
||||
state.hclen--;
|
||||
}
|
||||
}
|
||||
|
||||
void dynamic_read_lit_len()
|
||||
{
|
||||
//printf("dynamic read lit len\n");
|
||||
if(state.hlit == 0)
|
||||
{
|
||||
state.mode = mode_dynamic_read_dist;
|
||||
state.order = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
state.hlit -= lc_read(state.lit_len_lengths);
|
||||
}
|
||||
}
|
||||
|
||||
void dynamic_read_dist()
|
||||
{
|
||||
//printf("dynamic read dist\n");
|
||||
if(state.hdist == 0)
|
||||
{
|
||||
compute_begins();
|
||||
state.mode = mode_huff_block;
|
||||
}
|
||||
else
|
||||
{
|
||||
state.hdist -= lc_read(state.dist_lengths);
|
||||
}
|
||||
}
|
||||
|
||||
ntiny lc_read(ntiny * lenghts)
|
||||
{
|
||||
//printf("read lc\n");
|
||||
ntiny code = huff_read(state.hc_lengths, state.hc_begins, 19);
|
||||
// this reads 7 bits max so we still have 9 bits left in the buffer
|
||||
if(code < 16)
|
||||
{
|
||||
lenghts[state.order] = code;
|
||||
state.order++;
|
||||
return 1;
|
||||
}
|
||||
else if(code == 16)
|
||||
{
|
||||
ntiny i;
|
||||
ntiny copy = (lookahead() & 3) + 3;
|
||||
consume(2);
|
||||
for(i = 0; i < copy; i++)
|
||||
lenghts[state.order + i] = lenghts[state.order - 1];
|
||||
state.order += copy;
|
||||
return copy;
|
||||
}
|
||||
else
|
||||
{
|
||||
ntiny fill;
|
||||
ntiny i;
|
||||
|
||||
if(code == 17)
|
||||
{
|
||||
fill = (lookahead() & 7) + 3;
|
||||
consume(3);
|
||||
}
|
||||
else
|
||||
{
|
||||
fill = (lookahead() & 127) + 11;
|
||||
consume(7);
|
||||
}
|
||||
for(i = 0; i < fill; i++)
|
||||
{
|
||||
lenghts[state.order] = 0;
|
||||
state.order++;
|
||||
}
|
||||
return fill;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void compute_begins()
|
||||
{
|
||||
//printf("compute begins\n");
|
||||
compute_begin(state.lit_len_lengths, state.lit_len_begins, 288);
|
||||
compute_begin(state.dist_lengths, state.dist_begins, 32);
|
||||
}
|
||||
|
||||
|
||||
void compute_begin(ntiny * lengths, nint * begins, nint size)
|
||||
{
|
||||
ntiny j;
|
||||
nint i;
|
||||
//printf("compute begin\n");
|
||||
for(j = 0; j < 14; j++)
|
||||
begins[j] = 0;
|
||||
for(i = 0; i < size; i++)
|
||||
{
|
||||
nint len = lengths[i];
|
||||
if(len != 0 && len != 15)
|
||||
begins[len-1] += 1 << (15 - len);
|
||||
}
|
||||
nint acc = 0;
|
||||
for(j = 0; j < 14; j++)
|
||||
{
|
||||
nint val = begins[j];
|
||||
acc += val;
|
||||
begins[j] = acc;
|
||||
}
|
||||
}
|
||||
|
||||
nint lit_len_read()
|
||||
{
|
||||
//printf("lit len read\n");
|
||||
|
||||
return huff_read(state.lit_len_lengths, state.lit_len_begins, 288);
|
||||
}
|
||||
|
||||
nint dist_read()
|
||||
{
|
||||
//printf("dist read\n");
|
||||
return huff_read(state.dist_lengths, state.dist_begins, 32);
|
||||
}
|
||||
|
||||
nint huff_read(ntiny * lenghts, nint * begins, nint size)
|
||||
{
|
||||
//printf("huff read\n");
|
||||
nint code = 0;
|
||||
ntiny i;
|
||||
for(i = 1; i < 16; i++)
|
||||
{
|
||||
|
||||
code |= (lookahead() & 1) << (15-i);
|
||||
consume(1);
|
||||
if(i == 15 || code < begins[i-1])
|
||||
break;
|
||||
}
|
||||
code -= begins[i-2];
|
||||
code >>= (15-i);
|
||||
nint j;
|
||||
for(j = 0; j < size; j++)
|
||||
{
|
||||
if(lenghts[j] == i)
|
||||
{
|
||||
if(code == 0)
|
||||
return j;
|
||||
code--;
|
||||
}
|
||||
}
|
||||
//assert(0);
|
||||
return 0; // silent warning
|
||||
}
|
||||
|
||||
#ifndef NEGINF_USE_SEQ_WRITES
|
||||
void neginf_cb_seq_byte(nbyte byte)
|
||||
{
|
||||
neginf_cb_byte(state.output_pos, byte);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef NEGINF_USE_REL_COPY
|
||||
void neginf_cb_rel_copy(nint distance, nint length)
|
||||
{
|
||||
neginf_cb_copy(state.output_pos - distance, state.output_pos, length);
|
||||
}
|
||||
#endif
|
||||
43
avr/usbload/neginf/neginf.h
Normal file
43
avr/usbload/neginf/neginf.h
Normal file
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* neginf.h
|
||||
* neginf -- embedded inflate lib
|
||||
*
|
||||
* public header file
|
||||
*/
|
||||
|
||||
#ifndef NEGINF_H
|
||||
#define NEGINF_H
|
||||
|
||||
#include "neginf_conf.h"
|
||||
|
||||
#if defined(NEGINF_USE_SEQ_WRITES) && defined(NEGINF_USE_REL_COPY)
|
||||
#else
|
||||
#ifndef NEGINF_POS_TRACKING
|
||||
#define NEGINF_POS_TRACKING
|
||||
#endif
|
||||
#endif
|
||||
|
||||
void neginf_init(nsize start_pos);
|
||||
void neginf_process_byte(nbyte byte);
|
||||
|
||||
#ifdef NEGINF_POS_TRACKING
|
||||
nsize neginf_output_position();
|
||||
#endif
|
||||
|
||||
// callbacks
|
||||
|
||||
#ifdef NEGINF_USE_SEQ_WRITES
|
||||
void neginf_cb_seq_byte(nbyte byte);
|
||||
#else
|
||||
void neginf_cb_byte(nsize pos, nbyte byte);
|
||||
#endif
|
||||
|
||||
#ifdef NEGINF_USE_REL_COPY
|
||||
void neginf_cb_rel_copy(nint distance, nint length);
|
||||
#else
|
||||
void neginf_cb_copy(nsize from, nsize to, nint length);
|
||||
#endif
|
||||
|
||||
void neginf_cb_completed();
|
||||
|
||||
#endif
|
||||
48
avr/usbload/neginf/neginf_conf.h
Normal file
48
avr/usbload/neginf/neginf_conf.h
Normal file
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* neginf_conf.h
|
||||
* neginf -- embedded inflate lib
|
||||
*
|
||||
* configuration header file
|
||||
*/
|
||||
|
||||
#ifndef NEGINF_CONF_H
|
||||
#define NEGINF_CONF_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
#define NEGINF_USE_SEQ_WRITES
|
||||
//#define NEGINF_USE_REL_COPY
|
||||
//#define NEGINF_POS_TRACKING
|
||||
|
||||
//#define NEGINF_8BIT
|
||||
#define NEGINF_PACKED_STATE
|
||||
|
||||
|
||||
#ifdef NEGINF_8BIT
|
||||
|
||||
typedef char nbool;
|
||||
typedef uint8_t nbyte;
|
||||
typedef uint8_t ntiny;
|
||||
typedef uint16_t nint;
|
||||
typedef uint32_t nbuf;
|
||||
|
||||
typedef uint32_t nsize;
|
||||
|
||||
#else
|
||||
|
||||
typedef int nbool; // boolean
|
||||
typedef uint8_t nbyte; // has to be exaclty 8 bit, unsigned
|
||||
typedef unsigned int ntiny; // has to be at least 8 bit, unsigned
|
||||
typedef unsigned int nint; // has to be at least 16 bit, unsigned
|
||||
typedef unsigned int nbuf; // has to be at least 24 bit, unsigned
|
||||
|
||||
|
||||
typedef size_t nsize; // has be at least 24 bit, unsigned
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
102
avr/usbload/neginf/neginf_priv.h
Normal file
102
avr/usbload/neginf/neginf_priv.h
Normal file
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* neginf_priv.h
|
||||
* neginf -- embedded inflate lib
|
||||
*
|
||||
* internal header file
|
||||
*/
|
||||
|
||||
#ifndef NEGINF_PRIV_H
|
||||
#define NEGINF_PRIV_H
|
||||
|
||||
typedef struct neginf_state_s neginf_state;
|
||||
struct neginf_state_s {
|
||||
ntiny queue_size; // 0 .. 24
|
||||
ntiny mode;
|
||||
nbool last_block;
|
||||
#ifdef NEGINF_POS_TRACKING
|
||||
nsize output_pos;
|
||||
#endif
|
||||
// can be left uninitialized
|
||||
nbuf input_queue; // three input bytes
|
||||
|
||||
ntiny raw_size;
|
||||
ntiny tcode;
|
||||
nint code;
|
||||
nint match_len;
|
||||
|
||||
nint order;
|
||||
ntiny torder;
|
||||
nint hlit;
|
||||
ntiny hdist;
|
||||
ntiny hclen;
|
||||
|
||||
ntiny lit_len_lengths[288];
|
||||
nint lit_len_begins[14];
|
||||
|
||||
ntiny dist_lengths[32];
|
||||
nint dist_begins[14];
|
||||
|
||||
ntiny hc_lengths[19];
|
||||
nint hc_begins[14];
|
||||
// what could be saved by limiting this to 7
|
||||
// will be lost due to the extra code i guess
|
||||
|
||||
|
||||
}
|
||||
#ifdef NEGINF_PACKED_STATE
|
||||
__attribute__((__packed__))
|
||||
#endif
|
||||
;
|
||||
|
||||
enum neginf_mode {
|
||||
mode_await_block = 0,
|
||||
mode_raw_block_begin,
|
||||
mode_raw_block_begin2,
|
||||
mode_raw_block,
|
||||
mode_fixed_block_begin,
|
||||
mode_huff_block,
|
||||
mode_huff_len_addbits,
|
||||
mode_huff_dist,
|
||||
mode_huff_dist_addbits,
|
||||
mode_dynamic_block_begin,
|
||||
mode_dynamic_read_lc,
|
||||
mode_dynamic_read_lit_len,
|
||||
mode_dynamic_read_dist,
|
||||
mode_count
|
||||
};
|
||||
|
||||
static void await_block();
|
||||
static void raw_block_begin();
|
||||
static void raw_block_begin2();
|
||||
static void raw_block();
|
||||
static void fixed_block_begin();
|
||||
static void huff_block();
|
||||
static void huff_len_addbits();
|
||||
static void huff_dist();
|
||||
static void huff_dist_addbits();
|
||||
static void dynamic_block_begin();
|
||||
static void dynamic_read_lc();
|
||||
static void dynamic_read_lit_len();
|
||||
static void dynamic_read_dist();
|
||||
|
||||
static void compute_begins();
|
||||
static void compute_begin(ntiny * lengths, nint * begins, nint size);
|
||||
static nint lit_len_read();
|
||||
static nint dist_read();
|
||||
static nint huff_read(ntiny * lengths, nint * begins, nint size);
|
||||
static ntiny lc_read(ntiny * lengths);
|
||||
|
||||
static nint lookahead();
|
||||
static void consume(ntiny amount);
|
||||
|
||||
#ifndef NEGINF_USE_SEQ_WRITES
|
||||
static void neginf_cb_seq_byte(nbyte byte);
|
||||
#endif
|
||||
|
||||
#ifndef NEGINF_USE_REL_COPY
|
||||
void neginf_cb_rel_copy(nint distance, nint length);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
104
avr/usbload/pwm.c
Normal file
104
avr/usbload/pwm.c
Normal file
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* =====================================================================================
|
||||
*
|
||||
* ________ .__ __ ________ ____ ________
|
||||
* \_____ \ __ __|__| ____ | | __\______ \ _______ _/_ |/ _____/
|
||||
* / / \ \| | \ |/ ___\| |/ / | | \_/ __ \ \/ /| / __ \
|
||||
* / \_/. \ | / \ \___| < | ` \ ___/\ / | \ |__\ \
|
||||
* \_____\ \_/____/|__|\___ >__|_ \/_______ /\___ >\_/ |___|\_____ /
|
||||
* \__> \/ \/ \/ \/ \/
|
||||
*
|
||||
* www.optixx.org
|
||||
*
|
||||
*
|
||||
* Version: 1.0
|
||||
* Created: 07/21/2009 03:32:16 PM
|
||||
* Author: david@optixx.org
|
||||
*
|
||||
* =====================================================================================
|
||||
*/
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <avr/io.h>
|
||||
#include <avr/interrupt.h>
|
||||
|
||||
#include "pwm.h"
|
||||
#include "debug.h"
|
||||
#include "info.h"
|
||||
#include "sram.h"
|
||||
|
||||
|
||||
#define PWM_SINE_MAX 64
|
||||
#define PWM_OVERFLOW_MAX 1024
|
||||
|
||||
#if 0
|
||||
|
||||
uint8_t pwm_sine_table[] = {
|
||||
0x7f,0x8b,0x97,0xa4,0xaf,0xbb,0xc5,0xcf,0xd9,0xe1,0xe8,0xef,0xf4,0xf8,0xfb,0xfd,
|
||||
0xfd,0xfd,0xfb,0xf8,0xf3,0xee,0xe7,0xe0,0xd7,0xce,0xc4,0xb9,0xae,0xa2,0x96,0x89,
|
||||
0x7e,0x71,0x65,0x59,0x4d,0x42,0x37,0x2d,0x24,0x1c,0x15,0x0f,0x09,0x05,0x03,0x01,
|
||||
0x01,0x01,0x03,0x07,0x0b,0x11,0x17,0x1f,0x28,0x31,0x3b,0x46,0x52,0x5e,0x6a,0x76
|
||||
};
|
||||
|
||||
volatile uint8_t pwm_setting;
|
||||
volatile uint16_t pwm_overflow;
|
||||
volatile uint8_t pwm_idx;
|
||||
volatile uint16_t pwm_overflow_max;
|
||||
|
||||
ISR(TIMER2_COMPA_vect) {
|
||||
static uint8_t pwm_cnt=0;
|
||||
OCR2A += (uint16_t)T_PWM;
|
||||
|
||||
if (pwm_setting> pwm_cnt)
|
||||
led_pwm_on();
|
||||
else
|
||||
led_pwm_off();
|
||||
|
||||
if (pwm_cnt==(uint8_t)(PWM_STEPS-1))
|
||||
pwm_cnt=0;
|
||||
else
|
||||
pwm_cnt++;
|
||||
if (pwm_overflow_max == pwm_overflow++ ){
|
||||
pwm_setting = pwm_sine_table[pwm_idx++];
|
||||
pwm_overflow = 0;
|
||||
if (PWM_SINE_MAX == pwm_idx)
|
||||
pwm_idx = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void pwm_speed(uint16_t val) {
|
||||
pwm_overflow_max = val;
|
||||
}
|
||||
|
||||
void pwm_speed_slow(uint16_t val) {
|
||||
pwm_overflow_max = PWM_OVERFLOW_MAX * 2 ;
|
||||
}
|
||||
|
||||
void pwm_speed_fast(uint16_t val) {
|
||||
pwm_overflow_max = PWM_OVERFLOW_MAX / 2;
|
||||
}
|
||||
|
||||
void pwm_speed_normal(uint16_t val) {
|
||||
pwm_overflow_max = PWM_OVERFLOW_MAX;
|
||||
}
|
||||
|
||||
|
||||
void pwm_set(uint8_t val) {
|
||||
pwm_setting = val;
|
||||
}
|
||||
|
||||
void pwm_stop(void) {
|
||||
while(pwm_setting!=0xfd);
|
||||
TIMSK2 = 0;
|
||||
}
|
||||
|
||||
void pwm_init(void) {
|
||||
pwm_overflow_max = PWM_OVERFLOW_MAX;
|
||||
pwm_setting = 0x7f;
|
||||
pwm_overflow = 0;
|
||||
//cli();
|
||||
TCCR2B = 1;
|
||||
TIMSK2 |= (1<<OCIE2A);
|
||||
sei();
|
||||
}
|
||||
#endif
|
||||
37
avr/usbload/pwm.h
Normal file
37
avr/usbload/pwm.h
Normal file
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* =====================================================================================
|
||||
*
|
||||
* ________ .__ __ ________ ____ ________
|
||||
* \_____ \ __ __|__| ____ | | __\______ \ _______ _/_ |/ _____/
|
||||
* / / \ \| | \ |/ ___\| |/ / | | \_/ __ \ \/ /| / __ \
|
||||
* / \_/. \ | / \ \___| < | ` \ ___/\ / | \ |__\ \
|
||||
* \_____\ \_/____/|__|\___ >__|_ \/_______ /\___ >\_/ |___|\_____ /
|
||||
* \__> \/ \/ \/ \/ \/
|
||||
*
|
||||
* www.optixx.org
|
||||
*
|
||||
*
|
||||
* Version: 1.0
|
||||
* Created: 07/21/2009 03:32:16 PM
|
||||
* Author: david@optixx.org
|
||||
*
|
||||
* =====================================================================================
|
||||
*/
|
||||
|
||||
#ifndef __PWM_H__
|
||||
#define __PWM_H__
|
||||
|
||||
#define F_PWM 100 // PWM-Frequenz in Hz
|
||||
#define PWM_STEPS 256 // PWM-Schritte pro Zyklus(1..256)
|
||||
|
||||
#define T_PWM (F_CPU/(F_PWM*PWM_STEPS)) // Systemtakte pro PWM-Takt
|
||||
|
||||
#if (T_PWM<(93+5))
|
||||
#error T_PWM zu klein, F_CPU muss vergrösst werden oder F_PWM oder PWM_STEPS verkleinert werden
|
||||
#endif
|
||||
|
||||
void pwm_init(void);
|
||||
void pwm_stop(void);
|
||||
|
||||
|
||||
#endif
|
||||
@@ -38,5 +38,23 @@
|
||||
#define USB_MODE_SNES 10
|
||||
#define USB_MODE_AVR 11
|
||||
#define USB_AVR_RESET 12
|
||||
#define USB_SET_LAODER 13
|
||||
|
||||
typedef struct usb_transaction_t {
|
||||
uint32_t req_addr;
|
||||
uint32_t req_addr_end;
|
||||
uint8_t req_bank;
|
||||
uint32_t req_bank_size;
|
||||
uint16_t req_bank_cnt;
|
||||
uint8_t req_percent;
|
||||
uint8_t req_percent_last;
|
||||
uint8_t req_state;
|
||||
uint8_t rx_remaining;
|
||||
uint8_t tx_remaining ;
|
||||
uint16_t sync_errors;
|
||||
uint8_t tx_buffer[32];
|
||||
uint8_t rx_buffer[8];
|
||||
uint8_t loader_enabled;
|
||||
} usb_transaction_t;
|
||||
|
||||
#endif /* __REQUESTS_H_INCLUDED__ */
|
||||
|
||||
126
avr/usbload/ringbuffer.c
Normal file
126
avr/usbload/ringbuffer.c
Normal file
@@ -0,0 +1,126 @@
|
||||
// AT90USB/ringbuffer.c
|
||||
// Simple Ring-Buffer (FIFO) for Elements of type char
|
||||
// S. Salewski, 19-MAR-2007
|
||||
|
||||
/*
|
||||
t-> o
|
||||
o <-w
|
||||
x
|
||||
x <-r
|
||||
b-> x
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#include "ringbuffer.h"
|
||||
#define memory_size 65536
|
||||
#define t &buf[ringbuffer_size - 1]
|
||||
#define b &buf[0]
|
||||
|
||||
char buf[ringbuffer_size];
|
||||
int rb_count;
|
||||
char *memory;
|
||||
int pos_mem;
|
||||
int pos_head;
|
||||
|
||||
|
||||
//char *t = &buf[ringbuffer_size - 1];
|
||||
//char *b = &buf[0];
|
||||
|
||||
char *r; // position from where we can read (if rb_count > 0)
|
||||
char *w; // next free position (if rb_count < ringbuffer_size))
|
||||
char *o; // output pointer
|
||||
|
||||
void rb_init()
|
||||
{
|
||||
r = b;
|
||||
w = b;
|
||||
o = b;
|
||||
rb_count = 0;
|
||||
memory = (char*)malloc(memory_size);
|
||||
pos_mem = 0;
|
||||
pos_head = 0;
|
||||
}
|
||||
|
||||
|
||||
void rb_dump()
|
||||
{
|
||||
int i;
|
||||
printf("b=0x%02x t=0x%02x w=0x%02x o=0x%02x\n",*b,*t,*w,*o);
|
||||
for (i=0; i<ringbuffer_size; i++)
|
||||
printf("%02i 0x%02x\n",i, buf[i]);
|
||||
|
||||
}
|
||||
void rb_flush(){
|
||||
FILE *file;
|
||||
while(!rb_isempty()){
|
||||
memory[pos_mem++] = rb_get();
|
||||
}
|
||||
printf("write out.smc\n");
|
||||
file = fopen("out.smc","w");
|
||||
fwrite(memory,memory_size,1,file);
|
||||
fclose(file);
|
||||
}
|
||||
|
||||
char rb_get(void)
|
||||
{
|
||||
rb_count--;
|
||||
if (r > t)
|
||||
r = b;
|
||||
return *r++;
|
||||
}
|
||||
|
||||
|
||||
char rb_read(int pos)
|
||||
{
|
||||
char *p;
|
||||
printf("rb_read: pos_mem=%06i pos_head=%06i pos=%06i\n",
|
||||
pos_mem, pos_head,pos);
|
||||
|
||||
if ( pos_head - pos > ringbuffer_size){
|
||||
printf("rb_read: memory[%i]=0x%02x \n",
|
||||
pos,
|
||||
memory[pos]);
|
||||
return memory[pos];
|
||||
}
|
||||
if (w - index >= b)
|
||||
p = w - index;
|
||||
else
|
||||
p = b + (b - ( w - index ));
|
||||
return *p;
|
||||
}
|
||||
|
||||
void rb_copy(int from,int to,int len){
|
||||
int i;
|
||||
char c;
|
||||
for (i = from; i< to; i++){
|
||||
c = rb_read(i);
|
||||
rb_put(c);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void rb_put(char el)
|
||||
{
|
||||
pos_head++;
|
||||
rb_count++;
|
||||
|
||||
if ( rb_count > ringbuffer_size){
|
||||
rb_dump();
|
||||
memory[pos_mem++]=*o++;
|
||||
if (o > t){
|
||||
o = b;
|
||||
}
|
||||
}
|
||||
printf("rb_count=%i pos_head=0x%06x add_mem=0x%06x\n",rb_count, pos_head,pos_mem);
|
||||
|
||||
if (w > t){
|
||||
w = b;
|
||||
}
|
||||
*w++ = el;
|
||||
}
|
||||
19
avr/usbload/ringbuffer.h
Normal file
19
avr/usbload/ringbuffer.h
Normal file
@@ -0,0 +1,19 @@
|
||||
|
||||
#ifndef _RING_BUFFER_H_
|
||||
#define _RING_BUFFER_H_
|
||||
|
||||
|
||||
#define ringbuffer_size 8
|
||||
|
||||
extern int rb_count;
|
||||
|
||||
#define rb_free() (ringbuffer_size - rb_count)
|
||||
#define rb_isfull() (rb_count == ringbuffer_size)
|
||||
#define rb_isempty() (rb_count == 0)
|
||||
|
||||
void rb_init(void);
|
||||
void rb_put(char el);
|
||||
char rb_get(void);
|
||||
void rb_flush(void);
|
||||
|
||||
#endif
|
||||
@@ -18,7 +18,7 @@
|
||||
* =====================================================================================
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include <avr/io.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
@@ -32,14 +32,14 @@
|
||||
|
||||
#define RUNCHAR 0x90
|
||||
|
||||
uint8_t rle_decode(PGM_VOID_P in_addr, int32_t in_len, uint32_t out_addr)
|
||||
#if 0
|
||||
|
||||
uint32_t rle_decode(PGM_VOID_P in_addr, int32_t in_len, uint32_t out_addr)
|
||||
{
|
||||
uint8_t in_byte, in_repeat, last_byte;
|
||||
uint32_t out_len, out_len_left;
|
||||
info("RLE decode len=%li addr=0x%08lx\n",in_len,out_addr);
|
||||
uint8_t in_byte, in_repeat, last_byte;
|
||||
info_P(PSTR("RLE decode len=%li addr=0x%08lx\n"), in_len, out_addr);
|
||||
last_byte = 0;
|
||||
|
||||
out_len_left = out_len;
|
||||
|
||||
sram_bulk_write_start(out_addr);
|
||||
#define INBYTE(b) \
|
||||
do { \
|
||||
@@ -58,100 +58,49 @@ uint8_t rle_decode(PGM_VOID_P in_addr, int32_t in_len, uint32_t out_addr)
|
||||
out_addr++;\
|
||||
} while(0)
|
||||
|
||||
INBYTE(in_byte);
|
||||
INBYTE(in_byte);
|
||||
|
||||
if (in_byte == RUNCHAR) {
|
||||
INBYTE(in_repeat);
|
||||
if (in_repeat != 0) {
|
||||
info("Orphaned RLE code at start\n");
|
||||
return 1;
|
||||
}
|
||||
OUTBYTE(RUNCHAR);
|
||||
} else {
|
||||
OUTBYTE(in_byte);
|
||||
}
|
||||
if (in_byte == RUNCHAR) {
|
||||
INBYTE(in_repeat);
|
||||
if (in_repeat != 0) {
|
||||
info_P(PSTR("Orphaned RLE code at start\n"));
|
||||
return 1;
|
||||
}
|
||||
OUTBYTE(RUNCHAR);
|
||||
} else {
|
||||
OUTBYTE(in_byte);
|
||||
}
|
||||
|
||||
while( in_len > 0 ) {
|
||||
INBYTE(in_byte);
|
||||
if (in_len%1024==0)
|
||||
info(".");
|
||||
if (in_byte == RUNCHAR) {
|
||||
INBYTE(in_repeat);
|
||||
if ( in_repeat == 0 ) {
|
||||
/* Just an escaped RUNCHAR value */
|
||||
OUTBYTE(RUNCHAR);
|
||||
} else {
|
||||
/* Pick up value and output a sequence of it */
|
||||
in_byte = last_byte; //;out_data[-1];
|
||||
while ( --in_repeat > 0 )
|
||||
OUTBYTE(in_byte);
|
||||
}
|
||||
} else {
|
||||
/* Normal byte */
|
||||
OUTBYTE(in_byte);
|
||||
}
|
||||
while (in_len > 0) {
|
||||
INBYTE(in_byte);
|
||||
if (in_len % 1024 == 0)
|
||||
info_P(PSTR("."));
|
||||
if (in_byte == RUNCHAR) {
|
||||
INBYTE(in_repeat);
|
||||
if (in_repeat == 0) {
|
||||
/*
|
||||
* Just an escaped RUNCHAR value
|
||||
*/
|
||||
OUTBYTE(RUNCHAR);
|
||||
} else {
|
||||
/*
|
||||
* Pick up value and output a sequence of it
|
||||
*/
|
||||
in_byte = last_byte; // ;out_data[-1];
|
||||
while (--in_repeat > 0)
|
||||
OUTBYTE(in_byte);
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* Normal byte
|
||||
*/
|
||||
OUTBYTE(in_byte);
|
||||
}
|
||||
last_byte = in_byte;
|
||||
}
|
||||
}
|
||||
sram_bulk_write_end();
|
||||
return 0;
|
||||
info_P(PSTR("\nDone addr=0x%08lx\n"), out_addr);
|
||||
return out_addr;
|
||||
}
|
||||
|
||||
|
||||
uint8_t rle_decode_sram(uint32_t in_addr, int32_t in_len, uint32_t out_addr)
|
||||
{
|
||||
uint8_t in_byte, in_repeat, last_byte;
|
||||
uint32_t out_len, out_len_left;
|
||||
info("RLE decode len=%li addr=0x%08lx\n",in_len,out_addr);
|
||||
last_byte = 0;
|
||||
out_len_left = out_len;
|
||||
#define INBYTE(b) \
|
||||
do { \
|
||||
if ( --in_len < 0 ) { \
|
||||
return 1; \
|
||||
} \
|
||||
b = sram_read(in_addr);\
|
||||
in_addr++;\
|
||||
} while(0)
|
||||
|
||||
#define OUTBYTE(b) \
|
||||
do { \
|
||||
sram_write(out_addr,b);\
|
||||
out_addr++;\
|
||||
} while(0)
|
||||
|
||||
INBYTE(in_byte);
|
||||
|
||||
if (in_byte == RUNCHAR) {
|
||||
INBYTE(in_repeat);
|
||||
if (in_repeat != 0) {
|
||||
info("Orphaned RLE code at start\n");
|
||||
return 1;
|
||||
}
|
||||
OUTBYTE(RUNCHAR);
|
||||
} else {
|
||||
OUTBYTE(in_byte);
|
||||
}
|
||||
|
||||
while( in_len > 0 ) {
|
||||
INBYTE(in_byte);
|
||||
if (in_len%1024==0)
|
||||
info(".");
|
||||
if (in_byte == RUNCHAR) {
|
||||
INBYTE(in_repeat);
|
||||
if ( in_repeat == 0 ) {
|
||||
/* Just an escaped RUNCHAR value */
|
||||
OUTBYTE(RUNCHAR);
|
||||
} else {
|
||||
/* Pick up value and output a sequence of it */
|
||||
in_byte = last_byte; //;out_data[-1];
|
||||
while ( --in_repeat > 0 )
|
||||
OUTBYTE(in_byte);
|
||||
}
|
||||
} else {
|
||||
/* Normal byte */
|
||||
OUTBYTE(in_byte);
|
||||
}
|
||||
last_byte = in_byte;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -18,12 +18,11 @@
|
||||
* =====================================================================================
|
||||
*/
|
||||
|
||||
#ifndef __RLE_H__
|
||||
#define __RLE_H__
|
||||
|
||||
#include <avr/pgmspace.h>
|
||||
#ifndef __RLE_H__
|
||||
#define __RLE_H__
|
||||
|
||||
uint8_t rle_decode(PGM_VOID_P in_addr,uint32_t in_len, uint32_t out_addr);
|
||||
uint8_t rle_decode_sram(uint32_t in_addr, int32_t in_len, uint32_t out_addr);
|
||||
#include <avr/pgmspace.h>
|
||||
|
||||
uint32_t rle_decode(PGM_VOID_P in_addr, uint32_t in_len, uint32_t out_addr);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -19,17 +19,20 @@
|
||||
*
|
||||
* =====================================================================================
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <util/delay.h>
|
||||
#include <util/delay.h>
|
||||
|
||||
#include "shared_memory.h"
|
||||
#include "config.h"
|
||||
#include "sram.h"
|
||||
#include "debug.h"
|
||||
#include "dump.h"
|
||||
#include "info.h"
|
||||
#include "crc.h"
|
||||
|
||||
|
||||
uint8_t irq_addr_lo;
|
||||
uint8_t irq_addr_hi;
|
||||
@@ -38,55 +41,305 @@ uint8_t scratchpad_state;
|
||||
uint8_t scratchpad_cmd;
|
||||
uint8_t scratchpad_payload;
|
||||
|
||||
void shared_memory_scratchpad_save(){
|
||||
scratchpad_state = sram_read(SHARED_MEM_LOC_STATE);
|
||||
scratchpad_cmd = sram_read(SHARED_MEM_LOC_CMD);
|
||||
scratchpad_payload = sram_read(SHARED_MEM_LOC_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;
|
||||
|
||||
|
||||
void shared_memory_init(void){
|
||||
scratchpad_locked_rx = 1;
|
||||
scratchpad_locked_tx = 1;
|
||||
|
||||
}
|
||||
|
||||
void shared_memory_scratchpad_restore(){
|
||||
sram_write(SHARED_MEM_LOC_STATE, scratchpad_state);
|
||||
sram_write(SHARED_MEM_LOC_CMD, scratchpad_cmd);
|
||||
sram_write(SHARED_MEM_LOC_PAYLOAD, scratchpad_payload);
|
||||
|
||||
uint8_t shared_memory_scratchpad_region_save_helper(uint32_t addr){
|
||||
|
||||
|
||||
|
||||
#if DO_SHM_SCRATCHPAD
|
||||
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;
|
||||
}
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
||||
void shared_memory_irq_hook(){
|
||||
|
||||
void shared_memory_scratchpad_region_tx_save()
|
||||
{
|
||||
sram_bulk_addr_save();
|
||||
|
||||
#if SHARED_SCRATCHPAD_CRC
|
||||
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 SHARED_SCRATCHPAD_CRC
|
||||
do_crc_update(0, scratchpad_region_tx,SHARED_MEM_TX_LOC_SIZE);
|
||||
debug_P(DEBUG_SHM, PSTR("shared_memory_scratchpad_region_tx_save: crc=%x\n"),crc);
|
||||
#endif
|
||||
|
||||
#if SHARED_SCRATCHPAD_DUMP
|
||||
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
|
||||
sram_bulk_addr_restore();
|
||||
|
||||
}
|
||||
|
||||
void shared_memory_scratchpad_region_rx_save()
|
||||
{
|
||||
|
||||
sram_bulk_addr_save();
|
||||
#if SHARED_SCRATCHPAD_CRC
|
||||
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_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 SHARED_SCRATCHPAD_CRC
|
||||
do_crc_update(0, scratchpad_region_rx,SHARED_MEM_RX_LOC_SIZE);
|
||||
debug_P(DEBUG_SHM, PSTR("shared_memory_scratchpad_region_rx_save: crc=%x\n"),crc);
|
||||
#endif
|
||||
|
||||
#if SHARED_SCRATCHPAD_DUMP
|
||||
dump_packet(SHARED_MEM_RX_LOC_STATE, SHARED_MEM_RX_LOC_SIZE, scratchpad_region_rx);
|
||||
dump_memory(SHARED_MEM_RX_LOC_STATE, SHARED_MEM_RX_LOC_STATE + SHARED_MEM_RX_LOC_SIZE);
|
||||
#endif
|
||||
sram_bulk_addr_restore();
|
||||
|
||||
}
|
||||
|
||||
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"));
|
||||
|
||||
#if SHARED_SCRATCHPAD_DUMP
|
||||
debug_P(DEBUG_SHM, PSTR("shared_memory_scratchpad_region_tx_restore: memory\n"));
|
||||
dump_memory(SHARED_MEM_TX_LOC_STATE, SHARED_MEM_TX_LOC_STATE + SHARED_MEM_TX_LOC_SIZE);
|
||||
#endif
|
||||
|
||||
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 SHARED_SCRATCHPAD_DUMP
|
||||
debug_P(DEBUG_SHM, PSTR("shared_memory_scratchpad_region_tx_restore: buffer\n"));
|
||||
dump_packet(SHARED_MEM_TX_LOC_STATE, SHARED_MEM_TX_LOC_SIZE, scratchpad_region_tx);
|
||||
debug_P(DEBUG_SHM, PSTR("shared_memory_scratchpad_region_tx_restore: memory\n"));
|
||||
dump_memory(SHARED_MEM_TX_LOC_STATE, SHARED_MEM_TX_LOC_STATE + SHARED_MEM_TX_LOC_SIZE);
|
||||
#endif
|
||||
|
||||
#if SHARED_SCRATCHPAD_CRC
|
||||
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_rx_restore: lock\n"));
|
||||
|
||||
#if SHARED_SCRATCHPAD_DUMP
|
||||
debug_P(DEBUG_SHM, PSTR("shared_memory_scratchpad_region_rx_restore: memory\n"));
|
||||
dump_memory(SHARED_MEM_RX_LOC_STATE - 0x10, SHARED_MEM_RX_LOC_STATE + SHARED_MEM_RX_LOC_SIZE);
|
||||
#endif
|
||||
|
||||
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 SHARED_SCRATCHPAD_DUMP
|
||||
debug_P(DEBUG_SHM, PSTR("shared_memory_scratchpad_region_rx_restore: buffer\n"));
|
||||
dump_packet(SHARED_MEM_RX_LOC_STATE, SHARED_MEM_RX_LOC_SIZE, scratchpad_region_rx);
|
||||
debug_P(DEBUG_SHM, PSTR("shared_memory_scratchpad_region_rx_restore: memory\n"));
|
||||
dump_memory(SHARED_MEM_RX_LOC_STATE - 0x10, SHARED_MEM_RX_LOC_STATE + SHARED_MEM_RX_LOC_SIZE);
|
||||
#endif
|
||||
|
||||
#if SHARED_SCRATCHPAD_CRC
|
||||
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()
|
||||
{
|
||||
scratchpad_state = sram_read(SHARED_MEM_TX_LOC_STATE);
|
||||
scratchpad_cmd = sram_read(SHARED_MEM_TX_LOC_CMD);
|
||||
scratchpad_payload = sram_read(SHARED_MEM_TX_LOC_PAYLOAD);
|
||||
}
|
||||
|
||||
void shared_memory_scratchpad_tx_restore()
|
||||
{
|
||||
sram_write(SHARED_MEM_TX_LOC_STATE, scratchpad_state);
|
||||
sram_write(SHARED_MEM_TX_LOC_CMD, scratchpad_cmd);
|
||||
sram_write(SHARED_MEM_TX_LOC_PAYLOAD, scratchpad_payload);
|
||||
}
|
||||
|
||||
|
||||
void shared_memory_irq_hook()
|
||||
{
|
||||
irq_addr_lo = sram_read(SHARED_IRQ_LOC_LO);
|
||||
irq_addr_hi = sram_read(SHARED_IRQ_LOC_HI);
|
||||
sram_write(SHARED_IRQ_HANDLER_LO, 0);
|
||||
sram_write(SHARED_IRQ_HANDLER_HI, 0);
|
||||
}
|
||||
|
||||
void shared_memory_irq_restore(){
|
||||
void shared_memory_irq_restore()
|
||||
{
|
||||
sram_write(SHARED_IRQ_LOC_LO, irq_addr_lo);
|
||||
sram_write(SHARED_IRQ_LOC_HI, irq_addr_hi);
|
||||
}
|
||||
|
||||
void shared_memory_put(uint8_t cmd, uint8_t value){
|
||||
|
||||
info("Write shared memory 0x%04x=0x%02x 0x%04x=0x%02x \n",SHARED_MEM_LOC_CMD,cmd,SHARED_MEM_LOC_PAYLOAD,value);
|
||||
void shared_memory_write(uint8_t cmd, uint8_t value)
|
||||
{
|
||||
#if DO_SHM
|
||||
#if DO_SHM_SCRATCHPAD
|
||||
if (scratchpad_locked_tx){
|
||||
debug_P(DEBUG_SHM, PSTR("shared_memory_write: locked_tx\n"));
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
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_memory_scratchpad_save();
|
||||
sram_bulk_addr_save();
|
||||
|
||||
#if (DO_SHM_SCRATCHPAD==0)
|
||||
shared_memory_scratchpad_tx_save();
|
||||
#endif
|
||||
#if SHARED_MEM_SWITCH_IRQ
|
||||
shared_memory_irq_hook();
|
||||
|
||||
sram_write(SHARED_MEM_LOC_STATE,SHARED_MEM_SNES_ACK);
|
||||
sram_write(SHARED_MEM_LOC_CMD,cmd);
|
||||
sram_write(SHARED_MEM_LOC_PAYLOAD,value);
|
||||
|
||||
#endif
|
||||
|
||||
sram_write(SHARED_MEM_TX_LOC_STATE, SHARED_MEM_TX_SNES_ACK);
|
||||
sram_write(SHARED_MEM_TX_LOC_CMD, cmd);
|
||||
sram_write(SHARED_MEM_TX_LOC_PAYLOAD, value);
|
||||
|
||||
snes_hirom();
|
||||
snes_wr_disable();
|
||||
snes_wr_disable();
|
||||
snes_bus_active();
|
||||
_delay_ms(50);
|
||||
|
||||
|
||||
|
||||
#if SHARED_MEM_SWITCH_IRQ
|
||||
snes_irq_on();
|
||||
snes_irq_lo();
|
||||
_delay_us(20);
|
||||
snes_irq_hi();
|
||||
snes_irq_off();
|
||||
#else
|
||||
_delay_ms(SHARED_MEM_SWITCH_DELAY);
|
||||
#endif
|
||||
|
||||
avr_bus_active();
|
||||
snes_irq_lo();
|
||||
snes_irq_off();
|
||||
snes_lorom();
|
||||
snes_wr_disable();
|
||||
|
||||
shared_memory_scratchpad_restore();
|
||||
snes_wr_disable();
|
||||
|
||||
#if (DO_SHM_SCRATCHPAD==0)
|
||||
shared_memory_scratchpad_tx_restore();
|
||||
#endif
|
||||
#if SHARED_MEM_SWITCH_IRQ
|
||||
shared_memory_irq_restore();
|
||||
#endif
|
||||
sram_bulk_addr_restore();
|
||||
#endif
|
||||
}
|
||||
|
||||
void shared_memory_yield()
|
||||
{
|
||||
|
||||
snes_hirom();
|
||||
snes_wr_disable();
|
||||
snes_bus_active();
|
||||
_delay_ms(SHARED_MEM_SWITCH_DELAY);
|
||||
avr_bus_active();
|
||||
snes_lorom();
|
||||
snes_wr_disable();
|
||||
|
||||
}
|
||||
|
||||
|
||||
int shared_memory_read(uint8_t *cmd, uint8_t *len,uint8_t *buffer)
|
||||
{
|
||||
uint8_t state;
|
||||
#if DO_SHM
|
||||
#if DO_SHM_SCRATCHPAD
|
||||
if (scratchpad_locked_rx){
|
||||
debug_P(DEBUG_SHM, PSTR("shared_memory_write: locked_tx\n"));
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
sram_bulk_addr_save();
|
||||
|
||||
state = sram_read(SHARED_MEM_RX_LOC_STATE);
|
||||
if (state != SHARED_MEM_RX_AVR_ACK){
|
||||
sram_bulk_addr_restore();
|
||||
return 1;
|
||||
}
|
||||
|
||||
*cmd = sram_read(SHARED_MEM_RX_LOC_CMD);
|
||||
*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"),
|
||||
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_write(SHARED_MEM_RX_LOC_STATE, SHARED_MEM_RX_AVR_RTS);
|
||||
|
||||
snes_hirom();
|
||||
snes_wr_disable();
|
||||
snes_bus_active();
|
||||
|
||||
#if SHARED_MEM_SWITCH_IRQ
|
||||
snes_irq_on();
|
||||
snes_irq_lo();
|
||||
_delay_us(20);
|
||||
snes_irq_hi();
|
||||
snes_irq_off();
|
||||
#else
|
||||
_delay_ms(SHARED_MEM_SWITCH_DELAY);
|
||||
#endif
|
||||
|
||||
avr_bus_active();
|
||||
snes_lorom();
|
||||
snes_wr_disable();
|
||||
sram_bulk_addr_restore();
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -17,35 +17,60 @@
|
||||
*
|
||||
* =====================================================================================
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __SHARED_MEMORY_H__
|
||||
#define __SHARED_MEMORY_H__
|
||||
|
||||
|
||||
#define SHARED_MEM_SNES_ACK 0xa5
|
||||
#define SHARED_MEM_SNES_RTS 0x5a
|
||||
#define SHARED_MEM_SWITCH_IRQ 0
|
||||
#define SHARED_MEM_SWITCH_DELAY 20
|
||||
|
||||
#define SHARED_MEM_TX_SNES_ACK 0xa5
|
||||
#define SHARED_MEM_TX_SNES_RTS 0x5a
|
||||
|
||||
#define SHARED_MEM_CMD_BANK_COUNT 0
|
||||
#define SHARED_MEM_CMD_BANK_CURRENT 1
|
||||
#define SHARED_MEM_TX_CMD_BANK_COUNT 0x00
|
||||
#define SHARED_MEM_TX_CMD_BANK_CURRENT 0x01
|
||||
|
||||
#define SHARED_MEM_CMD_UPLOAD_START 3
|
||||
#define SHARED_MEM_CMD_UPLOAD_END 4
|
||||
#define SHARED_MEM_CMD_UPLOAD_PROGESS 5
|
||||
#define SHARED_MEM_CMD_TERMINATE 6
|
||||
#define SHARED_MEM_TX_CMD_UPLOAD_START 0x03
|
||||
#define SHARED_MEM_TX_CMD_UPLOAD_END 0x04
|
||||
#define SHARED_MEM_TX_CMD_UPLOAD_PROGESS 0x05
|
||||
#define SHARED_MEM_TX_CMD_TERMINATE 0x06
|
||||
|
||||
#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_PAYLOAD 0x000002
|
||||
|
||||
#define SHARED_MEM_LOC_STATE 0x000000
|
||||
#define SHARED_MEM_LOC_CMD 0x000001
|
||||
#define SHARED_MEM_LOC_PAYLOAD 0x000002
|
||||
#define SHARED_MEM_RX_AVR_ACK 0xa5
|
||||
#define SHARED_MEM_RX_AVR_RTS 0x5a
|
||||
|
||||
#define SHARED_IRQ_LOC_LO 0x00fffe
|
||||
#define SHARED_IRQ_LOC_HI 0x00ffff
|
||||
#define SHARED_MEM_RX_CMD_PRINFT 0x00
|
||||
#define SHARED_MEM_RX_CMD_FILESEL 0x01
|
||||
|
||||
#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_LEN 0x001002
|
||||
#define SHARED_MEM_RX_LOC_PAYLOAD 0x001003
|
||||
|
||||
#define SHARED_IRQ_HANDLER_LO 0x00
|
||||
#define SHARED_IRQ_HANDLER_HI 0x10
|
||||
#define SHARED_IRQ_LOC_LO 0x00fffe
|
||||
#define SHARED_IRQ_LOC_HI 0x00ffff
|
||||
|
||||
void shared_memory_put(uint8_t cmd, uint8_t value);
|
||||
/* Use COP IRQ LOC for hooked IRQ handler */
|
||||
#define SHARED_IRQ_HANDLER_LO 0x0ffe4
|
||||
#define SHARED_IRQ_HANDLER_HI 0x0ffe5
|
||||
|
||||
#define SHARED_SCRATCHPAD_DUMP 0
|
||||
#define SHARED_SCRATCHPAD_CRC 0
|
||||
|
||||
|
||||
void shared_memory_init(void);
|
||||
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);
|
||||
int shared_memory_read(uint8_t *cmd, uint8_t *len,uint8_t *buffer);
|
||||
|
||||
#endif
|
||||
|
||||
487
avr/usbload/shell.c
Normal file
487
avr/usbload/shell.c
Normal file
@@ -0,0 +1,487 @@
|
||||
/*
|
||||
* =====================================================================================
|
||||
*
|
||||
* ________ .__ __ ________ ____ ________
|
||||
* \_____ \ __ __|__| ____ | | __\______ \ _______ _/_ |/ _____/
|
||||
* / / \ \| | \ |/ ___\| |/ / | | \_/ __ \ \/ /| / __ \
|
||||
* / \_/. \ | / \ \___| < | ` \ ___/\ / | \ |__\ \
|
||||
* \_____\ \_/____/|__|\___ >__|_ \/_______ /\___ >\_/ |___|\_____ /
|
||||
* \__> \/ \/ \/ \/ \/
|
||||
*
|
||||
* www.optixx.org
|
||||
*
|
||||
*
|
||||
* Version: 1.0
|
||||
* Created: 07/21/2009 03:32:16 PM
|
||||
* Author: david@optixx.org
|
||||
*
|
||||
* =====================================================================================
|
||||
*/
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <avr/io.h>
|
||||
#include <stdlib.h>
|
||||
#include <avr/interrupt.h>
|
||||
#include <util/delay.h>
|
||||
#include <avr/pgmspace.h>
|
||||
#include <avr/eeprom.h>
|
||||
|
||||
|
||||
#include "pwm.h"
|
||||
#include "debug.h"
|
||||
#include "info.h"
|
||||
#include "sram.h"
|
||||
#include "util.h"
|
||||
#include "uart.h"
|
||||
#include "dump.h"
|
||||
#include "irq.h"
|
||||
#include "config.h"
|
||||
#include "crc.h"
|
||||
#include "command.h"
|
||||
#include "shared_memory.h"
|
||||
#include "system.h"
|
||||
|
||||
|
||||
extern system_t system;
|
||||
|
||||
uint8_t command_buf[RECEIVE_BUF_LEN];
|
||||
uint8_t recv_buf[RECEIVE_BUF_LEN];
|
||||
|
||||
volatile uint8_t recv_counter = 0;
|
||||
volatile uint8_t cr = 0;
|
||||
|
||||
uint8_t *token_ptr;
|
||||
|
||||
#ifdef DO_SHELL
|
||||
|
||||
uint8_t *get_token(void)
|
||||
{
|
||||
uint8_t *p = token_ptr;
|
||||
while (*p == ' ')
|
||||
p++;
|
||||
if (*p == '\0')
|
||||
return NULL;
|
||||
token_ptr = p;
|
||||
do {
|
||||
token_ptr++;
|
||||
if (*token_ptr == ' ' || *token_ptr == '\n' || *token_ptr == '\r') {
|
||||
*token_ptr++ = '\0';
|
||||
break;
|
||||
}
|
||||
} while (*token_ptr != ' ' && *token_ptr != '\n' && *token_ptr != '\r');
|
||||
return p;
|
||||
}
|
||||
|
||||
uint8_t get_dec(uint32_t *decval)
|
||||
{
|
||||
const uint8_t *t;
|
||||
t = get_token();
|
||||
if (t != NULL) {
|
||||
int x = util_sscandec(t);
|
||||
if (x < 0)
|
||||
return 0;
|
||||
*decval = x;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t parse_hex(const uint8_t *s, uint32_t *hexval)
|
||||
{
|
||||
uint32_t x = util_sscanhex(s);
|
||||
*hexval = (uint32_t) x;
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint8_t get_hex(uint32_t *hexval)
|
||||
{
|
||||
const uint8_t *t;
|
||||
t = get_token();
|
||||
if (t != NULL)
|
||||
return parse_hex(t, hexval);
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t get_hex_arg2(uint32_t *hexval1, uint32_t *hexval2)
|
||||
{
|
||||
return get_hex(hexval1) && get_hex(hexval2);
|
||||
}
|
||||
|
||||
uint8_t get_hex_arg3(uint32_t *hexval1, uint32_t *hexval2, uint32_t *hexval3)
|
||||
{
|
||||
return get_hex(hexval1) && get_hex(hexval2) && get_hex(hexval3);
|
||||
}
|
||||
|
||||
static uint8_t get_int32(uint32_t *val)
|
||||
{
|
||||
if (!get_hex(val)){
|
||||
info_P(PSTR("Invalid argument!\n"));
|
||||
return 0;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t get_int8(uint8_t *val)
|
||||
{
|
||||
uint32_t ret;
|
||||
if (!get_hex(&ret) ||ret > 0xff){
|
||||
info_P(PSTR("Invalid argument!\n"));
|
||||
return 0;
|
||||
}else{
|
||||
*val = (uint8_t)ret;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
static int get_bool(void)
|
||||
{
|
||||
const uint8_t *t;
|
||||
t = get_token();
|
||||
if (t != NULL) {
|
||||
int result = util_sscanbool(t);
|
||||
if (result >= 0)
|
||||
return result;
|
||||
}
|
||||
info_P(PSTR("Invalid argument (should be 0 or 1)!\n"));
|
||||
return -1;
|
||||
}
|
||||
void prompt(void){
|
||||
|
||||
uart_putc('\r');
|
||||
uart_putc('\n');
|
||||
uart_putc('>');
|
||||
|
||||
}
|
||||
|
||||
ISR(USART0_RX_vect)
|
||||
{
|
||||
UCSR0B &= (255 - (1<<RXCIE0));// Interrupts disable for RxD
|
||||
sei();
|
||||
if(recv_counter == (sizeof(recv_buf)-1)) {
|
||||
cr=1;
|
||||
recv_buf[recv_counter]='\0';
|
||||
recv_counter=0;
|
||||
prompt();
|
||||
}
|
||||
recv_buf[recv_counter] = UDR0;
|
||||
uart_putc(recv_buf[recv_counter]);
|
||||
if (recv_buf[recv_counter] == 0x0d) {
|
||||
/* recv_buf[recv_counter] = 0; */
|
||||
cr = 1;
|
||||
recv_buf[++recv_counter]='\0';
|
||||
recv_counter = 0;
|
||||
prompt();
|
||||
} else {
|
||||
// we accept backspace or delete
|
||||
if ((recv_buf[recv_counter] == 0x08 || recv_buf[recv_counter] == 0x7f) && recv_counter > 0) {
|
||||
recv_counter--;
|
||||
} else {
|
||||
recv_counter++;
|
||||
}
|
||||
}
|
||||
UCSR0B |= (1<<RXCIE0);
|
||||
}
|
||||
|
||||
enum cmds {
|
||||
CMD_DUMP,
|
||||
CMD_DUMPVEC,
|
||||
CMD_DUMPHEADER,
|
||||
CMD_CRC,
|
||||
CMD_EXIT,
|
||||
CMD_RESET,
|
||||
CMD_RESETSNIFF,
|
||||
CMD_IRQ,
|
||||
CMD_AVR,
|
||||
CMD_SNES,
|
||||
CMD_LOROM,
|
||||
CMD_HIROM,
|
||||
CMD_WR,
|
||||
CMD_SHMWR,
|
||||
CMD_SHMSAVE,
|
||||
CMD_SHMRESTORE,
|
||||
CMD_LOADER,
|
||||
CMD_RECONNECT,
|
||||
CMD_STATUS,
|
||||
CMD_SYS,
|
||||
CMD_HELP
|
||||
};
|
||||
|
||||
uint8_t cmdlist[][CMD_HELP] PROGMEM = {
|
||||
{"DUMP"},
|
||||
{"DUMPVEC"},
|
||||
{"DUMPHEADER"},
|
||||
{"CRC"},
|
||||
{"EXIT"},
|
||||
{"RESET"},
|
||||
{"RESETSNIFF"},
|
||||
{"IRQ"},
|
||||
{"AVR"},
|
||||
{"SNES"},
|
||||
{"LOROM"},
|
||||
{"HIROM"},
|
||||
{"WR"},
|
||||
{"SHMWR"},
|
||||
{"SHMSAVE"},
|
||||
{"SHMRESTORE"},
|
||||
{"LOADER"},
|
||||
{"RECONNECT"},
|
||||
{"STATUS"},
|
||||
{"SYS"},
|
||||
{"HELP"},
|
||||
};
|
||||
|
||||
|
||||
void shell_help(void){
|
||||
uint8_t i;
|
||||
info_P(PSTR("\n"));
|
||||
for (i=CMD_DUMP; i<CMD_HELP; i++){
|
||||
info_P((PGM_P)cmdlist[i]);
|
||||
info_P(PSTR("\n"));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void shell_run(void)
|
||||
{
|
||||
uint8_t *t;
|
||||
uint32_t arg1;
|
||||
uint32_t arg2;
|
||||
uint32_t arg3;
|
||||
uint16_t crc;
|
||||
uint16_t offset;
|
||||
uint16_t i;
|
||||
uint8_t c;
|
||||
|
||||
if (!cr)
|
||||
return;
|
||||
cr=0;
|
||||
strcpy((char*)command_buf, (char*)recv_buf);
|
||||
|
||||
token_ptr = command_buf;
|
||||
t = get_token();
|
||||
|
||||
if (t == NULL)
|
||||
shell_help();
|
||||
|
||||
util_strupper(t);
|
||||
|
||||
if (strcmp_P((const char*)t,(PGM_P)cmdlist[CMD_DUMP]) == 0) {
|
||||
if (get_hex_arg2(&arg1,&arg2))
|
||||
dump_memory(arg1,arg2);
|
||||
else
|
||||
info_P(PSTR("DUMP <start addr> <end addr>\n"));
|
||||
|
||||
}else if (strcmp_P((char*)t, (PGM_P)cmdlist[CMD_CRC]) == 0) {
|
||||
if (get_hex_arg2(&arg1,&arg2)){
|
||||
crc = crc_check_bulk_memory(arg1,arg2,0x8000);
|
||||
info_P(PSTR("0x%06lx - 0x%06lx crc=0x%04x\n"),arg1,arg2,crc);
|
||||
} else
|
||||
info_P(PSTR("CRC <start addr> <end addr>\n"));
|
||||
}else if (strcmp_P((char*)t, (PGM_P)cmdlist[CMD_EXIT]) == 0) {
|
||||
leave_application();
|
||||
}else if (strcmp_P((char*)t, (PGM_P)cmdlist[CMD_RESET]) == 0) {
|
||||
system_send_snes_reset();
|
||||
}else if (strcmp_P((char*)t, (PGM_P)cmdlist[CMD_IRQ]) == 0) {
|
||||
info_P(PSTR("Send IRQ\n"));
|
||||
snes_irq_on();
|
||||
snes_irq_lo();
|
||||
_delay_us(20);
|
||||
snes_irq_hi();
|
||||
snes_irq_off();
|
||||
}else if (strcmp_P((char*)t, (PGM_P)cmdlist[CMD_AVR]) == 0) {
|
||||
//info_P(PSTR("Activate AVR bus\n"));
|
||||
//avr_bus_active();
|
||||
//snes_irq_lo();
|
||||
//snes_irq_off();
|
||||
system_set_bus_avr();
|
||||
snes_irq_lo();
|
||||
system_snes_irq_off();
|
||||
|
||||
}else if (strcmp_P((char*)t, (PGM_P)cmdlist[CMD_SNES]) == 0) {
|
||||
//info_P(PSTR("Activate SNES bus\n"));
|
||||
//snes_irq_lo();
|
||||
//snes_irq_off();
|
||||
//snes_wr_disable();
|
||||
//snes_bus_active();
|
||||
snes_irq_lo();
|
||||
system_snes_irq_off();
|
||||
system_set_wr_disable();
|
||||
system_set_bus_snes();
|
||||
|
||||
}else if (strcmp_P((char*)t, (PGM_P)cmdlist[CMD_LOROM]) == 0) {
|
||||
//info_P(PSTR("Set LOROM\n"));
|
||||
//snes_lorom();
|
||||
//snes_wr_disable();
|
||||
system_set_rom_lorom();
|
||||
system_set_wr_disable();
|
||||
|
||||
}else if (strcmp_P((char*)t, (PGM_P)cmdlist[CMD_HIROM]) == 0) {
|
||||
//info_P(PSTR("Set HIROM\n"));
|
||||
//snes_hirom();
|
||||
//snes_wr_disable();
|
||||
system_set_rom_hirom();
|
||||
system_set_wr_disable();
|
||||
}else if (strcmp_P((char*)t, (PGM_P)cmdlist[CMD_WR]) == 0) {
|
||||
arg1 = get_bool();
|
||||
if(arg1==1){
|
||||
info_P(PSTR("Set WR enable"));
|
||||
snes_wr_enable();
|
||||
}else if (arg1==0){
|
||||
info_P(PSTR("Set WR disable"));
|
||||
snes_wr_disable();
|
||||
}
|
||||
}else if (strcmp_P((char*)t, (PGM_P)cmdlist[CMD_RESETSNIFF]) == 0) {
|
||||
arg1 = get_bool();
|
||||
if(arg1==1){
|
||||
info_P(PSTR("Start Reset sniffer"));
|
||||
irq_init();
|
||||
}else if (arg1==0){
|
||||
info_P(PSTR("Stop Reset sniffer"));
|
||||
irq_stop();
|
||||
}
|
||||
}else if (strcmp_P((char*)t, (PGM_P)cmdlist[CMD_DUMPVEC]) == 0) {
|
||||
uint16_t offset;
|
||||
if (system.rom_mode==LOROM)
|
||||
offset = 0x8000;
|
||||
else
|
||||
offset = 0x0000;
|
||||
|
||||
info_P(PSTR("ABORT 0x%04x 0x%04x\n"), (0xFFE8 - offset),sram_read16_be(0xFFE8 - offset));
|
||||
info_P(PSTR("BRK 0x%04x 0x%04x\n"), (0xFFE6 - offset),sram_read16_be(0xFFE6 - offset));
|
||||
info_P(PSTR("COP 0x%04x 0x%04x\n"), (0xFFE4 - offset),sram_read16_be(0xFFE4 - offset));
|
||||
info_P(PSTR("IRQ 0x%04x 0x%04x\n"), (0xFFEE - offset),sram_read16_be(0xFFEE - offset));
|
||||
info_P(PSTR("NMI 0x%04x 0x%04x\n"), (0xFFEA - offset),sram_read16_be(0xFFEA - offset));
|
||||
info_P(PSTR("RES 0x%04x 0x%04x\n"), (0xFFFC - offset),sram_read16_be(0xFFFC - offset));
|
||||
|
||||
}else if (strcmp_P((char*)t, (PGM_P)cmdlist[CMD_DUMPHEADER]) == 0) {
|
||||
|
||||
if (system.rom_mode==LOROM)
|
||||
offset = 0x8000;
|
||||
else
|
||||
offset = 0x0000;
|
||||
/*
|
||||
# $ffc0..$ffd4 => Name of the ROM, typically in ASCII, using spaces to pad the name to 21 bytes.
|
||||
# $ffd5 => ROM layout, typically $20 for LoROM, or $21 for HiROM. Add $10 for FastROM.
|
||||
# $ffd6 => Cartridge type, typically $00 for ROM only, or $02 for ROM with save-RAM.
|
||||
# $ffd7 => ROM size byte.
|
||||
# $ffd8 => RAM size byte.
|
||||
# $ffd9 => Country code, which selects the video in the emulator. Values $00, $01, $0d use NTSC. Values in range $02..$0c use PAL. Other values are invalid.
|
||||
# $ffda => Licensee code. If this value is $33, then the ROM has an extended header with ID at $ffb2..$ffb5.
|
||||
# $ffdb => Version number, typically $00.
|
||||
# $ffdc..$ffdd => Checksum complement, which is the bitwise-xor of the checksum and $ffff.
|
||||
# $ffde..$ffdf => SNES checksum, an unsigned 16-bit checksum of bytes.
|
||||
# $ffe0..$ffe3 => Unknown.
|
||||
*/
|
||||
info_P(PSTR("NAME 0x%04x "), (0xffc0 - offset));
|
||||
for(arg1=(0xffc0 - offset); arg1<(0xffc0 - offset + 21);arg1++){
|
||||
c = sram_read(arg1);
|
||||
if (c>0x1f && c<0x7f)
|
||||
printf("%c",c);
|
||||
}
|
||||
printf("\n");
|
||||
c = sram_read(0xffd5 - offset);
|
||||
info_P(PSTR("LAYOUT 0x%04x "), (0xffd5 - offset));
|
||||
|
||||
switch(c){
|
||||
case 0x20:
|
||||
info_P(PSTR("LoROM, not fast\n"));
|
||||
break;
|
||||
case 0x21:
|
||||
info_P(PSTR("HiRom, not fast\n"));
|
||||
break;
|
||||
case 0x30:
|
||||
info_P(PSTR("LoROM, fast\n"));
|
||||
break;
|
||||
case 0x31:
|
||||
info_P(PSTR("HiRom, fast\n"));
|
||||
break;
|
||||
default:
|
||||
info_P(PSTR("Unkown 0x%02x\n"),c);
|
||||
break;
|
||||
}
|
||||
|
||||
c = sram_read(0xffd6 - offset);
|
||||
info_P(PSTR("TYPE 0x%04x "), (0xffd6 - offset),c);
|
||||
switch(c){
|
||||
case 0x00:
|
||||
info_P(PSTR("Rom\n"));
|
||||
break;
|
||||
case 0x01:
|
||||
info_P(PSTR("Rom + Sram\n"));
|
||||
break;
|
||||
case 0x02:
|
||||
info_P(PSTR("Rom + Sram + Battery\n"));
|
||||
break;
|
||||
case 0x13:
|
||||
info_P(PSTR("SuperFX\n"));
|
||||
break;
|
||||
case 0x14:
|
||||
info_P(PSTR("SuperFX\n"));
|
||||
break;
|
||||
case 0x15:
|
||||
info_P(PSTR("SuperFX + Sram\n"));
|
||||
break;
|
||||
case 0x1a:
|
||||
info_P(PSTR("SuperFX + Sram\n"));
|
||||
break;
|
||||
case 0x34:
|
||||
info_P(PSTR("SA-1"));
|
||||
break;
|
||||
case 0x35:
|
||||
info_P(PSTR("SA-1"));
|
||||
break;
|
||||
default:
|
||||
info_P(PSTR("Unkown 0x%02x\n"),c);
|
||||
break;
|
||||
}
|
||||
arg1 = ( 2 << ( sram_read(0xffd7 - offset) - 1 ));
|
||||
info_P(PSTR("ROM 0x%04x %li MBit ( %li KiB)\n"), (0xffd7 - offset), (arg1 / 128), arg1);
|
||||
arg1 = ( 2 << ( sram_read(0xffd8 - offset) - 1 ));
|
||||
info_P(PSTR("RAM 0x%04x %li KiB\n"), (0xffd8 - offset), arg1);
|
||||
|
||||
info_P(PSTR("CCODE 0x%04x "), (0xffd9 - offset));
|
||||
c = sram_read(0xffd9 - offset);
|
||||
if (c==0x00 || c==0x01 || 0x0d )
|
||||
info_P(PSTR("NTSC\n"));
|
||||
else if (c>=0x02 || c<=0x0c )
|
||||
info_P(PSTR("PAL\n"));
|
||||
else
|
||||
info_P(PSTR("Unkown 0x%02x\n"),c);
|
||||
|
||||
info_P(PSTR("LIC 0x%04x 0x%02x\n"), (0xffda - offset),sram_read(0xffda - offset));
|
||||
info_P(PSTR("VER 0x%04x 0x%02x\n"), (0xffdb - offset),sram_read(0xffdb - offset));
|
||||
info_P(PSTR("SUM1 0x%04x 0x%04x\n"), (0xffdc - offset),sram_read16_be(0xffdc - offset));
|
||||
info_P(PSTR("SUM2 0x%04x 0x%04x\n"), (0xffde - offset),sram_read16_be(0xffde - offset));
|
||||
|
||||
|
||||
}else if (strcmp_P((char*)t, (PGM_P)cmdlist[CMD_SHMWR]) == 0) {
|
||||
if (get_hex_arg2(&arg1,&arg2))
|
||||
shared_memory_write((uint8_t)arg1, (uint8_t)arg1);
|
||||
else
|
||||
info_P(PSTR("SHMWR <command> <value>\n"));
|
||||
}else if (strcmp_P((char*)t, (PGM_P)cmdlist[CMD_SHMSAVE]) == 0) {
|
||||
shared_memory_scratchpad_region_tx_save();
|
||||
shared_memory_scratchpad_region_rx_save();
|
||||
info_P(PSTR("Save scratchpad\n"));
|
||||
}else if (strcmp_P((char*)t, (PGM_P)cmdlist[CMD_SHMRESTORE]) == 0) {
|
||||
shared_memory_scratchpad_region_tx_restore();
|
||||
shared_memory_scratchpad_region_rx_restore();
|
||||
info_P(PSTR("Restore scratchpad\n"));
|
||||
}else if (strcmp_P((char*)t, (PGM_P)cmdlist[CMD_LOADER]) == 0) {
|
||||
boot_startup_rom(500);
|
||||
}else if (strcmp_P((char*)t, (PGM_P)cmdlist[CMD_RECONNECT]) == 0) {
|
||||
usb_connect();
|
||||
}else if (strcmp_P((char*)t, (PGM_P)cmdlist[CMD_STATUS]) == 0) {
|
||||
transaction_status();
|
||||
}else if (strcmp_P((char*)t, (PGM_P)cmdlist[CMD_SYS]) == 0) {
|
||||
system_status();
|
||||
}else if (strcmp_P((char*)t, (PGM_P)cmdlist[CMD_HELP]) == 0) {
|
||||
shell_help();
|
||||
}
|
||||
prompt();
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
26
avr/usbload/shell.h
Normal file
26
avr/usbload/shell.h
Normal file
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* =====================================================================================
|
||||
*
|
||||
* ________ .__ __ ________ ____ ________
|
||||
* \_____ \ __ __|__| ____ | | __\______ \ _______ _/_ |/ _____/
|
||||
* / / \ \| | \ |/ ___\| |/ / | | \_/ __ \ \/ /| / __ \
|
||||
* / \_/. \ | / \ \___| < | ` \ ___/\ / | \ |__\ \
|
||||
* \_____\ \_/____/|__|\___ >__|_ \/_______ /\___ >\_/ |___|\_____ /
|
||||
* \__> \/ \/ \/ \/ \/
|
||||
*
|
||||
* www.optixx.org
|
||||
*
|
||||
*
|
||||
* Version: 1.0
|
||||
* Created: 07/21/2009 03:32:16 PM
|
||||
* Author: david@optixx.org
|
||||
*
|
||||
* =====================================================================================
|
||||
*/
|
||||
|
||||
#ifndef __SHELL_H__
|
||||
#define __SHELL_H__
|
||||
|
||||
void shell_run(void);
|
||||
|
||||
#endif
|
||||
@@ -31,7 +31,10 @@
|
||||
#include "debug.h"
|
||||
#include "info.h"
|
||||
|
||||
void system_init(void)
|
||||
uint32_t addr_current = 0;
|
||||
uint32_t addr_stash = 0;
|
||||
|
||||
void sram_init(void)
|
||||
{
|
||||
/*-------------------------------------------------*/
|
||||
|
||||
@@ -44,18 +47,17 @@ void system_init(void)
|
||||
| (1 << AVR_ADDR_SCK_PIN)
|
||||
| (1 << AVR_ADDR_SER_PIN)
|
||||
| (1 << AVR_ADDR_LOAD_PIN)
|
||||
| (1 << AVR_ADDR_DOWN_PIN)
|
||||
| (1 << AVR_ADDR_UP_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)
|
||||
| (1 << AVR_ADDR_SCK_PIN)
|
||||
| (1 << SNES_WR_PIN));
|
||||
|
||||
|
||||
PORTC |= ( (1 << AVR_ADDR_DOWN_PIN)
|
||||
| (1 << AVR_ADDR_UP_PIN)
|
||||
PORTC |= ( (1 << AVR_ADDR_UP_PIN)
|
||||
| (1 << AVR_ADDR_LOAD_PIN));
|
||||
|
||||
//| (1 << SNES_WR_PIN));
|
||||
@@ -89,23 +91,22 @@ void system_init(void)
|
||||
|
||||
}
|
||||
|
||||
|
||||
void sreg_set(uint32_t addr)
|
||||
{
|
||||
uint8_t i = 24;
|
||||
debug(DEBUG_SREG,"sreg_set: addr=0x%08lx",addr);
|
||||
debug_P(DEBUG_SREG, PSTR("sreg_set: addr=0x%08lx"),addr);
|
||||
while(i--) {
|
||||
if ((addr & ( 1L << i))){
|
||||
debug(DEBUG_SREG,"1");
|
||||
debug_P(DEBUG_SREG, PSTR("1"));
|
||||
AVR_ADDR_SER_PORT |= ( 1 << AVR_ADDR_SER_PIN);
|
||||
} else {
|
||||
AVR_ADDR_SER_PORT &= ~( 1 << AVR_ADDR_SER_PIN);
|
||||
debug(DEBUG_SREG,"0");
|
||||
debug_P(DEBUG_SREG, PSTR("0"));
|
||||
}
|
||||
AVR_ADDR_SCK_PORT |= (1 << AVR_ADDR_SCK_PIN);
|
||||
AVR_ADDR_SCK_PORT &= ~(1 << AVR_ADDR_SCK_PIN);
|
||||
}
|
||||
debug(DEBUG_SREG,"\n");
|
||||
debug_P(DEBUG_SREG, PSTR("\n"));
|
||||
AVR_ADDR_LATCH_PORT |= (1 << AVR_ADDR_LATCH_PIN);
|
||||
AVR_ADDR_LATCH_PORT &= ~(1 << AVR_ADDR_LATCH_PIN);
|
||||
|
||||
@@ -113,11 +114,25 @@ void sreg_set(uint32_t addr)
|
||||
|
||||
}
|
||||
|
||||
void sram_bulk_addr_save()
|
||||
{
|
||||
addr_stash = addr_current;
|
||||
debug_P(DEBUG_SRAM, PSTR("sram_bulk_addr_save: addr=0x%08lx\n\r"), addr_stash);
|
||||
}
|
||||
|
||||
inline void sram_bulk_addr_restore()
|
||||
{
|
||||
debug_P(DEBUG_SRAM, PSTR("sram_bulk_addr_restore: addr=0x%08lx\n\r"), addr_stash);
|
||||
sram_bulk_write_start(addr_stash);
|
||||
}
|
||||
|
||||
|
||||
void sram_bulk_read_start(uint32_t addr)
|
||||
{
|
||||
debug(DEBUG_SRAM,"sram_bulk_read_start: addr=0x%08lx\n\r", addr);
|
||||
debug_P(DEBUG_SRAM, PSTR("sram_bulk_read_start: addr=0x%08lx\n\r"), addr);
|
||||
|
||||
addr_current = addr;
|
||||
|
||||
avr_data_in();
|
||||
|
||||
AVR_CS_PORT &= ~(1 << AVR_CS_PIN);
|
||||
@@ -138,6 +153,7 @@ void sram_bulk_read_start(uint32_t addr)
|
||||
|
||||
inline void sram_bulk_read_next(void)
|
||||
{
|
||||
addr_current++;
|
||||
AVR_RD_PORT |= (1 << AVR_RD_PIN);
|
||||
counter_up();
|
||||
AVR_RD_PORT &= ~(1 << AVR_RD_PIN);
|
||||
@@ -159,7 +175,7 @@ inline uint8_t sram_bulk_read(void)
|
||||
|
||||
void sram_bulk_read_end(void)
|
||||
{
|
||||
debug(DEBUG_SRAM,"sram_bulk_read_end:\n");
|
||||
debug_P(DEBUG_SRAM, PSTR("sram_bulk_read_end:\n"));
|
||||
|
||||
AVR_RD_PORT |= (1 << AVR_RD_PIN);
|
||||
AVR_CS_PORT |= (1 << AVR_CS_PIN);
|
||||
@@ -169,7 +185,7 @@ void sram_bulk_read_end(void)
|
||||
uint8_t sram_read(uint32_t addr)
|
||||
{
|
||||
uint8_t byte;
|
||||
debug(DEBUG_SRAM_RAW,"sram_read: addr=0x%08lx\n\r", addr);
|
||||
debug_P(DEBUG_SRAM_RAW, PSTR("sram_read: addr=0x%08lx\n\r"), addr);
|
||||
|
||||
avr_data_in();
|
||||
|
||||
@@ -199,9 +215,16 @@ uint8_t sram_read(uint32_t addr)
|
||||
|
||||
}
|
||||
|
||||
uint16_t sram_read16_be(uint32_t addr){
|
||||
uint8_t hi = sram_read(addr);
|
||||
uint8_t lo = sram_read(addr+1);
|
||||
return (hi << 8 | lo );
|
||||
}
|
||||
|
||||
void sram_bulk_write_start(uint32_t addr)
|
||||
{
|
||||
debug(DEBUG_SRAM,"sram_bulk_write_start: addr=0x%08lx\n\r", addr);
|
||||
debug_P(DEBUG_SRAM, PSTR("sram_bulk_write_start: addr=0x%08lx\n\r"), addr);
|
||||
addr_current = addr;
|
||||
|
||||
avr_data_out();
|
||||
|
||||
@@ -211,25 +234,25 @@ void sram_bulk_write_start(uint32_t addr)
|
||||
|
||||
sreg_set(addr);
|
||||
|
||||
AVR_WR_PORT &= ~(1 << AVR_WR_PIN);
|
||||
|
||||
}
|
||||
|
||||
inline void sram_bulk_write_next(void)
|
||||
{
|
||||
AVR_WR_PORT |= (1 << AVR_WR_PIN);
|
||||
counter_up();
|
||||
AVR_WR_PORT &= ~(1 << AVR_WR_PIN);
|
||||
addr_current++;
|
||||
counter_up();
|
||||
}
|
||||
|
||||
inline void sram_bulk_write( uint8_t data)
|
||||
{
|
||||
AVR_WR_PORT &= ~(1 << AVR_WR_PIN);
|
||||
AVR_DATA_PORT = data;
|
||||
}
|
||||
AVR_WR_PORT |= (1 << AVR_WR_PIN);
|
||||
}
|
||||
|
||||
void sram_bulk_write_end(void)
|
||||
{
|
||||
debug(DEBUG_SRAM,"sram_bulk_write_end:");
|
||||
debug_P(DEBUG_SRAM, PSTR("sram_bulk_write_end:"));
|
||||
AVR_WR_PORT |= (1 << AVR_WR_PIN);
|
||||
AVR_CS_PORT |= (1 << AVR_CS_PIN);
|
||||
avr_data_in();
|
||||
@@ -238,7 +261,7 @@ void sram_bulk_write_end(void)
|
||||
|
||||
void sram_write(uint32_t addr, uint8_t data)
|
||||
{
|
||||
debug(DEBUG_SRAM_RAW,"sram_write: addr=0x%08lx data=%x\n\r", addr, data);
|
||||
debug_P(DEBUG_SRAM_RAW, PSTR("sram_write: addr=0x%08lx data=%x\n\r"), addr, data);
|
||||
|
||||
avr_data_out();
|
||||
|
||||
@@ -267,90 +290,49 @@ void sram_write(uint32_t addr, uint8_t data)
|
||||
}
|
||||
|
||||
|
||||
void sram_bulk_copy(uint32_t addr, uint8_t * src, uint32_t len)
|
||||
void sram_bulk_copy_from_buffer(uint32_t addr, uint8_t * src, uint32_t len)
|
||||
{
|
||||
|
||||
uint32_t i;
|
||||
uint8_t *ptr = src;
|
||||
debug(DEBUG_SRAM,"sram_copy: addr=0x%08lx src=0x%p len=%li\n\r", addr,src,len);
|
||||
debug_P(DEBUG_SRAM, PSTR("sram_bulk_copy_from_buffer: addr=0x%08lx src=0x%p len=%li\n\r"),
|
||||
addr, src, len);
|
||||
sram_bulk_write_start(addr);
|
||||
for (i = addr; i < (addr + len); i++){
|
||||
sram_bulk_write(*ptr++);
|
||||
sram_bulk_write_next();
|
||||
sram_bulk_write(*ptr);
|
||||
//hack
|
||||
if ((i+1) < (addr + len))
|
||||
sram_bulk_write_next();
|
||||
ptr++;
|
||||
}
|
||||
sram_bulk_write_end();
|
||||
}
|
||||
|
||||
void sram_bulk_read_buffer(uint32_t addr, uint8_t * dst, uint32_t len)
|
||||
void sram_bulk_copy_into_buffer(uint32_t addr, uint8_t * dst, uint32_t len)
|
||||
{
|
||||
|
||||
uint32_t i;
|
||||
uint8_t *ptr = dst;
|
||||
debug(DEBUG_SRAM,"sram_bulk_read_buffer: addr=0x%08lx dst=0x%p len=%li\n\r", addr,dst,len);
|
||||
debug_P(DEBUG_SRAM, PSTR("sram_bulk_copy_into_buffer: addr=0x%08lx dst=0x%p len=%li\n\r"),
|
||||
addr, dst, len);
|
||||
sram_bulk_read_start(addr);
|
||||
for (i = addr; i < (addr + len); i++) {
|
||||
*ptr = sram_bulk_read();
|
||||
dst[i] = sram_bulk_read();
|
||||
sram_bulk_read_next();
|
||||
ptr++;
|
||||
}
|
||||
sram_bulk_read_end();
|
||||
}
|
||||
|
||||
void sram_bulk_set(uint32_t addr, uint32_t len,uint8_t value){
|
||||
uint32_t i;
|
||||
debug(DEBUG_SRAM,"sram_bulk_set: addr=0x%08lx len=%li\n\r", addr,len);
|
||||
debug_P(DEBUG_SRAM, PSTR("sram_bulk_set: addr=0x%08lx len=%li\n\r"), addr,len);
|
||||
sram_bulk_write_start(addr);
|
||||
for (i = addr; i < (addr + len); i++) {
|
||||
if (0 == i % 0xfff)
|
||||
debug(DEBUG_SRAM,"sram_bulk_set: addr=0x%08lx\n\r", i);
|
||||
debug_P(DEBUG_SRAM, PSTR("sram_bulk_set: addr=0x%08lx\n\r"), i);
|
||||
sram_bulk_write(value);
|
||||
sram_bulk_write_next();
|
||||
}
|
||||
sram_bulk_write_end();
|
||||
}
|
||||
|
||||
void sram_setr(uint32_t addr, uint32_t len,uint8_t value)
|
||||
{
|
||||
uint32_t i;
|
||||
debug(DEBUG_SRAM,"sram_clear: addr=0x%08lx len=%li\n\r", addr,len);
|
||||
for (i = addr; i < (addr + len); i++) {
|
||||
if (0 == i % 0xfff)
|
||||
debug(DEBUG_SRAM,"sram_clear: addr=0x%08lx\n\r", i);
|
||||
sram_write(i, value);
|
||||
}
|
||||
}
|
||||
|
||||
void sram_copy(uint32_t addr, uint8_t * src, uint32_t len)
|
||||
{
|
||||
|
||||
uint32_t i;
|
||||
uint8_t *ptr = src;
|
||||
debug(DEBUG_SRAM,"sram_copy: addr=0x%08lx src=0x%p len=%li\n\r", addr,src,len);
|
||||
for (i = addr; i < (addr + len); i++)
|
||||
sram_write(i, *ptr++);
|
||||
}
|
||||
|
||||
void sram_read_buffer(uint32_t addr, uint8_t * dst, uint32_t len)
|
||||
{
|
||||
|
||||
uint32_t i;
|
||||
uint8_t *ptr = dst;
|
||||
debug(DEBUG_SRAM,"sram_read_buffer: addr=0x%08lx dst=0x%p len=%li\n\r", addr,dst,len);
|
||||
for (i = addr; i < (addr + len); i++) {
|
||||
*ptr = sram_read(i);
|
||||
ptr++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
uint8_t sram_check(uint8_t * buffer, uint32_t len)
|
||||
{
|
||||
uint16_t cnt;
|
||||
debug(DEBUG_SRAM,"sram_check: len=%li\n\r",len);
|
||||
for (cnt = 0; cnt < len; cnt++)
|
||||
if (buffer[cnt])
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -40,14 +40,6 @@
|
||||
|
||||
#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 ---------------------------- */
|
||||
|
||||
@@ -85,17 +77,6 @@
|
||||
#define snes_irq_off() (SNES_IRQ_DIR &= ~(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 ---------------------------- */
|
||||
|
||||
@@ -105,22 +86,22 @@
|
||||
#define AVR_ADDR_LATCH_DIR DDRC
|
||||
#define AVR_ADDR_LATCH_PIN PC6
|
||||
|
||||
#define avr_addr_latch_hi() (AVR_ADDR_LATCH_PORT |= (1 << AVR_ADDR_LATCH_PIN)))
|
||||
#define avr_addr_latch_lo() (AVR_ADDR_LATCH_PORT &= ~(1 << AVR_ADDR_LATCH_PIN)))
|
||||
#define avr_addr_latch_hi() (AVR_ADDR_LATCH_PORT |= (1 << AVR_ADDR_LATCH_PIN))
|
||||
#define avr_addr_latch_lo() (AVR_ADDR_LATCH_PORT &= ~(1 << AVR_ADDR_LATCH_PIN))
|
||||
|
||||
#define AVR_ADDR_SCK_PORT PORTC
|
||||
#define AVR_ADDR_SCK_DIR DDRC
|
||||
#define AVR_ADDR_SCK_PIN PC5
|
||||
|
||||
#define avr_addr_sck_hi() (AVR_ADDR_SCK_PORT |= (1 << AVR_ADDR_SCK_PIN)))
|
||||
#define avr_addr_sck_lo() (AVR_ADDR_SCK_PORT &= ~(1 << AVR_ADDR_SCK_PIN)))
|
||||
#define avr_addr_sck_hi() (AVR_ADDR_SCK_PORT |= (1 << AVR_ADDR_SCK_PIN))
|
||||
#define avr_addr_sck_lo() (AVR_ADDR_SCK_PORT &= ~(1 << AVR_ADDR_SCK_PIN))
|
||||
|
||||
#define AVR_ADDR_SER_PORT PORTC
|
||||
#define AVR_ADDR_SER_DIR DDRC
|
||||
#define AVR_ADDR_SER_PIN PC4
|
||||
|
||||
#define avr_addr_ser_hi() (AVR_ADDR_SER_PORT |= (1 << AVR_ADDR_SER_PIN)))
|
||||
#define avr_addr_ser_lo() (AVR_ADDR_SER_PORT &= ~(1 << AVR_ADDR_SER_PIN)))
|
||||
#define avr_addr_ser_hi() (AVR_ADDR_SER_PORT |= (1 << AVR_ADDR_SER_PIN))
|
||||
#define avr_addr_ser_lo() (AVR_ADDR_SER_PORT &= ~(1 << AVR_ADDR_SER_PIN))
|
||||
|
||||
#define AVR_ADDR_LOAD_PORT PORTC
|
||||
#define AVR_ADDR_LOAD_DIR DDRC
|
||||
@@ -129,12 +110,12 @@
|
||||
#define counter_load() ((AVR_ADDR_LOAD_PORT &= ~(1 << AVR_ADDR_LOAD_PIN)),\
|
||||
(AVR_ADDR_LOAD_PORT |= (1 << AVR_ADDR_LOAD_PIN)))
|
||||
|
||||
#define AVR_ADDR_DOWN_PORT PORTC
|
||||
#define AVR_ADDR_DOWN_DIR DDRC
|
||||
#define AVR_ADDR_DOWN_PIN PC1
|
||||
#define AVR_BTLDR_EN_PORT PORTC
|
||||
#define AVR_BTLDR_EN_DIR DDRC
|
||||
#define AVR_BTLDR_EN_PIN PC1
|
||||
|
||||
#define counter_down() ((AVR_ADDR_DOWN_PORT &= ~(1 << AVR_ADDR_DOWN_PIN)),\
|
||||
(AVR_ADDR_DOWN_PORT |= (1 << AVR_ADDR_DOWN_PIN)))
|
||||
#define btldr_down() ((AVR_BTLDR_EN_PORT &= ~(1 << AVR_BTLDR_EN_PIN)),\
|
||||
(AVR_BTLDR_EN_PORT |= (1 << AVR_BTLDR_EN_PIN)))
|
||||
|
||||
#define AVR_ADDR_UP_PORT PORTC
|
||||
#define AVR_ADDR_UP_DIR DDRC
|
||||
@@ -147,6 +128,18 @@
|
||||
#define SNES_WR_DIR DDRC
|
||||
#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)))
|
||||
|
||||
#define led_pwm_on() (LED_DIR &=~ (1 << LED_PIN))
|
||||
#define led_pwm_off() (LED_DIR |= (1 << LED_PIN))
|
||||
|
||||
/* ---------------------------- PORT D ---------------------------- */
|
||||
|
||||
#define AVR_SNES_PORT PORTD
|
||||
@@ -160,7 +153,8 @@
|
||||
(AVR_CS_DIR |= (1 << AVR_CS_PIN)))
|
||||
|
||||
#define snes_bus_active() ((AVR_SNES_SW_PORT |= (1 << AVR_SNES_SW_PIN)),\
|
||||
(AVR_CS_DIR &= ~(1 << AVR_CS_PIN)))
|
||||
(AVR_CS_DIR &= ~(1 << AVR_CS_PIN)),\
|
||||
(AVR_CS_PORT |= (1 << AVR_CS_PIN)))
|
||||
|
||||
#define HI_LOROM_SW_PORT PORTD
|
||||
#define HI_LOROM_SW_DIR DDRD
|
||||
@@ -177,31 +171,56 @@
|
||||
|
||||
#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
|
||||
|
||||
|
||||
|
||||
|
||||
void system_init(void);
|
||||
|
||||
void sram_init(void);
|
||||
void sreg_set(uint32_t addr);
|
||||
|
||||
uint8_t sram_read(uint32_t addr);
|
||||
void sram_write(uint32_t addr, uint8_t data);
|
||||
void sram_set(uint32_t addr, uint32_t len, uint8_t value);
|
||||
void sram_copy(uint32_t addr,uint8_t *src, uint32_t len);
|
||||
void sram_read_buffer(uint32_t addr,uint8_t *dst, uint32_t len);
|
||||
|
||||
void sram_bulk_read_start(uint32_t addr);
|
||||
inline void sram_bulk_read_next(void);
|
||||
inline void sram_bulk_read_end(void);
|
||||
uint8_t sram_bulk_read(void);
|
||||
uint16_t sram_read16_be(uint32_t addr);
|
||||
|
||||
void sram_bulk_write_start(uint32_t addr);
|
||||
inline void sram_bulk_write_next(void);
|
||||
inline void sram_bulk_write_end(void);
|
||||
void sram_bulk_write(uint8_t data);
|
||||
|
||||
void sram_bulk_copy(uint32_t addr, uint8_t * src, uint32_t len);
|
||||
void sram_bulk_read_buffer(uint32_t addr, uint8_t * dst, uint32_t len);
|
||||
void sram_bulk_copy_from_buffer(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_set(uint32_t addr, uint32_t len,uint8_t value);
|
||||
|
||||
inline void sram_bulk_addr_save();
|
||||
inline void sram_bulk_addr_restore();
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
186
avr/usbload/system.c
Normal file
186
avr/usbload/system.c
Normal file
@@ -0,0 +1,186 @@
|
||||
/*
|
||||
* =====================================================================================
|
||||
*
|
||||
* ________ .__ __ ________ ____ ________
|
||||
* \_____ \ __ __|__| ____ | | __\______ \ _______ _/_ |/ _____/
|
||||
* / / \ \| | \ |/ ___\| |/ / | | \_/ __ \ \/ /| / __ \
|
||||
* / \_/. \ | / \ \___| < | ` \ ___/\ / | \ |__\ \
|
||||
* \_____\ \_/____/|__|\___ >__|_ \/_______ /\___ >\_/ |___|\_____ /
|
||||
* \__> \/ \/ \/ \/ \/
|
||||
*
|
||||
* www.optixx.org
|
||||
*
|
||||
*
|
||||
* Version: 1.0
|
||||
* Created: 07/21/2009 03:32:16 PM
|
||||
* Author: david@optixx.org
|
||||
*
|
||||
* =====================================================================================
|
||||
*/
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <avr/io.h>
|
||||
#include <util/delay.h> /* for _delay_ms() */
|
||||
#include <avr/interrupt.h>
|
||||
|
||||
|
||||
#include "config.h"
|
||||
#include "sram.h"
|
||||
#include "system.h"
|
||||
#include "uart.h"
|
||||
#include "debug.h"
|
||||
#include "info.h"
|
||||
#include "requests.h"
|
||||
#include "irq.h"
|
||||
|
||||
system_t system;
|
||||
|
||||
void system_init(void)
|
||||
{
|
||||
snes_reset_hi();
|
||||
snes_reset_off();
|
||||
system.reset_line = RESET_OFF;
|
||||
|
||||
snes_irq_hi();
|
||||
snes_irq_off();
|
||||
system.irq_line = IRQ_OFF;
|
||||
|
||||
|
||||
snes_wr_disable();
|
||||
system.wr_line = WR_DISABLE;
|
||||
|
||||
avr_bus_active();
|
||||
system.bus_mode = MODE_AVR;
|
||||
|
||||
snes_lorom();
|
||||
system.rom_mode = LOROM;
|
||||
|
||||
system.snes_reset_count = 0;
|
||||
system.avr_reset_count = 0;
|
||||
|
||||
system.reset_irq = RESET_IRQ_OFF;
|
||||
|
||||
}
|
||||
|
||||
void system_send_snes_reset()
|
||||
{
|
||||
info_P(PSTR("Reset SNES\n"));
|
||||
cli();
|
||||
snes_reset_on();
|
||||
snes_reset_lo();
|
||||
_delay_ms(2);
|
||||
snes_reset_hi();
|
||||
snes_reset_off();
|
||||
sei();
|
||||
system.snes_reset_count++;
|
||||
}
|
||||
|
||||
void system_send_snes_irq()
|
||||
{
|
||||
snes_irq_on();
|
||||
snes_irq_lo();
|
||||
_delay_us(20);
|
||||
snes_irq_hi();
|
||||
snes_irq_off();
|
||||
}
|
||||
|
||||
void system_snes_irq_off()
|
||||
{
|
||||
snes_irq_off();
|
||||
system.irq_line = IRQ_OFF;
|
||||
}
|
||||
|
||||
void system_snes_irq_on()
|
||||
{
|
||||
snes_irq_on();
|
||||
system.irq_line = IRQ_ON;
|
||||
}
|
||||
|
||||
|
||||
void system_set_bus_avr()
|
||||
{
|
||||
avr_bus_active();
|
||||
info_P(PSTR("Activate AVR bus\n"));
|
||||
system.bus_mode = MODE_AVR;
|
||||
}
|
||||
|
||||
void system_set_wr_disable(){
|
||||
snes_wr_disable();
|
||||
system.wr_line = WR_DISABLE;
|
||||
info_P(PSTR("Disable SNES WR\n"));
|
||||
}
|
||||
|
||||
void system_set_wr_enable(){
|
||||
snes_wr_enable();
|
||||
system.wr_line = WR_ENABLE;
|
||||
info_P(PSTR("Enable SNES WR\n"));
|
||||
}
|
||||
|
||||
void system_set_bus_snes()
|
||||
{
|
||||
snes_bus_active();
|
||||
system.bus_mode = MODE_SNES;
|
||||
info_P(PSTR("Activate SNES bus\n"));
|
||||
}
|
||||
|
||||
void system_set_rom_mode(usb_transaction_t *usb_trans)
|
||||
{
|
||||
if (usb_trans->req_bank_size == 0x8000) {
|
||||
snes_lorom();
|
||||
system.rom_mode = LOROM;
|
||||
info_P(PSTR("Set SNES lorom \n"));
|
||||
} else {
|
||||
snes_hirom();
|
||||
system.rom_mode = HIROM;
|
||||
info_P(PSTR("Set SNES hirom \n"));
|
||||
}
|
||||
}
|
||||
|
||||
void system_set_rom_lorom()
|
||||
{
|
||||
snes_lorom();
|
||||
system.rom_mode = LOROM;
|
||||
info_P(PSTR("Set SNES lorom \n"));
|
||||
}
|
||||
|
||||
|
||||
void system_set_rom_hirom()
|
||||
{
|
||||
snes_hirom();
|
||||
system.rom_mode = HIROM;
|
||||
info_P(PSTR("Set SNES hirom \n"));
|
||||
}
|
||||
|
||||
char* system_status_helper(uint8_t val){
|
||||
if (val)
|
||||
return "ON";
|
||||
else
|
||||
return "OFF";
|
||||
}
|
||||
|
||||
char* system_status_bus(uint8_t val){
|
||||
if (val)
|
||||
return "SNES";
|
||||
else
|
||||
return "AVR";
|
||||
}
|
||||
|
||||
char* system_status_rom(uint8_t val){
|
||||
if (val)
|
||||
return "HIROM";
|
||||
else
|
||||
return "LOROM";
|
||||
}
|
||||
|
||||
void system_status(){
|
||||
info_P(PSTR("\nBus Mode %s\n"),system_status_bus(system.bus_mode));
|
||||
info_P(PSTR("Rom Mode %s\n"),system_status_rom(system.rom_mode));
|
||||
info_P(PSTR("Reset Line %s\n"),system_status_helper(system.reset_line));
|
||||
info_P(PSTR("IRQ Line %s\n"),system_status_helper(system.irq_line));
|
||||
info_P(PSTR("WR Line %s\n"),system_status_helper(system.wr_line));
|
||||
info_P(PSTR("Reset IRQ %s\n"),system_status_helper(system.reset_irq));
|
||||
info_P(PSTR("SNES Reset 0x%02x\n"),system.snes_reset_count);
|
||||
info_P(PSTR("AVR Reset 0x%02x\n"),system.avr_reset_count);
|
||||
}
|
||||
57
avr/usbload/system.h
Normal file
57
avr/usbload/system.h
Normal file
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* =====================================================================================
|
||||
*
|
||||
* ________ .__ __ ________ ____ ________
|
||||
* \_____ \ __ __|__| ____ | | __\______ \ _______ _/_ |/ _____/
|
||||
* / / \ \| | \ |/ ___\| |/ / | | \_/ __ \ \/ /| / __ \
|
||||
* / \_/. \ | / \ \___| < | ` \ ___/\ / | \ |__\ \
|
||||
* \_____\ \_/____/|__|\___ >__|_ \/_______ /\___ >\_/ |___|\_____ /
|
||||
* \__> \/ \/ \/ \/ \/
|
||||
*
|
||||
* www.optixx.org
|
||||
*
|
||||
*
|
||||
* Version: 1.0
|
||||
* Created: 07/21/2009 03:32:16 PM
|
||||
* Author: david@optixx.org
|
||||
*
|
||||
* =====================================================================================
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#ifndef __SYSTEM_H__
|
||||
#define __SYSTEM_H__
|
||||
|
||||
#include "requests.h"
|
||||
|
||||
|
||||
|
||||
typedef struct system_t {
|
||||
enum bus_mode_e { MODE_AVR, MODE_SNES } bus_mode;
|
||||
enum rom_mode_e { LOROM, HIROM } rom_mode;
|
||||
enum reset_line_e { RESET_OFF, RESET_ON } reset_line;
|
||||
enum irq_line_e { IRQ_ON, IRQ_OFF } irq_line;
|
||||
enum wr_line_e { WR_DISABLE, WR_ENABLE } wr_line;
|
||||
enum reset_irq_e { RESET_IRQ_OFF, RESET_IRQ_ON } reset_irq;
|
||||
|
||||
uint8_t snes_reset_count;
|
||||
uint8_t avr_reset_count;
|
||||
} system_t;
|
||||
|
||||
void system_init(void);
|
||||
void system_init(void);
|
||||
void system_send_snes_reset(void);
|
||||
void system_send_snes_irq(void);
|
||||
void system_set_bus_avr(void);
|
||||
void system_set_bus_snes(void);
|
||||
void system_set_rom_mode(usb_transaction_t *usb_trans);
|
||||
void system_set_rom_hirom(void);
|
||||
void system_set_rom_lorom(void);
|
||||
void system_snes_irq_off(void);
|
||||
void system_set_wr_disable(void);
|
||||
void system_set_wr_enable(void);
|
||||
|
||||
void system_status();
|
||||
|
||||
#endif
|
||||
1184
avr/usbload/tags
Normal file
1184
avr/usbload/tags
Normal file
File diff suppressed because it is too large
Load Diff
131
avr/usbload/testing.c
Normal file
131
avr/usbload/testing.c
Normal file
@@ -0,0 +1,131 @@
|
||||
|
||||
|
||||
/*
|
||||
* =====================================================================================
|
||||
*
|
||||
* ________ .__ __ ________ ____ ________
|
||||
* \_____ \ __ __|__| ____ | | __\______ \ _______ _/_ |/ _____/
|
||||
* / / \ \| | \ |/ ___\| |/ / | | \_/ __ \ \/ /| / __ \
|
||||
* / \_/. \ | / \ \___| < | ` \ ___/\ / | \ |__\ \
|
||||
* \_____\ \_/____/|__|\___ >__|_ \/_______ /\___ >\_/ |___|\_____ /
|
||||
* \__> \/ \/ \/ \/ \/
|
||||
*
|
||||
* www.optixx.org
|
||||
*
|
||||
*
|
||||
* Version: 1.0
|
||||
* Created: 07/21/2009 03:32:16 PM
|
||||
* Author: david@optixx.org
|
||||
*
|
||||
* =====================================================================================
|
||||
*/
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <util/delay.h>
|
||||
|
||||
#include "shared_memory.h"
|
||||
#include "config.h"
|
||||
#include "sram.h"
|
||||
#include "debug.h"
|
||||
#include "crc.h"
|
||||
#include "info.h"
|
||||
#include "dump.h"
|
||||
|
||||
void test_read_write()
|
||||
{
|
||||
|
||||
uint8_t i;
|
||||
uint32_t addr;
|
||||
avr_bus_active();
|
||||
addr = 0x000000;
|
||||
i = 1;
|
||||
while (addr++ <= 0x0000ff) {
|
||||
sram_write(addr, i++);
|
||||
}
|
||||
addr = 0x000000;
|
||||
while (addr++ <= 0x0000ff) {
|
||||
info_P(PSTR("read addr=0x%08lx %x\n"), addr, sram_read(addr));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void test_bulk_read_write()
|
||||
{
|
||||
|
||||
uint8_t i;
|
||||
uint32_t addr;
|
||||
avr_bus_active();
|
||||
addr = 0x000000;
|
||||
i = 0;
|
||||
sram_bulk_write_start(addr);
|
||||
while (addr++ <= 0x8000) {
|
||||
sram_bulk_write(i++);
|
||||
sram_bulk_write_next();
|
||||
}
|
||||
sram_bulk_write_end();
|
||||
|
||||
addr = 0x000000;
|
||||
sram_bulk_read_start(addr);
|
||||
while (addr <= 0x8000) {
|
||||
info_P(PSTR("addr=0x%08lx %x\n"), addr, sram_bulk_read());
|
||||
sram_bulk_read_next();
|
||||
addr++;
|
||||
}
|
||||
sram_bulk_read_end();
|
||||
}
|
||||
|
||||
|
||||
void test_non_zero_memory(uint32_t bottom_addr, uint32_t top_addr)
|
||||
{
|
||||
uint32_t addr = 0;
|
||||
uint8_t c;
|
||||
sram_bulk_read_start(bottom_addr);
|
||||
for (addr = bottom_addr; addr < top_addr; addr++) {
|
||||
c = sram_bulk_read();
|
||||
if (c != 0xff)
|
||||
info_P(PSTR("addr=0x%08lx c=0x%x\n"), addr, c);
|
||||
sram_bulk_read_next();
|
||||
}
|
||||
sram_bulk_read_end();
|
||||
}
|
||||
|
||||
|
||||
void test_memory_pattern(uint32_t bottom_addr, uint32_t top_addr, uint32_t bank_size)
|
||||
{
|
||||
uint32_t addr = 0;
|
||||
uint8_t pattern = 0x55;
|
||||
info_P(PSTR("test_memory_pattern: bottom_addr=0x%08lx top_addr=0x%08lx\n"), bottom_addr, top_addr);
|
||||
sram_bulk_write_start(bottom_addr);
|
||||
for (addr = bottom_addr; addr < top_addr; addr++) {
|
||||
if (addr % bank_size == 0){
|
||||
pattern++;
|
||||
info_P(PSTR("test_memory_pattern: write addr=0x%08lx pattern=0x%08lx\n"), addr, pattern);
|
||||
}
|
||||
sram_bulk_write(pattern);
|
||||
}
|
||||
sram_bulk_write_end();
|
||||
|
||||
|
||||
for (addr = bottom_addr; addr < top_addr; addr+=bank_size) {
|
||||
info_P(PSTR("test_memory_pattern: dump bottom_addr=0x%08lx top_addr=0x%08lx\n"), addr, addr + bank_size);
|
||||
dump_memory(addr, addr + bank_size );
|
||||
info_P(PSTR("----------------------------------------------------------------\n"));
|
||||
}
|
||||
|
||||
crc_check_bulk_memory((uint32_t)bottom_addr,top_addr, bank_size);
|
||||
}
|
||||
|
||||
void test_crc()
|
||||
{
|
||||
info_P(PSTR("test_crc: clear\n"));
|
||||
avr_bus_active();
|
||||
sram_bulk_set(0x000000, 0x10000, 0xff);
|
||||
info_P(PSTR("test_crc: crc\n"));
|
||||
crc_check_bulk_memory(0x000000, 0x10000, 0x8000);
|
||||
info_P(PSTR("test_crc: check\n"));
|
||||
test_non_zero_memory(0x000000, 0x10000);
|
||||
}
|
||||
|
||||
31
avr/usbload/testing.h
Normal file
31
avr/usbload/testing.h
Normal file
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* =====================================================================================
|
||||
*
|
||||
* ________ .__ __ ________ ____ ________
|
||||
* \_____ \ __ __|__| ____ | | __\______ \ _______ _/_ |/ _____/
|
||||
* / / \ \| | \ |/ ___\| |/ / | | \_/ __ \ \/ /| / __ \
|
||||
* / \_/. \ | / \ \___| < | ` \ ___/\ / | \ |__\ \
|
||||
* \_____\ \_/____/|__|\___ >__|_ \/_______ /\___ >\_/ |___|\_____ /
|
||||
* \__> \/ \/ \/ \/ \/
|
||||
*
|
||||
* www.optixx.org
|
||||
*
|
||||
*
|
||||
* Version: 1.0
|
||||
* Created: 07/21/2009 03:32:16 PM
|
||||
* Author: david@optixx.org
|
||||
*
|
||||
* =====================================================================================
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __TESTING_H__
|
||||
#define __TESTING_H__
|
||||
|
||||
|
||||
void test_read_write();
|
||||
void test_bulk_read_write();
|
||||
void test_non_zero_memory(uint32_t bottom_addr, uint32_t top_addr);
|
||||
void test_crc();
|
||||
|
||||
#endif
|
||||
@@ -29,7 +29,11 @@
|
||||
|
||||
#include "debug.h"
|
||||
#include "info.h"
|
||||
#include "sram.h"
|
||||
|
||||
|
||||
extern uint8_t snes_reset_line;
|
||||
|
||||
#ifndef OCR1A
|
||||
#define OCR1A OCR1 // 2313 support
|
||||
#endif
|
||||
@@ -52,6 +56,7 @@ uint16_t volatile second; // count seconds
|
||||
|
||||
ISR (SIG_OUTPUT_COMPARE1A)
|
||||
{
|
||||
|
||||
|
||||
#if XTAL % DEBOUNCE // bei rest
|
||||
OCR1A = 20000000UL / DEBOUNCE - 1; // compare DEBOUNCE - 1 times
|
||||
|
||||
@@ -25,19 +25,21 @@
|
||||
#include "uart.h"
|
||||
#include "fifo.h"
|
||||
|
||||
|
||||
|
||||
volatile struct {
|
||||
uint8_t tmr_int:1;
|
||||
uint8_t adc_int:1;
|
||||
uint8_t rx_int:1;
|
||||
} intflags;
|
||||
|
||||
/*
|
||||
* * Last character read from the UART.
|
||||
*
|
||||
*/
|
||||
|
||||
volatile char rxbuff;
|
||||
|
||||
|
||||
|
||||
static int uart_stream(char c, FILE *stream);
|
||||
|
||||
FILE uart_stdout = FDEV_SETUP_STREAM(uart_stream, NULL, _FDEV_SETUP_WRITE);
|
||||
|
||||
void uart_init(void)
|
||||
@@ -50,7 +52,7 @@ void uart_init(void)
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
ISR(USART0_RX_vect)
|
||||
{
|
||||
uint8_t c;
|
||||
@@ -60,7 +62,7 @@ ISR(USART0_RX_vect)
|
||||
intflags.rx_int = 1;
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
void uart_putc(uint8_t c)
|
||||
{
|
||||
|
||||
@@ -32,8 +32,8 @@ void uart_init(void);
|
||||
void uart_putc(const uint8_t);
|
||||
void uart_puts(const char *s);
|
||||
void uart_puts_P(PGM_P s);
|
||||
static int uart_stream(char c, FILE *stream);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -39,41 +39,24 @@
|
||||
#include "crc.h"
|
||||
#include "usb_bulk.h"
|
||||
|
||||
extern uint8_t read_buffer[TRANSFER_BUFFER_SIZE];
|
||||
extern uint32_t req_addr;
|
||||
extern uint32_t req_size;
|
||||
extern uint8_t req_bank;
|
||||
extern uint32_t req_bank_size;
|
||||
extern uint8_t req_state;
|
||||
extern uint8_t rx_remaining;
|
||||
extern uint8_t tx_remaining;
|
||||
extern uint8_t tx_buffer[32];
|
||||
extern uint16_t crc;
|
||||
|
||||
extern usb_transaction_t usb_trans;
|
||||
|
||||
uint8_t usbFunctionWrite(uint8_t * data, uint8_t len)
|
||||
{
|
||||
uint8_t *ptr;
|
||||
uint8_t i;
|
||||
|
||||
if (len > rx_remaining) {
|
||||
info("ERROR:usbFunctionWrite more data than expected remain: %i len: %i\n",
|
||||
rx_remaining, len);
|
||||
len = rx_remaining;
|
||||
if (len > usb_trans.rx_remaining) {
|
||||
info_P(PSTR("ERROR:usbFunctionWrite more data than expected remain: %i len: %i\n"),
|
||||
usb_trans.rx_remaining, len);
|
||||
len = usb_trans.rx_remaining;
|
||||
}
|
||||
if (req_state == REQ_STATUS_UPLOAD) {
|
||||
if (usb_trans.req_state == REQ_STATUS_BULK_UPLOAD) {
|
||||
|
||||
rx_remaining -= len;
|
||||
debug(DEBUG_USB_TRANS,"usbFunctionWrite REQ_STATUS_UPLOAD addr: 0x%08lx len: %i rx_remaining=%i\n",
|
||||
req_addr, len, rx_remaining);
|
||||
debug(DEBUG_USB_TRANS,"usbFunctionWrite %02x %02x %02x %02x %02x %02x %02x %x\n",
|
||||
data[0],data[1],data[2],data[3],data[4],data[5],data[6],data[7]);
|
||||
sram_copy(req_addr, data, len);
|
||||
req_addr += len;
|
||||
} else if (req_state == REQ_STATUS_BULK_UPLOAD) {
|
||||
|
||||
rx_remaining -= len;
|
||||
debug(DEBUG_USB_TRANS,"usbFunctionWrite REQ_STATUS_BULK_UPLOAD addr: 0x%08lx len: %i rx_remaining=%i\n",
|
||||
req_addr, len, rx_remaining);
|
||||
usb_trans.rx_remaining -= len;
|
||||
debug_P(DEBUG_USB_TRANS, PSTR("usbFunctionWrite REQ_STATUS_BULK_UPLOAD addr: 0x%08lx len: %i rx_remaining=%i\n"),
|
||||
usb_trans.req_addr, len, usb_trans.rx_remaining);
|
||||
ptr = data;
|
||||
i = len;
|
||||
while(i--){
|
||||
@@ -81,21 +64,19 @@ uint8_t usbFunctionWrite(uint8_t * data, uint8_t len)
|
||||
sram_bulk_write_next();
|
||||
}
|
||||
}
|
||||
/* test this */
|
||||
//return rx_remaining == 0
|
||||
return len;
|
||||
}
|
||||
|
||||
uint8_t usbFunctionRead(uint8_t * data, uint8_t len)
|
||||
{
|
||||
uint8_t i;
|
||||
if (len > tx_remaining)
|
||||
len = tx_remaining;
|
||||
tx_remaining -= len;
|
||||
debug(DEBUG_USB_TRANS,"usbFunctionRead len=%i tx_remaining=%i \n", len, tx_remaining);
|
||||
if (len > usb_trans.tx_remaining)
|
||||
len = usb_trans.tx_remaining;
|
||||
usb_trans.tx_remaining -= len;
|
||||
debug_P(DEBUG_USB_TRANS, PSTR("usbFunctionRead len=%i tx_remaining=%i \n"), len, usb_trans.tx_remaining);
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
*data = tx_buffer[len];
|
||||
*data = usb_trans.tx_buffer[len];
|
||||
data++;
|
||||
}
|
||||
return len;
|
||||
|
||||
@@ -127,7 +127,7 @@ section at the end of this file).
|
||||
* (e.g. HID), but never want to send any data. This option saves a couple
|
||||
* of bytes in flash memory and the transmit buffers in RAM.
|
||||
*/
|
||||
#define USB_CFG_INTR_POLL_INTERVAL 200
|
||||
#define USB_CFG_INTR_POLL_INTERVAL 20
|
||||
/* If you compile a version with endpoint 1 (interrupt-in), this is the poll
|
||||
* interval. The value is in milliseconds and must not be less than 10 ms for
|
||||
* low speed devices.
|
||||
@@ -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
|
||||
* details.
|
||||
*/
|
||||
#define USB_CFG_DEVICE_NAME 'S', 'N', 'E', 'S', 'R', 'A', 'M'
|
||||
#define USB_CFG_DEVICE_NAME_LEN 7
|
||||
#define USB_CFG_DEVICE_NAME 'Q', 'U', 'I', 'C', 'K', 'D', 'E', 'V', '1', '6'
|
||||
#define USB_CFG_DEVICE_NAME_LEN 10
|
||||
/* 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
|
||||
* use a shared VID/PID.
|
||||
|
||||
132
avr/usbload/util.c
Normal file
132
avr/usbload/util.c
Normal file
@@ -0,0 +1,132 @@
|
||||
/*
|
||||
* =====================================================================================
|
||||
*
|
||||
* ________ .__ __ ________ ____ ________
|
||||
* \_____ \ __ __|__| ____ | | __\______ \ _______ _/_ |/ _____/
|
||||
* / / \ \| | \ |/ ___\| |/ / | | \_/ __ \ \/ /| / __ \
|
||||
* / \_/. \ | / \ \___| < | ` \ ___/\ / | \ |__\ \
|
||||
* \_____\ \_/____/|__|\___ >__|_ \/_______ /\___ >\_/ |___|\_____ /
|
||||
* \__> \/ \/ \/ \/ \/
|
||||
*
|
||||
* www.optixx.org
|
||||
*
|
||||
*
|
||||
* Version: 1.0
|
||||
* Created: 07/21/2009 03:32:16 PM
|
||||
* Author: david@optixx.org
|
||||
*
|
||||
* =====================================================================================
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
uint8_t *util_strupper(uint8_t *s)
|
||||
{
|
||||
uint8_t *p;
|
||||
for (p = s; *p != '\0'; p++)
|
||||
if (*p >= 'a' && *p <= 'z')
|
||||
*p += 'A' - 'a';
|
||||
return s;
|
||||
}
|
||||
|
||||
uint8_t *util_strlower(uint8_t *s)
|
||||
{
|
||||
uint8_t *p;
|
||||
for (p = s; *p != '\0'; p++)
|
||||
if (*p >= 'A' && *p <= 'Z')
|
||||
*p += 'a' - 'A';
|
||||
return s;
|
||||
}
|
||||
|
||||
void util_chomp(uint8_t *s)
|
||||
{
|
||||
uint16_t len;
|
||||
|
||||
len = strlen((char*)s);
|
||||
if (len >= 2 && s[len - 1] == '\n' && s[len - 2] == '\r')
|
||||
s[len - 2] = '\0';
|
||||
else if (len >= 1 && (s[len - 1] == '\n' || s[len - 1] == '\r'))
|
||||
s[len - 1] = '\0';
|
||||
}
|
||||
|
||||
void util_trim(uint8_t *s)
|
||||
{
|
||||
uint8_t *p = s;
|
||||
uint8_t *q;
|
||||
/* skip leading whitespace */
|
||||
while (*p == ' ' || *p == '\t' || *p == '\r' || *p == '\n')
|
||||
p++;
|
||||
/* now p points at the first non-whitespace uint8_tacter */
|
||||
|
||||
if (*p == '\0') {
|
||||
/* only whitespace */
|
||||
*s = '\0';
|
||||
return;
|
||||
}
|
||||
|
||||
q = s + strlen((char*)s);
|
||||
/* skip trailing whitespace */
|
||||
/* we have found p < q such that *p is non-whitespace,
|
||||
so this loop terminates with q >= p */
|
||||
do
|
||||
q--;
|
||||
while (*q == ' ' || *q == '\t' || *q == '\r' || *q == '\n');
|
||||
|
||||
/* now q points at the last non-whitespace uint8_tacter */
|
||||
/* cut off trailing whitespace */
|
||||
*++q = '\0';
|
||||
|
||||
/* move to string */
|
||||
memmove(s, p, q + 1 - p);
|
||||
}
|
||||
|
||||
uint32_t util_sscandec(const uint8_t *s)
|
||||
{
|
||||
uint32_t result;
|
||||
if (*s == '\0')
|
||||
return -1;
|
||||
result = 0;
|
||||
for (;;) {
|
||||
if (*s >= '0' && *s <= '9')
|
||||
result = 10 * result + *s - '0';
|
||||
else if (*s == '\0')
|
||||
return result;
|
||||
else
|
||||
return -1;
|
||||
s++;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t util_sscanhex(const uint8_t *s)
|
||||
{
|
||||
int32_t result;
|
||||
if (*s == '\0')
|
||||
return -1;
|
||||
result = 0;
|
||||
for (;;) {
|
||||
if (*s >= '0' && *s <= '9')
|
||||
result = 16 * result + *s - '0';
|
||||
else if (*s >= 'A' && *s <= 'F')
|
||||
result = 16 * result + *s - 'A' + 10;
|
||||
else if (*s >= 'a' && *s <= 'f')
|
||||
result = 16 * result + *s - 'a' + 10;
|
||||
else if (*s == '\0')
|
||||
return result;
|
||||
else
|
||||
return -1;
|
||||
s++;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t util_sscanbool(const uint8_t *s)
|
||||
{
|
||||
if (*s == '0' && s[1] == '\0')
|
||||
return 0;
|
||||
if (*s == '1' && s[1] == '\0')
|
||||
return 1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
32
avr/usbload/util.h
Normal file
32
avr/usbload/util.h
Normal file
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* =====================================================================================
|
||||
*
|
||||
* ________ .__ __ ________ ____ ________
|
||||
* \_____ \ __ __|__| ____ | | __\______ \ _______ _/_ |/ _____/
|
||||
* / / \ \| | \ |/ ___\| |/ / | | \_/ __ \ \/ /| / __ \
|
||||
* / \_/. \ | / \ \___| < | ` \ ___/\ / | \ |__\ \
|
||||
* \_____\ \_/____/|__|\___ >__|_ \/_______ /\___ >\_/ |___|\_____ /
|
||||
* \__> \/ \/ \/ \/ \/
|
||||
*
|
||||
* www.optixx.org
|
||||
*
|
||||
*
|
||||
* Version: 1.0
|
||||
* Created: 07/21/2009 03:32:16 PM
|
||||
* Author: david@optixx.org
|
||||
*
|
||||
* =====================================================================================
|
||||
*/
|
||||
|
||||
#ifndef __UTIL_H__
|
||||
#define __UTIL_H__
|
||||
|
||||
uint8_t *util_strupper(uint8_t *s);
|
||||
uint8_t *util_strlower(uint8_t *s);
|
||||
void util_chomp(uint8_t *s);
|
||||
void util_trim(uint8_t *s);
|
||||
uint32_t util_sscandec(const uint8_t *s);
|
||||
uint32_t util_sscanhex(const uint8_t *s);
|
||||
uint8_t util_sscanbool(const uint8_t *s);
|
||||
|
||||
#endif
|
||||
10
done.txt
Normal file
10
done.txt
Normal file
@@ -0,0 +1,10 @@
|
||||
x 2009-10-13 Send PCB to seeed
|
||||
x 2009-10-13 RS232 cable add programm header and sio lines
|
||||
x 2009-10-13 Assemble No. 006 & No. 007
|
||||
x 2009-10-13 Flash all cartridge with latest firmware and bootloader
|
||||
x 2009-10-13 Bootloader lockbits
|
||||
x 2009-10-13 Rework No. 002
|
||||
x 2009-10-13 Package for Quickdev16
|
||||
x 2009-10-13 Add struct for usb and communcations flags
|
||||
x 2009-10-13 Mail snega2usb about OEM
|
||||
x 2009-10-13 Email to seeed about the retour package
|
||||
39
packages/efsl-0.3.6/CHANGELOG
vendored
Normal file
39
packages/efsl-0.3.6/CHANGELOG
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
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
|
||||
|
||||
31
packages/efsl-0.3.6/Makefile
vendored
Normal file
31
packages/efsl-0.3.6/Makefile
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
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
|
||||
174
packages/efsl-0.3.6/conf/config-avr.h
vendored
Normal file
174
packages/efsl-0.3.6/conf/config-avr.h
vendored
Normal file
@@ -0,0 +1,174 @@
|
||||
#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
|
||||
46
packages/efsl-0.3.6/conf/config-avr.makefile
vendored
Normal file
46
packages/efsl-0.3.6/conf/config-avr.makefile
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
################################################################################
|
||||
### 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)
|
||||
151
packages/efsl-0.3.6/conf/config-linux.h
vendored
Normal file
151
packages/efsl-0.3.6/conf/config-linux.h
vendored
Normal file
@@ -0,0 +1,151 @@
|
||||
#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
|
||||
38
packages/efsl-0.3.6/conf/config-linux.makefile
vendored
Normal file
38
packages/efsl-0.3.6/conf/config-linux.makefile
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
################################################################################
|
||||
### 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)
|
||||
151
packages/efsl-0.3.6/conf/config-linux64.h
vendored
Normal file
151
packages/efsl-0.3.6/conf/config-linux64.h
vendored
Normal file
@@ -0,0 +1,151 @@
|
||||
#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
|
||||
38
packages/efsl-0.3.6/conf/config-linux64.makefile
vendored
Normal file
38
packages/efsl-0.3.6/conf/config-linux64.makefile
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
################################################################################
|
||||
### 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
packages/efsl-0.3.6/conf/config.h
vendored
Symbolic link
1
packages/efsl-0.3.6/conf/config.h
vendored
Symbolic link
@@ -0,0 +1 @@
|
||||
config-linux.h
|
||||
1
packages/efsl-0.3.6/conf/config.makefile
vendored
Symbolic link
1
packages/efsl-0.3.6/conf/config.makefile
vendored
Symbolic link
@@ -0,0 +1 @@
|
||||
config-linux.makefile
|
||||
13
packages/efsl-0.3.6/docs/Makefile
vendored
Normal file
13
packages/efsl-0.3.6/docs/Makefile
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
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
|
||||
4407
packages/efsl-0.3.6/docs/efsl-manual-0.3.5.pdf
vendored
Normal file
4407
packages/efsl-0.3.6/docs/efsl-manual-0.3.5.pdf
vendored
Normal file
File diff suppressed because it is too large
Load Diff
117
packages/efsl-0.3.6/docs/manual.tex
vendored
Normal file
117
packages/efsl-0.3.6/docs/manual.tex
vendored
Normal file
@@ -0,0 +1,117 @@
|
||||
\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}
|
||||
223
packages/efsl-0.3.6/docs/pages/avr.tex
vendored
Normal file
223
packages/efsl-0.3.6/docs/pages/avr.tex
vendored
Normal file
@@ -0,0 +1,223 @@
|
||||
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}
|
||||
180
packages/efsl-0.3.6/docs/pages/config.tex
vendored
Normal file
180
packages/efsl-0.3.6/docs/pages/config.tex
vendored
Normal file
@@ -0,0 +1,180 @@
|
||||
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.
|
||||
34
packages/efsl-0.3.6/docs/pages/dateandtime.tex
vendored
Normal file
34
packages/efsl-0.3.6/docs/pages/dateandtime.tex
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
\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.
|
||||
38
packages/efsl-0.3.6/docs/pages/debug.tex
vendored
Normal file
38
packages/efsl-0.3.6/docs/pages/debug.tex
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
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.
|
||||
166
packages/efsl-0.3.6/docs/pages/driver.tex
vendored
Normal file
166
packages/efsl-0.3.6/docs/pages/driver.tex
vendored
Normal file
@@ -0,0 +1,166 @@
|
||||
\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.
|
||||
45
packages/efsl-0.3.6/docs/pages/efs_init.tex
vendored
Normal file
45
packages/efsl-0.3.6/docs/pages/efs_init.tex
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
\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}
|
||||
43
packages/efsl-0.3.6/docs/pages/file_fclose.tex
vendored
Normal file
43
packages/efsl-0.3.6/docs/pages/file_fclose.tex
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
\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}
|
||||
70
packages/efsl-0.3.6/docs/pages/file_fopen.tex
vendored
Normal file
70
packages/efsl-0.3.6/docs/pages/file_fopen.tex
vendored
Normal file
@@ -0,0 +1,70 @@
|
||||
\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}
|
||||
51
packages/efsl-0.3.6/docs/pages/file_read.tex
vendored
Normal file
51
packages/efsl-0.3.6/docs/pages/file_read.tex
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
\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}
|
||||
52
packages/efsl-0.3.6/docs/pages/file_write.tex
vendored
Normal file
52
packages/efsl-0.3.6/docs/pages/file_write.tex
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
\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}
|
||||
236
packages/efsl-0.3.6/docs/pages/ioman.tex
vendored
Normal file
236
packages/efsl-0.3.6/docs/pages/ioman.tex
vendored
Normal file
@@ -0,0 +1,236 @@
|
||||
\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}
|
||||
|
||||
489
packages/efsl-0.3.6/docs/pages/lgpl.txt
vendored
Normal file
489
packages/efsl-0.3.6/docs/pages/lgpl.txt
vendored
Normal file
@@ -0,0 +1,489 @@
|
||||
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
|
||||
|
||||
12
packages/efsl-0.3.6/docs/pages/license.tex
vendored
Normal file
12
packages/efsl-0.3.6/docs/pages/license.tex
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
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}
|
||||
|
||||
138
packages/efsl-0.3.6/docs/pages/linux.tex
vendored
Normal file
138
packages/efsl-0.3.6/docs/pages/linux.tex
vendored
Normal file
@@ -0,0 +1,138 @@
|
||||
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}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
52
packages/efsl-0.3.6/docs/pages/lsgetnext.tex
vendored
Normal file
52
packages/efsl-0.3.6/docs/pages/lsgetnext.tex
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
\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.
|
||||
42
packages/efsl-0.3.6/docs/pages/lsopendir.tex
vendored
Normal file
42
packages/efsl-0.3.6/docs/pages/lsopendir.tex
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
\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.
|
||||
47
packages/efsl-0.3.6/docs/pages/mkdir.tex
vendored
Normal file
47
packages/efsl-0.3.6/docs/pages/mkdir.tex
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
\subsubsection*{Purpose}
|
||||
Creates a new directory.
|
||||
\subsubsection*{Prototype}
|
||||
\code{esint8 mkdir(FileSystem *fs,eint8* dirname);}
|
||||
\subsubsection*{Arguments}
|
||||
Objects passed to \code{mkdir}:
|
||||
\begin{itemize}
|
||||
\item{\code{fs}: pointer to the FileSystem object}
|
||||
\item{\code{dir}: pointer to the path + name of the new directory}
|
||||
\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 directory already exists.}
|
||||
\item{Returns -2 if the path is incorrect (parent directory does not exists).}
|
||||
\item{Returns -3 if no free space is available to create the directory.}
|
||||
\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;
|
||||
|
||||
/* 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")));
|
||||
|
||||
/* Create new directories */
|
||||
if(mkdir(&efs.myFs,"dir1")==0){
|
||||
mkdir(&efs.myFs,"dir1/subdir1");
|
||||
mkdir(&efs.myFs,"dir1/subdir2");
|
||||
mkdir(&efs.myFs,"dir1/subdir3");
|
||||
}
|
||||
|
||||
/* Close filesystem */
|
||||
fs_umount(&efs.myFs);
|
||||
}
|
||||
\end{lstlisting}
|
||||
62
packages/efsl-0.3.6/docs/pages/plibc.tex
vendored
Normal file
62
packages/efsl-0.3.6/docs/pages/plibc.tex
vendored
Normal file
@@ -0,0 +1,62 @@
|
||||
This section of the manual describes the minimalistic C library functions that were
|
||||
created for EFSL. Since EFSL was designed for ultimate portability, no assumptions about the
|
||||
workings or even the presence of a C library could be made. Fortunately only very few functions
|
||||
had to be created that mimicked the operations of well known C library functions.
|
||||
\\
|
||||
\begin{longtable}{|p{0.35\textwidth}|p{0.65\textwidth}|}
|
||||
|
||||
\hline
|
||||
\multicolumn{2}{|c|}{
|
||||
\textbf{PLibC Functions}
|
||||
} \\
|
||||
\multicolumn{2}{|c|}{} \\
|
||||
\hline
|
||||
\hline
|
||||
\endfirsthead
|
||||
|
||||
\hline
|
||||
\multicolumn{2}{|c|}{\textbf{PLibC Functions (continued)}} \\
|
||||
\hline
|
||||
\endhead
|
||||
|
||||
\hline
|
||||
\endfoot
|
||||
|
||||
\hline
|
||||
\endlastfoot
|
||||
|
||||
\code{strMatch} & \code{euint16 strMatch(eint8* bufa, eint8*bufb,euint32 n)} \\
|
||||
\hline
|
||||
\multicolumn{2}{|p{\textwidth}|}{
|
||||
This function compares the strings \code{bufa} and \code{bufb} for \code{n} bytes.
|
||||
It will return the number of bytes in that section that does not match. So if you
|
||||
want to compare two strings the return value should be 0, for the strings to match over
|
||||
the entire \code{n} area.
|
||||
}\\
|
||||
\hline
|
||||
|
||||
\code{memCpy} & \code{void memCpy(void* psrc, void* pdest, euint32 size)} \\
|
||||
\hline
|
||||
\multicolumn{2}{|p{\textwidth}|}{
|
||||
This function will copy the contents at location \code{psrc} to location \code{pdest} over
|
||||
a range of \code{size} bytes.
|
||||
}\\
|
||||
\hline
|
||||
|
||||
\code{memClr} & \code{void memClr(void *pdest,euint32 size)} \\
|
||||
\hline
|
||||
\multicolumn{2}{|p{\textwidth}|}{
|
||||
This function will set the memory at \code{pdest} to value \code{0x00} for a range of
|
||||
\code{size} bytes.
|
||||
}\\
|
||||
\hline
|
||||
|
||||
\code{memSet} & \code{void memSet(void *pdest,euint32 size,euint8 data)} \\
|
||||
\hline
|
||||
\multicolumn{2}{|p{\textwidth}|}{
|
||||
This function will set the memory at \code{pdest} to value \code{data} for a range of
|
||||
\code{size} bytes.
|
||||
}\\
|
||||
\hline
|
||||
\end{longtable}
|
||||
|
||||
25
packages/efsl-0.3.6/docs/pages/preface.tex
vendored
Normal file
25
packages/efsl-0.3.6/docs/pages/preface.tex
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
\subsection{Project aims}
|
||||
The EFSL project aims to create a library for filesystems, to be used on
|
||||
various embedded systems. Currently we support the Microsoft FAT filesystem
|
||||
family. It is our intention to create pure ANSI C code that compiles on
|
||||
anything that bears the name 'C compiler'. We don't make assumptions about
|
||||
endianness or how the memory alignment is arranged on your architecture.
|
||||
\newline\newline
|
||||
Adding code for your specific hardware is straightforward, just add code that
|
||||
fetches or writes a 512 byte sector, and the library will do the rest.
|
||||
Existing code can be used, writing your own code is only required when you
|
||||
have hardware for which no target exists.
|
||||
\subsection{Project status}
|
||||
Efsl currently supports FAT12, FAT16 and FAT32. Read and write has been tested
|
||||
and is stable. Efsl runs on PC (GNU/Linux, development environment),
|
||||
TMS C6000 DSP's from Texas instruments, and ATMega's from Atmel.
|
||||
You can use this code with as little as 1 kilobyte RAM, however if you have
|
||||
more at your disposal, an infinite amount can be used as cache memory.
|
||||
The more memory you commit, the better the performance will be.
|
||||
\subsection{License}
|
||||
This project is released under the Lesser General Public license, which
|
||||
means that you may use the library and it's sourcecode for any purpose you want,
|
||||
that you may link with it and use it commercially, but that ANY change to the
|
||||
code must be released under the same license. We would appreciate if you would send
|
||||
us a patch when you add support for new hardware, but this is not obligatory, since it
|
||||
falls under linking as far as the LGPL is concerned.
|
||||
98
packages/efsl-0.3.6/docs/pages/tms6713.tex
vendored
Normal file
98
packages/efsl-0.3.6/docs/pages/tms6713.tex
vendored
Normal file
@@ -0,0 +1,98 @@
|
||||
This section will tell you everything you need to know to start using the
|
||||
embedded filesystems library on a TMS Digital Signal Processor from Texas Instruments.
|
||||
The only thing that is required is that you have a McBSP port available, and that your DSP
|
||||
support CLOCKSTOP mode, which is required to connect a SPI compatible device.
|
||||
|
||||
There are special DSP's from TI which have a special MMC/SD card controller, if you want to
|
||||
use this special interface you will have to create a hardware endpoint for it. This section only
|
||||
describes connecting an SD card to a normal McBSP port, since every TI DSP has at least one of them.
|
||||
|
||||
\subsubsection{Hardware}
|
||||
Connecting the SD card to the McBSP is straightforward, you will have to make 4 data related
|
||||
connections, Vcc and ground, resulting in a 6 wire interface.\\
|
||||
\begin{tabular}{|l|l|l|l|l|}
|
||||
\hline
|
||||
\multicolumn{3}{|c|}{SD Card Interface}&\multicolumn{2}{|c|}{McBSP Interface}\\
|
||||
\hline
|
||||
1 & CS & Chip select & FSX & Frame Sync Transmit \\
|
||||
2 & MOSI & Master out Slave In & DX & Data transmit \\
|
||||
3 & GND & Supply Ground &&\\
|
||||
4 & Vcc & Supply voltage (3.3 Volt) &&\\
|
||||
5 & Clk & Clock & CLKX & Clock Transmit\\
|
||||
6 & GND & Supply ground &&\\
|
||||
7 & MISO & Master in Slave out & DR & Data receive \\
|
||||
8 & NC & Not connected &&\\
|
||||
9 & NC & Not connected &&\\
|
||||
\hline
|
||||
\end{tabular}\\
|
||||
You can optionally pull the DataIn and DataOut lines up to Vcc with a $10k\Omega$ resistor, but
|
||||
we found that this was not required for operation.\\
|
||||
\includegraphics[scale=0.4]{schematics/sdcard.eps}\\
|
||||
The frame sync from the McBSP port is used to select the card whenever a databyte has to be transferred, it is connected to the chip select of the SD card. The DX and DR pins are connected to the SDcard's DataIn and DataOut lines respectively. Finally the McBSP will have to generate a clock for
|
||||
the SDcard so that it can perform operations, this is accomplished by connecting the clock transmit
|
||||
line of the McBSP port to the CLK pin of the SDCard.
|
||||
|
||||
\subsubsection{McBSP configuration}
|
||||
\begin{longtable}{|p{0.13\textwidth}|p{0.1\textwidth}|p{0.06\textwidth}|p{0.75\textwidth}|}
|
||||
|
||||
\hline
|
||||
\multicolumn{4}{|c|}{
|
||||
\textbf{McBSP Register Explanations}
|
||||
} \\
|
||||
\hline
|
||||
\hline
|
||||
\endfirsthead
|
||||
|
||||
\hline
|
||||
\multicolumn{4}{|c|}{\textbf{mcbsp registers (continued)}} \\
|
||||
\hline
|
||||
\endhead
|
||||
\hline
|
||||
\endfoot
|
||||
|
||||
\hline
|
||||
\endlastfoot
|
||||
|
||||
\multicolumn{3}{|c|}{SPCR}&
|
||||
\multicolumn{1}{c|}{Serial Port Control Register}\\
|
||||
\hline
|
||||
Name & Bit & Value &\multicolumn{1}{c|}{Value \code{(0x00001800 | 0x00410001)}}\\
|
||||
\hline
|
||||
RRST&\code{0}&\code{1b} & The serial port receiver is enabled \\
|
||||
XRST&\code{16}&\code{1b} & The serial port transmitter is enabled \\
|
||||
CLKSTP&\code{12:11}&\code{11b} & Clock starts on falling edge without delay(see CLKXM) \\
|
||||
GRST&\code{22}&\code{1b} & Sample rate generator is pulled out of reset \\
|
||||
\hline
|
||||
|
||||
\multicolumn{3}{|c|}{PCR}&
|
||||
\multicolumn{1}{c|}{Pin Control Register}\\
|
||||
\hline
|
||||
Name &Bit & Value &\multicolumn{1}{c|}{Value \code{0x00000A0C}}\\
|
||||
\hline
|
||||
CLKXP&\code{1} &\code{0b} & Transmit data on the rising edge ofthe clock\\
|
||||
FSXP&\code{3} &\code{1b} & Frame Sync (Chip select on SD card) is active low\\
|
||||
CLKXM&\code{9} &\code{1b} & McBSP is a master in SPI mode and generates the clock based on
|
||||
the sample rate generator\\
|
||||
FSXM&\code{10} &\code{1b} & Frame sync is determined by tge sample rate generator\\
|
||||
\hline
|
||||
|
||||
\multicolumn{3}{|c|}{RCR/XCR}&
|
||||
\multicolumn{1}{c|}{Receive/Transmit Control Register}\\
|
||||
\hline
|
||||
Name &Bit & Value &\multicolumn{1}{c|}{Value \code{0x00010000}}\\
|
||||
\hline
|
||||
RWDLEN&\code{7:5} &\code{000b} & Receive element is 8 bits (1byte) large\\
|
||||
XDATDLY&\code{17:16} &\code{01b} & 1 bit data delay (after frame sync)\\
|
||||
\hline
|
||||
|
||||
\multicolumn{3}{|c|}{SRGR}&
|
||||
\multicolumn{1}{c|}{Sample Rate Genrator}\\
|
||||
\hline
|
||||
Name &Bit & Value &\multicolumn{1}{c|}{Value \code{0x20000002}}\\
|
||||
\hline
|
||||
CLKSM&\code{29} &\code{1b} & The sample rate generator clock is derived from the internal clock\\
|
||||
FSGM&\code{28} &\code{0b} & The transmit frame sync signal is generated on every DXR to XSR copy\\
|
||||
CLKGDV&\code{7:0}&\code{0x02h} & The clock divider\\
|
||||
\hline
|
||||
|
||||
\end{longtable}
|
||||
26
packages/efsl-0.3.6/docs/pages/types.tex
vendored
Normal file
26
packages/efsl-0.3.6/docs/pages/types.tex
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
Standard C data types have the annoying tendency to have different sizes on difference compilers
|
||||
and platforms. Therefore we have created 9 new types that are used everywhere throughout the library.
|
||||
When you implement your platform you should check if any of the existing one matches your hardware,
|
||||
or create a new one.\\
|
||||
\\
|
||||
Here's an overview:\\\\
|
||||
\begin{tabular}{|p{4cm}|l|l|}
|
||||
\hline
|
||||
\textbf{Type} & \textbf{Size} & \textbf{Signedness}\\
|
||||
\hline
|
||||
\hline
|
||||
\texttt{eint8} & 1 byte & default to platform \\
|
||||
\texttt{esint8} & 1 byte & signed \\
|
||||
\texttt{euint8} & 1 byte & unsigned \\
|
||||
\hline
|
||||
\texttt{eint16} & 2 bytes & default to platform \\
|
||||
\texttt{esint16} & 2 bytes & signed \\
|
||||
\texttt{euint16} & 2 bytes & unsigned \\
|
||||
\hline
|
||||
\texttt{eint32} & 4 bytes & default to platform \\
|
||||
\texttt{esint32} & 4 bytes & signed \\
|
||||
\texttt{euint32} & 4 bytes & unsigned \\
|
||||
\hline
|
||||
\end{tabular}
|
||||
$ $\\\\\\
|
||||
You will find the relevant code in the file \filename{types.h} in the directory \filename{inc/}.
|
||||
3501
packages/efsl-0.3.6/docs/pics/sdcard.eps
vendored
Normal file
3501
packages/efsl-0.3.6/docs/pics/sdcard.eps
vendored
Normal file
File diff suppressed because it is too large
Load Diff
2938
packages/efsl-0.3.6/docs/pics/sdconnection.eps
vendored
Normal file
2938
packages/efsl-0.3.6/docs/pics/sdconnection.eps
vendored
Normal file
File diff suppressed because it is too large
Load Diff
BIN
packages/efsl-0.3.6/docs/schematics/objectmodel.dia
vendored
Normal file
BIN
packages/efsl-0.3.6/docs/schematics/objectmodel.dia
vendored
Normal file
Binary file not shown.
1158
packages/efsl-0.3.6/docs/schematics/objectmodel.eps
vendored
Normal file
1158
packages/efsl-0.3.6/docs/schematics/objectmodel.eps
vendored
Normal file
File diff suppressed because it is too large
Load Diff
BIN
packages/efsl-0.3.6/docs/schematics/sdcard.dia
vendored
Normal file
BIN
packages/efsl-0.3.6/docs/schematics/sdcard.dia
vendored
Normal file
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user