Compare commits
223 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3928f5548e | ||
|
|
b8a45b6a38 | ||
|
|
bc08b4a71a | ||
|
|
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 | ||
|
|
92762d7f51 | ||
|
|
3e3fbe5bc4 | ||
|
|
570323f017 | ||
|
|
d1447db7b0 | ||
|
|
1b45c2f325 | ||
|
|
1539ff6111 | ||
|
|
c5e72c48eb | ||
|
|
82a6edad50 | ||
|
|
553ef0059a | ||
|
|
01e41d36dd | ||
|
|
3a85bb2ee5 | ||
|
|
29fb976051 | ||
|
|
3e988eafe2 | ||
|
|
7f84c8d97a | ||
|
|
1c8c3dc244 | ||
|
|
170ef9f5c6 | ||
|
|
6cab377087 | ||
|
|
8670300642 | ||
|
|
68d4ffc7f1 | ||
|
|
31989233b4 | ||
|
|
b2bf789b85 | ||
|
|
e45b08a5fb | ||
|
|
9e1a9fffc5 | ||
|
|
8bee3f786f | ||
|
|
31687b3094 | ||
|
|
cc2c7ab4dc | ||
|
|
a7270acdf1 | ||
|
|
56713860ac | ||
|
|
fbd05f2863 | ||
|
|
3a794947f0 | ||
|
|
ed16c23002 | ||
|
|
446c3932ae | ||
|
|
8e2889212a | ||
|
|
5a2bba0d33 | ||
|
|
8f0096eb5e | ||
|
|
18c4b45824 | ||
|
|
0f9ebb146e | ||
|
|
d7b82e2503 | ||
|
|
ef14c4dcd8 | ||
|
|
d609954c8b | ||
|
|
05db3108a2 | ||
|
|
a518ff1e1e | ||
|
|
e67e726743 | ||
|
|
ff6e13d8f0 | ||
|
|
935b2a3557 | ||
|
|
2e84cf22d1 | ||
|
|
bcd3d802f0 | ||
|
|
fd1e5d890a | ||
|
|
5cb972e7f6 | ||
|
|
21298fc63f | ||
|
|
f1b89eee83 | ||
|
|
10d435d2f9 | ||
|
|
690bfd6502 | ||
|
|
c55a66f90d | ||
|
|
fef90c7f6e | ||
|
|
8d571d0c55 | ||
|
|
c110d1132a | ||
|
|
30399e2d1c | ||
|
|
78b77a1352 | ||
|
|
b67de0308c | ||
|
|
9d707f612a | ||
|
|
0a62ac52be | ||
|
|
7ef03b498f | ||
|
|
656192fc14 | ||
|
|
77d9418cee | ||
|
|
2ebd2b75aa | ||
|
|
f9724a3209 | ||
|
|
50886c58bd | ||
|
|
6419623018 | ||
|
|
fc785d3ec8 | ||
|
|
cc54fb9f61 | ||
|
|
daae8ef051 | ||
|
|
811b82616e | ||
|
|
8e6c67db08 | ||
|
|
accdf39f18 | ||
|
|
0b12206f1d | ||
|
|
e4e4beac3a | ||
|
|
36d6899692 | ||
|
|
1f6c710e9e | ||
|
|
b7b35800cc | ||
|
|
a9640af2bf | ||
|
|
b6956c8fbd | ||
|
|
d727e978be | ||
|
|
128c27d441 | ||
|
|
08e6710321 | ||
|
|
bc25723df0 | ||
|
|
ce712477fe | ||
|
|
4a0461987b | ||
|
|
8b10ccc7de | ||
|
|
c24d6ceb81 | ||
|
|
1b2b7ecbed | ||
|
|
465ea1fbfe | ||
|
|
b8bd7acfa3 | ||
|
|
6a8e8e4692 | ||
|
|
6b8a6babb7 | ||
|
|
d65a17184f | ||
|
|
b443d3df2f | ||
|
|
4f8e258710 | ||
|
|
c4631f2991 | ||
|
|
f3cc60e77b | ||
|
|
989b738c49 | ||
|
|
0fc0500cc6 | ||
|
|
086f77b551 | ||
|
|
925c54a9c6 | ||
|
|
b2c644b6e7 | ||
|
|
9991dfa249 | ||
|
|
396729e2e2 | ||
|
|
622841e70a | ||
|
|
1100333487 | ||
|
|
4ea1912318 | ||
|
|
c30e626a3f | ||
|
|
66a592eeff | ||
|
|
a4751edf97 | ||
|
|
7bdc299e61 | ||
|
|
8299d3d581 | ||
|
|
483c89c337 | ||
|
|
f832f0f72b | ||
|
|
8e1e5ea072 | ||
|
|
309e1062b9 | ||
|
|
cb0ea4f8c8 | ||
|
|
c1203c3519 | ||
|
|
4a61063406 | ||
|
|
641903c166 | ||
|
|
f5eb151288 | ||
|
|
74e238bdca | ||
|
|
19cc80e70d | ||
|
|
0b9ed151fa | ||
|
|
c1d066ae3c | ||
|
|
78a799d718 | ||
|
|
1ead73684d | ||
|
|
92c4e4d686 | ||
|
|
69182c85b0 | ||
|
|
53e0a0999e | ||
|
|
0a50554f4a | ||
|
|
3ecc61adf4 | ||
|
|
dfcf4016b1 | ||
|
|
515ed6dd27 | ||
|
|
4419128348 | ||
|
|
551ecb1915 | ||
|
|
ae0f35d746 | ||
|
|
4ec2da3a5c | ||
|
|
6b89029105 | ||
|
|
a64e9ebd7d | ||
|
|
6bab776497 | ||
|
|
7b98ebb480 | ||
|
|
2fd08d0df7 | ||
|
|
d69d2bf398 | ||
|
|
a9df4311b4 | ||
|
|
b6c8135749 | ||
|
|
23a5b777ec | ||
|
|
660767c464 | ||
|
|
0fd42d7b1d | ||
|
|
a6aade11c4 | ||
|
|
ce5d1de968 | ||
|
|
c8afff5630 | ||
|
|
efe6ba19c4 | ||
|
|
8929a96e6e | ||
|
|
5dd4904f9c | ||
|
|
aa649c89ee | ||
|
|
ef69ab4ab3 | ||
|
|
1075795ef4 | ||
|
|
c66828729f | ||
|
|
46a566ce14 | ||
|
|
ca2f62ee62 | ||
|
|
48b15ca792 |
15
.gitignore
vendored
15
.gitignore
vendored
@@ -21,3 +21,18 @@
|
|||||||
*.swc
|
*.swc
|
||||||
*.rom
|
*.rom
|
||||||
*.usage
|
*.usage
|
||||||
|
*.moc
|
||||||
|
*.obj
|
||||||
|
*.TMP
|
||||||
|
*.vfat
|
||||||
|
*.wla*
|
||||||
|
*.rcc
|
||||||
|
*.log
|
||||||
|
bootloader
|
||||||
|
snesuploader
|
||||||
|
tmtags
|
||||||
|
bsnes
|
||||||
|
web
|
||||||
|
ucon64.exe
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
[submodule "scripts/webpy"]
|
||||||
|
path = scripts/webpy
|
||||||
|
url = git://github.com/webpy/webpy.git
|
||||||
9
README
9
README
@@ -1 +1,8 @@
|
|||||||
o Test
|
________ .__ __ ________ ____ ________
|
||||||
|
\_____ \ __ __|__| ____ | | __\______ \ _______ _/_ |/ _____/
|
||||||
|
/ / \ \| | \ |/ ___\| |/ / | | \_/ __ \ \/ /| / __ \
|
||||||
|
/ \_/. \ | / \ \___| < | ` \ ___/\ / | \ |__\ \
|
||||||
|
\_____\ \_/____/|__|\___ >__|_ \/_______ /\___ >\_/ |___|\_____ /
|
||||||
|
\__> \/ \/ \/ \/ \/
|
||||||
|
|
||||||
|
www.optixx.org
|
||||||
78
avr/bootloader/Makefile
Normal file
78
avr/bootloader/Makefile
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
|
||||||
|
# microcontroller and project specific settings
|
||||||
|
TARGET = bootloader
|
||||||
|
F_CPU = 20000000UL
|
||||||
|
MCU = atmega644
|
||||||
|
|
||||||
|
SRC = bootloader.c
|
||||||
|
ASRC = usbdrv/usbdrvasm.S interrupts.S
|
||||||
|
OBJECTS += $(patsubst %.c,%.o,${SRC})
|
||||||
|
OBJECTS += $(patsubst %.S,%.o,${ASRC})
|
||||||
|
HEADERS += $(shell echo *.h)
|
||||||
|
# CFLAGS += -Werror
|
||||||
|
|
||||||
|
LDFLAGS += -L/usr/local/avr/avr/lib
|
||||||
|
CFLAGS += -Iusbdrv -I.
|
||||||
|
CFLAGS += -DHARDWARE_REV=$(HARDWARE_REV)
|
||||||
|
CDEFS += -DF_CPU
|
||||||
|
ASFLAGS += -x assembler-with-cpp
|
||||||
|
ASFLAGS += -Iusbdrv -I.
|
||||||
|
|
||||||
|
# use own linkerscript, for special interrupt table handling
|
||||||
|
LDFLAGS += -T ./ldscripts/avr5.x
|
||||||
|
|
||||||
|
# no safe mode checks
|
||||||
|
AVRDUDE_FLAGS += -u
|
||||||
|
|
||||||
|
# set name for dependency-file
|
||||||
|
MAKEFILE = Makefile
|
||||||
|
|
||||||
|
# bootloader section start
|
||||||
|
# (see datasheet)
|
||||||
|
ifeq ($(MCU),atmega168)
|
||||||
|
# atmega168 with 1024 words bootloader:
|
||||||
|
# bootloader section starts at 0x1c00 (word-address) == 0x3800 (byte-address)
|
||||||
|
BOOT_SECTION_START = 0x3800
|
||||||
|
else ifeq ($(MCU),atmega88)
|
||||||
|
# atmega88 with 1024 words bootloader:
|
||||||
|
# bootloader section starts at 0xc00 (word-address) == 0x1800 (byte-address)
|
||||||
|
BOOT_SECTION_START = 0x1800
|
||||||
|
else ifeq ($(MCU),atmega644)
|
||||||
|
# atmega644 with 2048 words bootloader:
|
||||||
|
# bootloader section starts at 0x7800 (word-address) == 0xF000 (byte-address)
|
||||||
|
BOOT_SECTION_START = 0xf000
|
||||||
|
endif
|
||||||
|
|
||||||
|
LDFLAGS += -Wl,--section-start=.text=$(BOOT_SECTION_START) -Wl,-u,vfprintf
|
||||||
|
CFLAGS += -DBOOT_SECTION_START=$(BOOT_SECTION_START)
|
||||||
|
|
||||||
|
|
||||||
|
include avr.mk
|
||||||
|
|
||||||
|
.PHONY: all
|
||||||
|
|
||||||
|
all: $(TARGET).hex $(TARGET).lss
|
||||||
|
@echo "==============================="
|
||||||
|
@echo "$(TARGET) compiled for: $(MCU)"
|
||||||
|
@echo -n "size is: "
|
||||||
|
@$(SIZE) -A $(TARGET).hex | grep "\.sec1" | tr -s " " | cut -d" " -f2
|
||||||
|
@echo "==============================="
|
||||||
|
|
||||||
|
$(TARGET): $(OBJECTS) $(TARGET).o
|
||||||
|
|
||||||
|
%.o: $(HEADERS)
|
||||||
|
|
||||||
|
.PHONY: clean clean-$(TARGET)
|
||||||
|
|
||||||
|
clean: clean-$(TARGET)
|
||||||
|
|
||||||
|
clean-$(TARGET):
|
||||||
|
$(RM) $(TARGET) $(OBJECTS)
|
||||||
|
|
||||||
|
|
||||||
|
.PHONY: depend test
|
||||||
|
|
||||||
|
depend:
|
||||||
|
$(CC) $(CFLAGS) -M $(CDEFS) $(CINCS) $(SRC) >> $(MAKEFILE).dep
|
||||||
|
|
||||||
|
-include $(MAKEFILE).dep
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
# Programmer used for In System Programming
|
# Programmer used for In System Programming
|
||||||
ISP_PROG = dapa
|
ISP_PROG = usbasp
|
||||||
# device the ISP programmer is connected to
|
# device the ISP programmer is connected to
|
||||||
ISP_DEV = /dev/parport0
|
ISP_DEV =
|
||||||
# Programmer used for serial programming (using the bootloader)
|
# Programmer used for serial programming (using the bootloader)
|
||||||
SERIAL_PROG = avr109
|
SERIAL_PROG = avr109
|
||||||
# device the serial programmer is connected to
|
# device the serial programmer is connected to
|
||||||
@@ -15,7 +15,6 @@ AS = avr-as
|
|||||||
CP = cp
|
CP = cp
|
||||||
RM = rm -f
|
RM = rm -f
|
||||||
AVRDUDE = avrdude
|
AVRDUDE = avrdude
|
||||||
AVRDUDE_BAUDRATE = 19200
|
|
||||||
SIZE = avr-size
|
SIZE = avr-size
|
||||||
|
|
||||||
-include $(CURDIR)/config.mk
|
-include $(CURDIR)/config.mk
|
||||||
@@ -33,8 +32,12 @@ endif
|
|||||||
ifeq ($(MCU),atmega168)
|
ifeq ($(MCU),atmega168)
|
||||||
AVRDUDE_MCU=m168
|
AVRDUDE_MCU=m168
|
||||||
endif
|
endif
|
||||||
|
ifeq ($(MCU),atmega644)
|
||||||
|
AVRDUDE_MCU=m644
|
||||||
|
endif
|
||||||
|
|
||||||
AVRDUDE_FLAGS += -p $(AVRDUDE_MCU) -b $(AVRDUDE_BAUDRATE)
|
|
||||||
|
AVRDUDE_FLAGS += -p $(AVRDUDE_MCU)
|
||||||
|
|
||||||
# flags for the compiler
|
# flags for the compiler
|
||||||
CFLAGS += -g -Os -finline-limit=800 -mmcu=$(MCU) -DF_CPU=$(F_CPU) -std=gnu99
|
CFLAGS += -g -Os -finline-limit=800 -mmcu=$(MCU) -DF_CPU=$(F_CPU) -std=gnu99
|
||||||
@@ -62,27 +65,14 @@ $(OBJECTS):
|
|||||||
clean:
|
clean:
|
||||||
$(RM) *.hex *.eep.hex *.o *.lst *.lss
|
$(RM) *.hex *.eep.hex *.o *.lst *.lss
|
||||||
|
|
||||||
interactive-isp:
|
|
||||||
$(AVRDUDE) $(AVRDUDE_FLAGS) -c $(ISP_PROG) -P $(ISP_DEV) -t
|
|
||||||
|
|
||||||
interactive-serial:
|
|
||||||
$(AVRDUDE) $(AVRDUDE_FLAGS) -c $(SERIAL_PROG) -P $(SERIAL_DEV) -t
|
|
||||||
|
|
||||||
|
|
||||||
.PHONY: all clean interactive-isp interactive-serial launch-bootloader
|
.PHONY: all clean interactive-isp interactive-serial launch-bootloader
|
||||||
|
|
||||||
program-isp-%: %.hex
|
flash: bootloader.hex
|
||||||
$(AVRDUDE) $(AVRDUDE_FLAGS) -c $(ISP_PROG) -P $(ISP_DEV) -U flash:w:$<
|
$(AVRDUDE) $(AVRDUDE_FLAGS) -c $(ISP_PROG) -U flash:w:$<
|
||||||
|
|
||||||
program-isp-eeprom-%: %.eep.hex
|
flash-eeprom-%: %.eep.hex
|
||||||
$(AVRDUDE) $(AVRDUDE_FLAGS) -c $(ISP_PROG) -P $(ISP_DEV) -U eeprom:w:$<
|
$(AVRDUDE) $(AVRDUDE_FLAGS) -c $(ISP_PROG) -P $(ISP_DEV) -U eeprom:w:$<
|
||||||
|
|
||||||
program-serial-%: %.hex
|
|
||||||
$(AVRDUDE) $(AVRDUDE_FLAGS) -c $(SERIAL_PROG) -P $(SERIAL_DEV) -U flash:w:$<
|
|
||||||
|
|
||||||
program-serial-eeprom-%: %.eep.hex launch-bootloader
|
|
||||||
$(AVRDUDE) $(AVRDUDE_FLAGS) -c $(SERIAL_PROG) -P $(SERIAL_DEV) -U eeprom:w:$<
|
|
||||||
|
|
||||||
%.hex: %
|
%.hex: %
|
||||||
$(OBJCOPY) -O ihex -R .eeprom $< $@
|
$(OBJCOPY) -O ihex -R .eeprom $< $@
|
||||||
|
|
||||||
@@ -94,6 +84,3 @@ program-serial-eeprom-%: %.eep.hex launch-bootloader
|
|||||||
|
|
||||||
%-size: %.hex
|
%-size: %.hex
|
||||||
$(SIZE) $<
|
$(SIZE) $<
|
||||||
|
|
||||||
launch-bootloader:
|
|
||||||
launch-bootloader $(SERIAL_DEV) $(AVRDUDE_BAUDRATE)
|
|
||||||
538
avr/bootloader/bootloader.c
Normal file
538
avr/bootloader/bootloader.c
Normal file
@@ -0,0 +1,538 @@
|
|||||||
|
/*
|
||||||
|
* =====================================================================================
|
||||||
|
*
|
||||||
|
* ________ .__ __ ________ ____ ________
|
||||||
|
* \_____ \ __ __|__| ____ | | __\______ \ _______ _/_ |/ _____/
|
||||||
|
* / / \ \| | \ |/ ___\| |/ / | | \_/ __ \ \/ /| / __ \
|
||||||
|
* / \_/. \ | / \ \___| < | ` \ ___/\ / | \ |__\ \
|
||||||
|
* \_____\ \_/____/|__|\___ >__|_ \/_______ /\___ >\_/ |___|\_____ /
|
||||||
|
* \__> \/ \/ \/ \/ \/
|
||||||
|
*
|
||||||
|
* www.optixx.org
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Version: 1.0
|
||||||
|
* Created: 07/21/2009 03:32:16 PM
|
||||||
|
* Author: david@optixx.org
|
||||||
|
*
|
||||||
|
* simple USBasp compatible bootloader by
|
||||||
|
* Alexander Neumann <alexander@lochraster.org>
|
||||||
|
* inspired by USBasploader by Christian Starkjohann,
|
||||||
|
* =====================================================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <avr/io.h>
|
||||||
|
#include <avr/interrupt.h>
|
||||||
|
#include <avr/pgmspace.h>
|
||||||
|
#include <avr/boot.h>
|
||||||
|
#include <avr/eeprom.h>
|
||||||
|
#include <util/delay.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <avr/wdt.h>
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
#include "usbdrv/usbdrv.c"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* USBasp requests, taken from the original USBasp sourcecode
|
||||||
|
*/
|
||||||
|
#define USBASP_FUNC_CONNECT 1
|
||||||
|
#define USBASP_FUNC_DISCONNECT 2
|
||||||
|
#define USBASP_FUNC_TRANSMIT 3
|
||||||
|
#define USBASP_FUNC_READFLASH 4
|
||||||
|
#define USBASP_FUNC_ENABLEPROG 5
|
||||||
|
#define USBASP_FUNC_WRITEFLASH 6
|
||||||
|
#define USBASP_FUNC_READEEPROM 7
|
||||||
|
#define USBASP_FUNC_WRITEEEPROM 8
|
||||||
|
#define USBASP_FUNC_SETLONGADDRESS 9
|
||||||
|
|
||||||
|
/*
|
||||||
|
* additional functions
|
||||||
|
*/
|
||||||
|
#define FUNC_ECHO 0x17
|
||||||
|
|
||||||
|
/*
|
||||||
|
* atmel isp commands
|
||||||
|
*/
|
||||||
|
#define ISP_CHIP_ERASE1 0xAC
|
||||||
|
#define ISP_CHIP_ERASE2 0x80
|
||||||
|
#define ISP_READ_SIGNATURE 0x30
|
||||||
|
#define ISP_READ_EEPROM 0xa0
|
||||||
|
#define ISP_WRITE_EEPROM 0xc0
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#define LED_PORT PORTC
|
||||||
|
#define LED_DIR DDRC
|
||||||
|
#define LED_PIN PC7
|
||||||
|
|
||||||
|
#define DLED_ON {((LED_PORT &=~ (1 << LED_PIN)),\
|
||||||
|
(LED_DIR &=~ (1 << LED_PIN))); }
|
||||||
|
#define DLED_OFF {((LED_PORT &=~ (1 << LED_PIN)),\
|
||||||
|
(LED_DIR |= (1 << LED_PIN))); }
|
||||||
|
#define DLED_TGL {((LED_PORT &=~ (1 << LED_PIN)),\
|
||||||
|
(LED_DIR ^= (1 << LED_PIN)));}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* some predefined signatures, taken from the original USBasp sourcecode
|
||||||
|
*/
|
||||||
|
static const uint8_t signature[4] = {
|
||||||
|
#ifdef SIGNATURE_BYTES
|
||||||
|
SIGNATURE_BYTES
|
||||||
|
#elif defined (__AVR_ATmega8__) || defined (__AVR_ATmega8HVA__)
|
||||||
|
0x1e, 0x93, 0x07, 0
|
||||||
|
#elif defined (__AVR_ATmega48__) || defined (__AVR_ATmega48P__)
|
||||||
|
0x1e, 0x92, 0x05, 0
|
||||||
|
#elif defined (__AVR_ATmega88__) || defined (__AVR_ATmega88P__)
|
||||||
|
0x1e, 0x93, 0x0a, 0
|
||||||
|
#elif defined (__AVR_ATmega168__) || defined (__AVR_ATmega168P__)
|
||||||
|
0x1e, 0x94, 0x06, 0
|
||||||
|
#elif defined (__AVR_ATmega328P__)
|
||||||
|
0x1e, 0x95, 0x0f, 0
|
||||||
|
#elif defined (__AVR_ATmega644__)
|
||||||
|
0x1e, 0x96, 0x09, 0
|
||||||
|
#else
|
||||||
|
# error "Device signature is not known, please edit config.h!"
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifndef BOOT_SECTION_START
|
||||||
|
# error "BOOT_SECTION_START undefined!"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined (__AVR_ATmega644__)
|
||||||
|
/*
|
||||||
|
* Due arvdude limitations we can't erase the whole progmem without running into an usb timeount on cleint side. So we we limit the
|
||||||
|
* erase section by 0x1000
|
||||||
|
*/
|
||||||
|
#define ERASE_SECTION 0xe000
|
||||||
|
#else
|
||||||
|
#define ERASE_SECTION BOOT_SECTION_START
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef DEBUG_UART
|
||||||
|
static __attribute__ ((__noinline__))
|
||||||
|
void uart_putc(uint8_t data)
|
||||||
|
{
|
||||||
|
while (!(UCSR0A & _BV(UDRE0)));
|
||||||
|
UDR0 = data;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
#define uart_putc(x)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef DEBUG_UART
|
||||||
|
static __attribute__ ((__noinline__))
|
||||||
|
void uart_puts(uint8_t * data)
|
||||||
|
{
|
||||||
|
while (*data) {
|
||||||
|
uart_putc(*data);
|
||||||
|
data++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
#define uart_puts(x)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* supply custom usbDeviceConnect() and usbDeviceDisconnect() macros which turn the interrupt on and off at the right times, and prevent
|
||||||
|
* the execution of an interrupt while the pullup resistor is switched off
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef USB_CFG_PULLUP_IOPORTNAME
|
||||||
|
#undef usbDeviceConnect
|
||||||
|
#define usbDeviceConnect() do { \
|
||||||
|
USB_PULLUP_DDR |= (1<<USB_CFG_PULLUP_BIT); \
|
||||||
|
USB_PULLUP_OUT |= (1<<USB_CFG_PULLUP_BIT); \
|
||||||
|
USB_INTR_ENABLE |= (1 << USB_INTR_ENABLE_BIT); \
|
||||||
|
} while(0);
|
||||||
|
#undef usbDeviceDisconnect
|
||||||
|
#define usbDeviceDisconnect() do { \
|
||||||
|
USB_INTR_ENABLE &= ~(1 << USB_INTR_ENABLE_BIT); \
|
||||||
|
USB_PULLUP_DDR &= ~(1<<USB_CFG_PULLUP_BIT); \
|
||||||
|
USB_PULLUP_OUT &= ~(1<<USB_CFG_PULLUP_BIT); \
|
||||||
|
} while(0);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* prototypes
|
||||||
|
*/
|
||||||
|
void __attribute__ ((__noreturn__, __noinline__,
|
||||||
|
__naked__)) leave_bootloader(void);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* we just support flash sizes <= 64kb, for code size reasons if you need to program bigger devices, have a look at USBasploader:
|
||||||
|
* http://www.obdev.at/products/avrusb/usbasploader.html
|
||||||
|
*/
|
||||||
|
#if FLASHEND > 0xffff
|
||||||
|
# error "usbload only supports up to 64kb of flash!"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* we are just checking the lower byte of flash_address, so make sure SPM_PAGESIZE is <= 256
|
||||||
|
*/
|
||||||
|
#if SPM_PAGESIZE > 256
|
||||||
|
# error "SPM_PAGESIZE is too big (just checking lower byte)"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* start flash (byte address) read/write at this address
|
||||||
|
*/
|
||||||
|
usbWord_t flash_address;
|
||||||
|
uint8_t bytes_remaining;
|
||||||
|
uint8_t request;
|
||||||
|
uint8_t request_exit;
|
||||||
|
|
||||||
|
uint8_t timeout;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
usbMsgLen_t usbFunctionSetup(uchar data[8])
|
||||||
|
{
|
||||||
|
usbRequest_t *req = (void *) data;
|
||||||
|
uint8_t len = 0;
|
||||||
|
static uint8_t buf[4];
|
||||||
|
|
||||||
|
/*
|
||||||
|
* set global data pointer to local buffer
|
||||||
|
*/
|
||||||
|
usbMsgPtr = buf;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* on enableprog just return one zero, which means success
|
||||||
|
*/
|
||||||
|
if (req->bRequest == USBASP_FUNC_ENABLEPROG) {
|
||||||
|
buf[0] = 0;
|
||||||
|
len = 1;
|
||||||
|
timeout = 255;
|
||||||
|
} else if (req->bRequest == USBASP_FUNC_CONNECT) {
|
||||||
|
/*
|
||||||
|
* turn on led
|
||||||
|
*/
|
||||||
|
DLED_ON;
|
||||||
|
} else if (req->bRequest == USBASP_FUNC_DISCONNECT) {
|
||||||
|
/*
|
||||||
|
* turn off led
|
||||||
|
*/
|
||||||
|
DLED_OFF;
|
||||||
|
request_exit = 1;
|
||||||
|
/*
|
||||||
|
* catch query for the devicecode, chip erase and eeprom byte requests
|
||||||
|
*/
|
||||||
|
} else if (req->bRequest == USBASP_FUNC_TRANSMIT) {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* reset buffer with zeroes
|
||||||
|
*/
|
||||||
|
memset(buf, '\0', sizeof(buf));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* read the address for eeprom operations
|
||||||
|
*/
|
||||||
|
usbWord_t address;
|
||||||
|
address.bytes[0] = data[4]; /* low byte is data[4] */
|
||||||
|
address.bytes[1] = data[3]; /* high byte is data[3] */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* if this is a request to read the device signature, answer with the appropiate signature byte
|
||||||
|
*/
|
||||||
|
if (data[2] == ISP_READ_SIGNATURE) {
|
||||||
|
/*
|
||||||
|
* the complete isp data is reported back to avrdude, but we just need byte 4 bits 0 and 1 of byte 3 determine the signature
|
||||||
|
* byte address
|
||||||
|
*/
|
||||||
|
buf[3] = signature[data[4] & 0x03];
|
||||||
|
|
||||||
|
#ifdef ENABLE_CATCH_EEPROM_ISP
|
||||||
|
/*
|
||||||
|
* catch eeprom read
|
||||||
|
*/
|
||||||
|
} else if (data[2] == ISP_READ_EEPROM) {
|
||||||
|
|
||||||
|
buf[3] = eeprom_read_byte((uint8_t *) address.word);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* catch eeprom write
|
||||||
|
*/
|
||||||
|
} else if (data[2] == ISP_WRITE_EEPROM) {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* address is in data[4], data[3], and databyte is in data[5]
|
||||||
|
*/
|
||||||
|
eeprom_write_byte((uint8_t *) address.word, data[5]);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* catch a chip erase
|
||||||
|
*/
|
||||||
|
} else if (data[2] == ISP_CHIP_ERASE1 && data[3] == ISP_CHIP_ERASE2) {
|
||||||
|
uart_puts("\n\rErase Flash");
|
||||||
|
for (flash_address.word = 0;
|
||||||
|
flash_address.word < ERASE_SECTION;
|
||||||
|
flash_address.word += SPM_PAGESIZE) {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* wait and erase page
|
||||||
|
*/
|
||||||
|
boot_spm_busy_wait();
|
||||||
|
if (flash_address.word && flash_address.word % 1024 == 0)
|
||||||
|
uart_putc('.');
|
||||||
|
cli();
|
||||||
|
boot_page_erase(flash_address.word);
|
||||||
|
sei();
|
||||||
|
}
|
||||||
|
uart_puts("\n\rWrite Flash");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* in case no data has been filled in by the if's above, just return zeroes
|
||||||
|
*/
|
||||||
|
len = 4;
|
||||||
|
|
||||||
|
#ifdef ENABLE_ECHO_FUNC
|
||||||
|
/*
|
||||||
|
* implement a simple echo function, for testing the usb connectivity
|
||||||
|
*/
|
||||||
|
} else if (req->bRequest == FUNC_ECHO) {
|
||||||
|
buf[0] = req->wValue.bytes[0];
|
||||||
|
buf[1] = req->wValue.bytes[1];
|
||||||
|
len = 2;
|
||||||
|
#endif
|
||||||
|
} else if (req->bRequest >= USBASP_FUNC_READFLASH) {
|
||||||
|
/*
|
||||||
|
* && req->bRequest <= USBASP_FUNC_SETLONGADDRESS
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* extract address and length
|
||||||
|
*/
|
||||||
|
flash_address.word = req->wValue.word;
|
||||||
|
bytes_remaining = req->wLength.bytes[0];
|
||||||
|
request = req->bRequest;
|
||||||
|
/*
|
||||||
|
* hand control over to usbFunctionRead()/usbFunctionWrite()
|
||||||
|
*/
|
||||||
|
len = 0xff;
|
||||||
|
}
|
||||||
|
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
uchar usbFunctionWrite(uchar * data, uchar len)
|
||||||
|
{
|
||||||
|
if (len > bytes_remaining)
|
||||||
|
len = bytes_remaining;
|
||||||
|
bytes_remaining -= len;
|
||||||
|
if (request == USBASP_FUNC_WRITEEEPROM) {
|
||||||
|
for (uint8_t i = 0; i < len; i++)
|
||||||
|
eeprom_write_byte((uint8_t *) flash_address.word++, *data++);
|
||||||
|
} else {
|
||||||
|
/*
|
||||||
|
* data is handled wordwise, adjust len
|
||||||
|
*/
|
||||||
|
len /= 2;
|
||||||
|
len -= 1;
|
||||||
|
for (uint8_t i = 0; i <= len; i++) {
|
||||||
|
uint16_t *w = (uint16_t *) data;
|
||||||
|
cli();
|
||||||
|
boot_page_fill(flash_address.word, *w);
|
||||||
|
sei();
|
||||||
|
|
||||||
|
usbWord_t next_address;
|
||||||
|
next_address.word = flash_address.word;
|
||||||
|
next_address.word += 2;
|
||||||
|
data += 2;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* write page if page boundary is crossed or this is the last page
|
||||||
|
*/
|
||||||
|
if (next_address.bytes[0] % SPM_PAGESIZE == 0 ||
|
||||||
|
(bytes_remaining == 0 && i == len)) {
|
||||||
|
cli();
|
||||||
|
boot_page_write(flash_address.word);
|
||||||
|
sei();
|
||||||
|
boot_spm_busy_wait();
|
||||||
|
cli();
|
||||||
|
boot_rww_enable();
|
||||||
|
sei();
|
||||||
|
}
|
||||||
|
|
||||||
|
flash_address.word = next_address.word;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* flash led on activity
|
||||||
|
*/
|
||||||
|
DLED_TGL;
|
||||||
|
|
||||||
|
return (bytes_remaining == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
uchar usbFunctionRead(uchar * data, uchar len)
|
||||||
|
{
|
||||||
|
if (len > bytes_remaining)
|
||||||
|
len = bytes_remaining;
|
||||||
|
bytes_remaining -= len;
|
||||||
|
|
||||||
|
for (uint8_t i = 0; i < len; i++) {
|
||||||
|
if (request == USBASP_FUNC_READEEPROM)
|
||||||
|
*data = eeprom_read_byte((void *) flash_address.word);
|
||||||
|
else
|
||||||
|
*data = pgm_read_byte_near((void *) flash_address.word);
|
||||||
|
data++;
|
||||||
|
flash_address.word++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* flash led on activity
|
||||||
|
*/
|
||||||
|
DLED_TGL;
|
||||||
|
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
void (*jump_to_app) (void) = 0x0000;
|
||||||
|
void leave_bootloader(void)
|
||||||
|
{
|
||||||
|
|
||||||
|
cli();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
wdt_enable(WDTO_15MS);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* let watchdog kick in and reset uC
|
||||||
|
*/
|
||||||
|
while (1);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* start bootloader
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef DEBUG_UART
|
||||||
|
/*
|
||||||
|
* init uart (115200 baud, at 20mhz)
|
||||||
|
*/
|
||||||
|
UBRR0L = 10;
|
||||||
|
UCSR0C = _BV(UCSZ00) | _BV(UCSZ01);
|
||||||
|
UCSR0B = _BV(TXEN0);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
uint8_t reset = MCUSR;
|
||||||
|
uint16_t delay = 0;
|
||||||
|
timeout = TIMEOUT;
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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();
|
||||||
|
uart_puts("Jump to 0x0000\n\r");
|
||||||
|
jump_to_app();
|
||||||
|
}
|
||||||
|
|
||||||
|
banner();
|
||||||
|
uart_puts("Enter programming mode\n\r");
|
||||||
|
/*
|
||||||
|
* else: enter programming mode
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* clear external reset flags
|
||||||
|
*/
|
||||||
|
MCUSR = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* init exit request state
|
||||||
|
*/
|
||||||
|
request_exit = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* move interrupts to boot section
|
||||||
|
*/
|
||||||
|
|
||||||
|
MCUCR = (1 << IVCE);
|
||||||
|
MCUCR = (1 << IVSEL);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* enable interrupts
|
||||||
|
*/
|
||||||
|
sei();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* initialize usb pins
|
||||||
|
*/
|
||||||
|
usbInit();
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* disconnect for ~500ms, so that the host re-enumerates this device
|
||||||
|
*/
|
||||||
|
usbDeviceDisconnect();
|
||||||
|
for (uint8_t i = 0; i < 50; i++)
|
||||||
|
_delay_ms(10); /* 0 means 0x10000, 38*1/f*0x10000 =~ 498ms */
|
||||||
|
usbDeviceConnect();
|
||||||
|
uart_puts("Wait for firmware");
|
||||||
|
while (1) {
|
||||||
|
usbPoll();
|
||||||
|
|
||||||
|
delay++;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* do some led blinking, so that it is visible that the bootloader is still running
|
||||||
|
*/
|
||||||
|
if (delay == 0) {
|
||||||
|
uart_putc('.');
|
||||||
|
DLED_TGL;
|
||||||
|
if (timeout < 255)
|
||||||
|
timeout--;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (request_exit || timeout == 0) {
|
||||||
|
uart_puts("\n\rExit\n\r");
|
||||||
|
_delay_ms(10);
|
||||||
|
leave_bootloader();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -15,4 +15,8 @@
|
|||||||
//#define ENABLE_ECHO_FUNC
|
//#define ENABLE_ECHO_FUNC
|
||||||
|
|
||||||
/* uncomment this for debug information via uart */
|
/* uncomment this for debug information via uart */
|
||||||
//#define DEBUG_UART
|
#define DEBUG_UART
|
||||||
|
|
||||||
|
|
||||||
|
#define DEBUG 1
|
||||||
|
#define DEBUG_USB 2
|
||||||
@@ -42,13 +42,13 @@ the newest features and options.
|
|||||||
|
|
||||||
/* ----------------------- Optional Hardware Config ------------------------ */
|
/* ----------------------- Optional Hardware Config ------------------------ */
|
||||||
|
|
||||||
#define USB_CFG_PULLUP_IOPORTNAME B
|
//#define USB_CFG_PULLUP_IOPORTNAME B
|
||||||
/* If you connect the 1.5k pullup resistor from D- to a port pin instead of
|
/* If you connect the 1.5k pullup resistor from D- to a port pin instead of
|
||||||
* V+, you can connect and disconnect the device from firmware by calling
|
* V+, you can connect and disconnect the device from firmware by calling
|
||||||
* the macros usbDeviceConnect() and usbDeviceDisconnect() (see usbdrv.h).
|
* the macros usbDeviceConnect() and usbDeviceDisconnect() (see usbdrv.h).
|
||||||
* This constant defines the port on which the pullup resistor is connected.
|
* This constant defines the port on which the pullup resistor is connected.
|
||||||
*/
|
*/
|
||||||
#define USB_CFG_PULLUP_BIT 0
|
//#define USB_CFG_PULLUP_BIT 0
|
||||||
/* This constant defines the bit number in USB_CFG_PULLUP_IOPORT (defined
|
/* This constant defines the bit number in USB_CFG_PULLUP_IOPORT (defined
|
||||||
* above) where the 1.5k pullup resistor is connected. See description
|
* above) where the 1.5k pullup resistor is connected. See description
|
||||||
* above for details.
|
* above for details.
|
||||||
108
avr/usbload/Makefile
Normal file
108
avr/usbload/Makefile
Normal file
@@ -0,0 +1,108 @@
|
|||||||
|
# =====================================================================================
|
||||||
|
#
|
||||||
|
# ________ .__ __ ________ ____ ________
|
||||||
|
# \_____ \ __ __|__| ____ | | __\______ \ _______ _/_ |/ _____/
|
||||||
|
# / / \ \| | \ |/ ___\| |/ / | | \_/ __ \ \/ /| / __ \
|
||||||
|
# / \_/. \ | / \ \___| < | ` \ ___/\ / | \ |__\ \
|
||||||
|
# \_____\ \_/____/|__|\___ >__|_ \/_______ /\___ >\_/ |___|\_____ /
|
||||||
|
# \__> \/ \/ \/ \/ \/
|
||||||
|
# www.optixx.org
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# Version: 1.0
|
||||||
|
# Created: 07/21/2009 03:32:16 PM
|
||||||
|
# Author: david@optixx.org
|
||||||
|
# Based on: custom-class, a basic USB example
|
||||||
|
# Author: Christian Starkjohann
|
||||||
|
# =====================================================================================
|
||||||
|
|
||||||
|
DEBUG = 1
|
||||||
|
TTY = /dev/tty.PL2303-00002126
|
||||||
|
DEVICE = atmega644
|
||||||
|
F_CPU = 20000000 # in Hz
|
||||||
|
TARGET = main
|
||||||
|
AVRDUDE = avrdude -c usbasp -p $(DEVICE)
|
||||||
|
SIZE = avr-size
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
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 rle.c loader.o info.o shared_memory.o \
|
||||||
|
irq.o command.o testing.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 command.o irq.o
|
||||||
|
endif
|
||||||
|
|
||||||
|
COMPILE = avr-gcc -Wall -Os -DF_CPU=$(F_CPU) $(CFLAGS) -mmcu=$(DEVICE)
|
||||||
|
|
||||||
|
##############################################################################
|
||||||
|
# Fuse values for particular devices
|
||||||
|
##############################################################################
|
||||||
|
# http://www.engbedded.com/fusecalc/
|
||||||
|
FUSE_L = 0xf7
|
||||||
|
FUSE_H = 0xda
|
||||||
|
|
||||||
|
all: hex
|
||||||
|
|
||||||
|
help:
|
||||||
|
@echo "This Makefile has no default rule. Use one of the following:"
|
||||||
|
@echo "make hex ....... to build main.hex"
|
||||||
|
@echo "make program ... to flash fuses and firmware"
|
||||||
|
@echo "make fuse ...... to flash the fuses"
|
||||||
|
@echo "make flash ..... to flash the firmware (use this on metaboard)"
|
||||||
|
@echo "make clean ..... to delete objects and hex file"
|
||||||
|
|
||||||
|
hex: main.hex
|
||||||
|
@echo "$(TARGET) compiled for: $(DEVICE)"
|
||||||
|
@./checksize $(TARGET).elf
|
||||||
|
|
||||||
|
program: flash fuse
|
||||||
|
|
||||||
|
# rule for programming fuse bits:
|
||||||
|
fuse:
|
||||||
|
@[ "$(FUSE_H)" != "" -a "$(FUSE_L)" != "" ] || \
|
||||||
|
{ echo "*** Edit Makefile and choose values for FUSE_L and FUSE_H!"; exit 1; }
|
||||||
|
$(AVRDUDE) -U hfuse:w:$(FUSE_H):m -U lfuse:w:$(FUSE_L):m
|
||||||
|
|
||||||
|
flash: main.hex
|
||||||
|
$(AVRDUDE) -U flash:w:main.hex:i
|
||||||
|
|
||||||
|
|
||||||
|
.c.o:
|
||||||
|
$(COMPILE) -c $< -o $@
|
||||||
|
|
||||||
|
.S.o:
|
||||||
|
$(COMPILE) -x assembler-with-cpp -c $< -o $@
|
||||||
|
|
||||||
|
.c.s:
|
||||||
|
$(COMPILE) -S $< -o $@
|
||||||
|
|
||||||
|
|
||||||
|
usbdrv:
|
||||||
|
cp -r ../../../usbdrv .
|
||||||
|
|
||||||
|
main.elf: usbdrv $(OBJECTS) # usbdrv dependency only needed because we copy it
|
||||||
|
$(COMPILE) -o main.elf $(OBJECTS) $(LDFLAGS)
|
||||||
|
|
||||||
|
main.hex: main.elf
|
||||||
|
rm -f main.hex main.eep.hex
|
||||||
|
avr-objcopy -j .text -j .data -O ihex main.elf main.hex
|
||||||
|
avr-size main.hex
|
||||||
|
|
||||||
|
disasm: main.elf
|
||||||
|
avr-objdump -d main.elf
|
||||||
|
|
||||||
|
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
|
||||||
35
avr/usbload/checksize
Executable file
35
avr/usbload/checksize
Executable file
@@ -0,0 +1,35 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
# Name: checksize
|
||||||
|
# Project: PowerSwitch/AVR-USB
|
||||||
|
# Author: Christian Starkjohann
|
||||||
|
# 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 $
|
||||||
|
|
||||||
|
error=0
|
||||||
|
codelimit=65536 # default value
|
||||||
|
datalimit=4064 # default value; leave 32 bytes for stack
|
||||||
|
|
||||||
|
if [ $# -gt 1 ]; then
|
||||||
|
codelimit="$2"
|
||||||
|
fi
|
||||||
|
if [ $# -gt 2 ]; then
|
||||||
|
datalimit="$3"
|
||||||
|
fi
|
||||||
|
|
||||||
|
set -- `avr-size -d "$1" | awk '/[0-9]/ {print $1 + $2, $2 + $3, $2}'`
|
||||||
|
if [ $1 -gt $codelimit ]; then
|
||||||
|
echo "*** code size $1 exceeds limit of $codelimit"
|
||||||
|
error=1
|
||||||
|
else
|
||||||
|
echo "ROM: $1 bytes (data=$3)"
|
||||||
|
fi
|
||||||
|
if [ $2 -gt $datalimit ]; then
|
||||||
|
echo "*** data size $2 exceeds limit of $datalimit"
|
||||||
|
error=1
|
||||||
|
else
|
||||||
|
echo "RAM: $2 bytes"
|
||||||
|
fi
|
||||||
|
|
||||||
|
exit $error
|
||||||
65
avr/usbload/command.c
Normal file
65
avr/usbload/command.c
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
/*
|
||||||
|
* =====================================================================================
|
||||||
|
*
|
||||||
|
* ________ .__ __ ________ ____ ________
|
||||||
|
* \_____ \ __ __|__| ____ | | __\______ \ _______ _/_ |/ _____/
|
||||||
|
* / / \ \| | \ |/ ___\| |/ / | | \_/ __ \ \/ /| / __ \
|
||||||
|
* / \_/. \ | / \ \___| < | ` \ ___/\ / | \ |__\ \
|
||||||
|
* \_____\ \_/____/|__|\___ >__|_ \/_______ /\___ >\_/ |___|\_____ /
|
||||||
|
* \__> \/ \/ \/ \/ \/
|
||||||
|
*
|
||||||
|
* 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"
|
||||||
|
|
||||||
|
extern uint32_t req_bank_size;
|
||||||
|
|
||||||
|
|
||||||
|
void send_reset()
|
||||||
|
{
|
||||||
|
info_P(PSTR("Reset SNES\n"));
|
||||||
|
cli();
|
||||||
|
snes_reset_on();
|
||||||
|
snes_reset_lo();
|
||||||
|
_delay_ms(2);
|
||||||
|
snes_reset_hi();
|
||||||
|
snes_reset_off();
|
||||||
|
sei();
|
||||||
|
}
|
||||||
|
|
||||||
|
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_P(PSTR("Set SNES lowrom \n"));
|
||||||
|
} else {
|
||||||
|
snes_hirom();
|
||||||
|
info_P(PSTR("Set SNES hirom \n"));
|
||||||
|
}
|
||||||
|
}
|
||||||
29
avr/usbload/command.h
Normal file
29
avr/usbload/command.h
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
/*
|
||||||
|
* =====================================================================================
|
||||||
|
*
|
||||||
|
* ________ .__ __ ________ ____ ________
|
||||||
|
* \_____ \ __ __|__| ____ | | __\______ \ _______ _/_ |/ _____/
|
||||||
|
* / / \ \| | \ |/ ___\| |/ / | | \_/ __ \ \/ /| / __ \
|
||||||
|
* / \_/. \ | / \ \___| < | ` \ ___/\ / | \ |__\ \
|
||||||
|
* \_____\ \_/____/|__|\___ >__|_ \/_______ /\___ >\_/ |___|\_____ /
|
||||||
|
* \__> \/ \/ \/ \/ \/
|
||||||
|
*
|
||||||
|
* 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 send_reset();
|
||||||
|
void send_irq();
|
||||||
|
void set_rom_mode();
|
||||||
|
|
||||||
|
#endif
|
||||||
48
avr/usbload/commandline/Makefile
Normal file
48
avr/usbload/commandline/Makefile
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
# Name: Makefile
|
||||||
|
# Project: custom-class example
|
||||||
|
# Author: Christian Starkjohann
|
||||||
|
# Creation Date: 2008-04-06
|
||||||
|
# Tabsize: 4
|
||||||
|
# Copyright: (c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH
|
||||||
|
# License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
|
||||||
|
# This Revision: $Id: Makefile 692 2008-11-07 15:07:40Z cs $
|
||||||
|
|
||||||
|
|
||||||
|
# Concigure the following definitions according to your system.
|
||||||
|
# This Makefile has been tested on Mac OS X, Linux and Windows.
|
||||||
|
|
||||||
|
# Use the following 3 lines on Unix (uncomment the framework on Mac OS X):
|
||||||
|
USBFLAGS = `libusb-config --cflags`
|
||||||
|
USBLIBS = `libusb-config --libs`
|
||||||
|
EXE_SUFFIX =
|
||||||
|
|
||||||
|
# Use the following 3 lines on Windows and comment out the 3 above. You may
|
||||||
|
# have to change the include paths to where you installed libusb-win32
|
||||||
|
#USBFLAGS = -I/usr/local/include
|
||||||
|
#USBLIBS = -L/usr/local/lib -lusb
|
||||||
|
#EXE_SUFFIX = .exe
|
||||||
|
|
||||||
|
NAME = snesuploader
|
||||||
|
|
||||||
|
OBJECTS = opendevice.o $(NAME).o
|
||||||
|
|
||||||
|
CC = gcc
|
||||||
|
CFLAGS = $(CPPFLAGS) $(USBFLAGS) -O -g -Wall
|
||||||
|
LIBS = $(USBLIBS)
|
||||||
|
|
||||||
|
PROGRAM = $(NAME)$(EXE_SUFFIX)
|
||||||
|
|
||||||
|
|
||||||
|
all: $(PROGRAM)
|
||||||
|
|
||||||
|
.c.o:
|
||||||
|
$(CC) $(CFLAGS) -c $<
|
||||||
|
|
||||||
|
$(PROGRAM): $(OBJECTS)
|
||||||
|
$(CC) -o $(PROGRAM) $(OBJECTS) $(LIBS)
|
||||||
|
|
||||||
|
strip: $(PROGRAM)
|
||||||
|
strip $(PROGRAM)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f *.o $(PROGRAM)
|
||||||
296
avr/usbload/commandline/opendevice.c
Normal file
296
avr/usbload/commandline/opendevice.c
Normal file
@@ -0,0 +1,296 @@
|
|||||||
|
/*
|
||||||
|
* =====================================================================================
|
||||||
|
*
|
||||||
|
* ________ .__ __ ________ ____ ________
|
||||||
|
* \_____ \ __ __|__| ____ | | __\______ \ _______ _/_ |/ _____/
|
||||||
|
* / / \ \| | \ |/ ___\| |/ / | | \_/ __ \ \/ /| / __ \
|
||||||
|
* / \_/. \ | / \ \___| < | ` \ ___/\ / | \ |__\ \
|
||||||
|
* \_____\ \_/____/|__|\___ >__|_ \/_______ /\___ >\_/ |___|\_____ /
|
||||||
|
* \__> \/ \/ \/ \/ \/
|
||||||
|
*
|
||||||
|
* www.optixx.org
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Version: 1.0
|
||||||
|
* Created: 07/21/2009 03:32:16 PM
|
||||||
|
* Author: david@optixx.org
|
||||||
|
* Based on: custom-class, a basic USB example
|
||||||
|
* Author: Christian Starkjohann
|
||||||
|
* =====================================================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "opendevice.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* -------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define MATCH_SUCCESS 1
|
||||||
|
#define MATCH_FAILED 0
|
||||||
|
#define MATCH_ABORT -1
|
||||||
|
|
||||||
|
/*
|
||||||
|
* private interface: match text and p, return MATCH_SUCCESS, MATCH_FAILED, or
|
||||||
|
* MATCH_ABORT.
|
||||||
|
*/
|
||||||
|
static int _shellStyleMatch(char *text, char *p)
|
||||||
|
{
|
||||||
|
int last,
|
||||||
|
matched,
|
||||||
|
reverse;
|
||||||
|
|
||||||
|
for (; *p; text++, p++) {
|
||||||
|
if (*text == 0 && *p != '*')
|
||||||
|
return MATCH_ABORT;
|
||||||
|
switch (*p) {
|
||||||
|
case '\\':
|
||||||
|
/*
|
||||||
|
* Literal match with following character.
|
||||||
|
*/
|
||||||
|
p++;
|
||||||
|
/*
|
||||||
|
* FALLTHROUGH
|
||||||
|
*/
|
||||||
|
default:
|
||||||
|
if (*text != *p)
|
||||||
|
return MATCH_FAILED;
|
||||||
|
continue;
|
||||||
|
case '?':
|
||||||
|
/*
|
||||||
|
* Match anything.
|
||||||
|
*/
|
||||||
|
continue;
|
||||||
|
case '*':
|
||||||
|
while (*++p == '*')
|
||||||
|
/*
|
||||||
|
* Consecutive stars act just like one.
|
||||||
|
*/
|
||||||
|
continue;
|
||||||
|
if (*p == 0)
|
||||||
|
/*
|
||||||
|
* Trailing star matches everything.
|
||||||
|
*/
|
||||||
|
return MATCH_SUCCESS;
|
||||||
|
while (*text)
|
||||||
|
if ((matched = _shellStyleMatch(text++, p)) != MATCH_FAILED)
|
||||||
|
return matched;
|
||||||
|
return MATCH_ABORT;
|
||||||
|
case '[':
|
||||||
|
reverse = p[1] == '^';
|
||||||
|
if (reverse) /* Inverted character class. */
|
||||||
|
p++;
|
||||||
|
matched = MATCH_FAILED;
|
||||||
|
if (p[1] == ']' || p[1] == '-')
|
||||||
|
if (*++p == *text)
|
||||||
|
matched = MATCH_SUCCESS;
|
||||||
|
for (last = *p; *++p && *p != ']'; last = *p)
|
||||||
|
if (*p == '-' && p[1] != ']' ? *text <= *++p
|
||||||
|
&& *text >= last : *text == *p)
|
||||||
|
matched = MATCH_SUCCESS;
|
||||||
|
if (matched == reverse)
|
||||||
|
return MATCH_FAILED;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return *text == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* public interface for shell style matching: returns 0 if fails, 1 if matches
|
||||||
|
*/
|
||||||
|
static int shellStyleMatch(char *text, char *pattern)
|
||||||
|
{
|
||||||
|
if (pattern == NULL) /* NULL pattern is synonymous to "*" */
|
||||||
|
return 1;
|
||||||
|
return _shellStyleMatch(text, pattern) == MATCH_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* -------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
int usbGetStringAscii(usb_dev_handle * dev, int index, char *buf, int buflen)
|
||||||
|
{
|
||||||
|
char buffer[256];
|
||||||
|
int rval,
|
||||||
|
i;
|
||||||
|
|
||||||
|
if ((rval = usb_get_string_simple(dev, index, buf, buflen)) >= 0) /* use
|
||||||
|
* libusb
|
||||||
|
* version
|
||||||
|
* if
|
||||||
|
* it
|
||||||
|
* works
|
||||||
|
*/
|
||||||
|
return rval;
|
||||||
|
if ((rval =
|
||||||
|
usb_control_msg(dev, USB_ENDPOINT_IN, USB_REQ_GET_DESCRIPTOR,
|
||||||
|
(USB_DT_STRING << 8) + index, 0x0409, buffer,
|
||||||
|
sizeof(buffer), 5000)) < 0)
|
||||||
|
return rval;
|
||||||
|
if (buffer[1] != USB_DT_STRING) {
|
||||||
|
*buf = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if ((unsigned char) buffer[0] < rval)
|
||||||
|
rval = (unsigned char) buffer[0];
|
||||||
|
rval /= 2;
|
||||||
|
/*
|
||||||
|
* lossy conversion to ISO Latin1:
|
||||||
|
*/
|
||||||
|
for (i = 1; i < rval; i++) {
|
||||||
|
if (i > buflen) /* destination buffer overflow */
|
||||||
|
break;
|
||||||
|
buf[i - 1] = buffer[2 * i];
|
||||||
|
if (buffer[2 * i + 1] != 0) /* outside of ISO Latin1 range */
|
||||||
|
buf[i - 1] = '?';
|
||||||
|
}
|
||||||
|
buf[i - 1] = 0;
|
||||||
|
return i - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* -------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
int usbOpenDevice(usb_dev_handle ** device, int vendorID,
|
||||||
|
char *vendorNamePattern, int productID,
|
||||||
|
char *productNamePattern, char *serialNamePattern,
|
||||||
|
FILE * printMatchingDevicesFp, FILE * warningsFp)
|
||||||
|
{
|
||||||
|
struct usb_bus *bus;
|
||||||
|
struct usb_device *dev;
|
||||||
|
usb_dev_handle *handle = NULL;
|
||||||
|
int errorCode = USBOPEN_ERR_NOTFOUND;
|
||||||
|
|
||||||
|
usb_find_busses();
|
||||||
|
usb_find_devices();
|
||||||
|
for (bus = usb_get_busses(); bus; bus = bus->next) {
|
||||||
|
for (dev = bus->devices; dev; dev = dev->next) { /* iterate over
|
||||||
|
* all devices
|
||||||
|
* on all
|
||||||
|
* busses */
|
||||||
|
if ((vendorID == 0 || dev->descriptor.idVendor == vendorID)
|
||||||
|
&& (productID == 0 || dev->descriptor.idProduct == productID)) {
|
||||||
|
char vendor[256],
|
||||||
|
product[256],
|
||||||
|
serial[256];
|
||||||
|
int len;
|
||||||
|
handle = usb_open(dev); /* we need to open the device in order
|
||||||
|
* to query strings */
|
||||||
|
if (!handle) {
|
||||||
|
errorCode = USBOPEN_ERR_ACCESS;
|
||||||
|
if (warningsFp != NULL)
|
||||||
|
fprintf(warningsFp,
|
||||||
|
"Warning: cannot open VID=0x%04x PID=0x%04x: %s\n",
|
||||||
|
dev->descriptor.idVendor,
|
||||||
|
dev->descriptor.idProduct, usb_strerror());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* now check whether the names match:
|
||||||
|
*/
|
||||||
|
len = vendor[0] = 0;
|
||||||
|
if (dev->descriptor.iManufacturer > 0) {
|
||||||
|
len =
|
||||||
|
usbGetStringAscii(handle, dev->descriptor.iManufacturer,
|
||||||
|
vendor, sizeof(vendor));
|
||||||
|
}
|
||||||
|
if (len < 0) {
|
||||||
|
errorCode = USBOPEN_ERR_ACCESS;
|
||||||
|
if (warningsFp != NULL)
|
||||||
|
fprintf(warningsFp,
|
||||||
|
"Warning: cannot query manufacturer for VID=0x%04x PID=0x%04x: %s\n",
|
||||||
|
dev->descriptor.idVendor,
|
||||||
|
dev->descriptor.idProduct, usb_strerror());
|
||||||
|
} else {
|
||||||
|
errorCode = USBOPEN_ERR_NOTFOUND;
|
||||||
|
/*
|
||||||
|
* printf("seen device from vendor ->%s<-\n", vendor);
|
||||||
|
*/
|
||||||
|
if (shellStyleMatch(vendor, vendorNamePattern)) {
|
||||||
|
len = product[0] = 0;
|
||||||
|
if (dev->descriptor.iProduct > 0) {
|
||||||
|
len =
|
||||||
|
usbGetStringAscii(handle,
|
||||||
|
dev->descriptor.iProduct,
|
||||||
|
product, sizeof(product));
|
||||||
|
}
|
||||||
|
if (len < 0) {
|
||||||
|
errorCode = USBOPEN_ERR_ACCESS;
|
||||||
|
if (warningsFp != NULL)
|
||||||
|
fprintf(warningsFp,
|
||||||
|
"Warning: cannot query product for VID=0x%04x PID=0x%04x: %s\n",
|
||||||
|
dev->descriptor.idVendor,
|
||||||
|
dev->descriptor.idProduct,
|
||||||
|
usb_strerror());
|
||||||
|
} else {
|
||||||
|
errorCode = USBOPEN_ERR_NOTFOUND;
|
||||||
|
/*
|
||||||
|
* printf("seen product ->%s<-\n", product);
|
||||||
|
*/
|
||||||
|
if (shellStyleMatch(product, productNamePattern)) {
|
||||||
|
len = serial[0] = 0;
|
||||||
|
if (dev->descriptor.iSerialNumber > 0) {
|
||||||
|
len =
|
||||||
|
usbGetStringAscii(handle,
|
||||||
|
dev->descriptor.
|
||||||
|
iSerialNumber, serial,
|
||||||
|
sizeof(serial));
|
||||||
|
}
|
||||||
|
if (len < 0) {
|
||||||
|
errorCode = USBOPEN_ERR_ACCESS;
|
||||||
|
if (warningsFp != NULL)
|
||||||
|
fprintf(warningsFp,
|
||||||
|
"Warning: cannot query serial for VID=0x%04x PID=0x%04x: %s\n",
|
||||||
|
dev->descriptor.idVendor,
|
||||||
|
dev->descriptor.idProduct,
|
||||||
|
usb_strerror());
|
||||||
|
}
|
||||||
|
if (shellStyleMatch(serial, serialNamePattern)) {
|
||||||
|
if (printMatchingDevicesFp != NULL) {
|
||||||
|
if (serial[0] == 0) {
|
||||||
|
fprintf(printMatchingDevicesFp,
|
||||||
|
"VID=0x%04x PID=0x%04x vendor=\"%s\" product=\"%s\"\n",
|
||||||
|
dev->descriptor.idVendor,
|
||||||
|
dev->descriptor.idProduct,
|
||||||
|
vendor, product);
|
||||||
|
} else {
|
||||||
|
fprintf(printMatchingDevicesFp,
|
||||||
|
"VID=0x%04x PID=0x%04x vendor=\"%s\" product=\"%s\" serial=\"%s\"\n",
|
||||||
|
dev->descriptor.idVendor,
|
||||||
|
dev->descriptor.idProduct,
|
||||||
|
vendor, product, serial);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
usb_close(handle);
|
||||||
|
handle = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (handle) /* we have found a deice */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (handle != NULL) {
|
||||||
|
errorCode = 0;
|
||||||
|
*device = handle;
|
||||||
|
}
|
||||||
|
if (printMatchingDevicesFp != NULL) /* never return an error for listing
|
||||||
|
* only */
|
||||||
|
errorCode = 0;
|
||||||
|
return errorCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* -------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
77
avr/usbload/commandline/opendevice.h
Normal file
77
avr/usbload/commandline/opendevice.h
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
/*
|
||||||
|
* =====================================================================================
|
||||||
|
*
|
||||||
|
* ________ .__ __ ________ ____ ________
|
||||||
|
* \_____ \ __ __|__| ____ | | __\______ \ _______ _/_ |/ _____/
|
||||||
|
* / / \ \| | \ |/ ___\| |/ / | | \_/ __ \ \/ /| / __ \
|
||||||
|
* / \_/. \ | / \ \___| < | ` \ ___/\ / | \ |__\ \
|
||||||
|
* \_____\ \_/____/|__|\___ >__|_ \/_______ /\___ >\_/ |___|\_____ /
|
||||||
|
* \__> \/ \/ \/ \/ \/
|
||||||
|
*
|
||||||
|
* www.optixx.org
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Version: 1.0
|
||||||
|
* Created: 07/21/2009 03:32:16 PM
|
||||||
|
* Author: david@optixx.org
|
||||||
|
* Based on: custom-class, a basic USB example
|
||||||
|
* Author: Christian Starkjohann
|
||||||
|
* =====================================================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef __OPENDEVICE_H_INCLUDED__
|
||||||
|
#define __OPENDEVICE_H_INCLUDED__
|
||||||
|
|
||||||
|
#include <usb.h> /* this is libusb, see http://libusb.sourceforge.net/ */
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
int usbGetStringAscii(usb_dev_handle *dev, int index, char *buf, int buflen);
|
||||||
|
/* This function gets a string descriptor from the device. 'index' is the
|
||||||
|
* string descriptor index. The string is returned in ISO Latin 1 encoding in
|
||||||
|
* 'buf' and it is terminated with a 0-character. The buffer size must be
|
||||||
|
* passed in 'buflen' to prevent buffer overflows. A libusb device handle
|
||||||
|
* must be given in 'dev'.
|
||||||
|
* Returns: The length of the string (excluding the terminating 0) or
|
||||||
|
* a negative number in case of an error. If there was an error, use
|
||||||
|
* usb_strerror() to obtain the error message.
|
||||||
|
*/
|
||||||
|
|
||||||
|
int usbOpenDevice(usb_dev_handle **device, int vendorID, char *vendorNamePattern, int productID, char *productNamePattern, char *serialNamePattern, FILE *printMatchingDevicesFp, FILE *warningsFp);
|
||||||
|
/* This function iterates over all devices on all USB busses and searches for
|
||||||
|
* a device. Matching is done first by means of Vendor- and Product-ID (passed
|
||||||
|
* in 'vendorID' and 'productID'. An ID of 0 matches any numeric ID (wildcard).
|
||||||
|
* When a device matches by its IDs, matching by names is performed. Name
|
||||||
|
* matching can be done on textual vendor name ('vendorNamePattern'), product
|
||||||
|
* name ('productNamePattern') and serial number ('serialNamePattern'). A
|
||||||
|
* device matches only if all non-null pattern match. If you don't care about
|
||||||
|
* a string, pass NULL for the pattern. Patterns are Unix shell style pattern:
|
||||||
|
* '*' stands for 0 or more characters, '?' for one single character, a list
|
||||||
|
* of characters in square brackets for a single character from the list
|
||||||
|
* (dashes are allowed to specify a range) and if the lis of characters begins
|
||||||
|
* with a caret ('^'), it matches one character which is NOT in the list.
|
||||||
|
* Other parameters to the function: If 'warningsFp' is not NULL, warning
|
||||||
|
* messages are printed to this file descriptor with fprintf(). If
|
||||||
|
* 'printMatchingDevicesFp' is not NULL, no device is opened but matching
|
||||||
|
* devices are printed to the given file descriptor with fprintf().
|
||||||
|
* If a device is opened, the resulting USB handle is stored in '*device'. A
|
||||||
|
* pointer to a "usb_dev_handle *" type variable must be passed here.
|
||||||
|
* Returns: 0 on success, an error code (see defines below) on failure.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* usbOpenDevice() error codes: */
|
||||||
|
#define USBOPEN_SUCCESS 0 /* no error */
|
||||||
|
#define USBOPEN_ERR_ACCESS 1 /* not enough permissions to open device */
|
||||||
|
#define USBOPEN_ERR_IO 2 /* I/O error */
|
||||||
|
#define USBOPEN_ERR_NOTFOUND 3 /* device not found */
|
||||||
|
|
||||||
|
|
||||||
|
/* Obdev's free USB IDs, see USBID-License.txt for details */
|
||||||
|
|
||||||
|
#define USB_VID_OBDEV_SHARED 5824 /* obdev's shared vendor ID */
|
||||||
|
#define USB_PID_OBDEV_SHARED_CUSTOM 1500 /* shared PID for custom class devices */
|
||||||
|
#define USB_PID_OBDEV_SHARED_HID 1503 /* shared PID for HIDs except mice & keyboards */
|
||||||
|
#define USB_PID_OBDEV_SHARED_CDCACM 1505 /* shared PID for CDC Modem devices */
|
||||||
|
#define USB_PID_OBDEV_SHARED_MIDI 1508 /* shared PID for MIDI class devices */
|
||||||
|
|
||||||
|
#endif /* __OPENDEVICE_H_INCLUDED__ */
|
||||||
313
avr/usbload/commandline/snesuploader.c
Normal file
313
avr/usbload/commandline/snesuploader.c
Normal file
@@ -0,0 +1,313 @@
|
|||||||
|
/*
|
||||||
|
* =====================================================================================
|
||||||
|
*
|
||||||
|
* ________ .__ __ ________ ____ ________
|
||||||
|
* \_____ \ __ __|__| ____ | | __\______ \ _______ _/_ |/ _____/
|
||||||
|
* / / \ \| | \ |/ ___\| |/ / | | \_/ __ \ \/ /| / __ \
|
||||||
|
* / \_/. \ | / \ \___| < | ` \ ___/\ / | \ |__\ \
|
||||||
|
* \_____\ \_/____/|__|\___ >__|_ \/_______ /\___ >\_/ |___|\_____ /
|
||||||
|
* \__> \/ \/ \/ \/ \/
|
||||||
|
*
|
||||||
|
* www.optixx.org
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Version: 1.0
|
||||||
|
* Created: 07/21/2009 03:32:16 PM
|
||||||
|
* Author: david@optixx.org
|
||||||
|
* Based on: custom-class, a basic USB example
|
||||||
|
* Author: Christian Starkjohann
|
||||||
|
* =====================================================================================
|
||||||
|
*/
|
||||||
|
#define BANK_SIZE_SHIFT 15
|
||||||
|
#define BANK_SIZE (1<<BANK_SIZE_SHIFT)
|
||||||
|
#define READ_BUFFER_SIZE (1<<BANK_SIZE_SHIFT)
|
||||||
|
#define SEND_BUFFER_SIZE 128
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <usb.h> /* this is libusb */
|
||||||
|
|
||||||
|
#include "opendevice.h" /* common code moved to separate module */
|
||||||
|
|
||||||
|
#include "../requests.h" /* custom request numbers */
|
||||||
|
#include "../usbconfig.h" /* device's VID/PID and names */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void dump_packet(uint32_t addr, uint32_t len, uint8_t * packet)
|
||||||
|
{
|
||||||
|
uint16_t i,
|
||||||
|
j;
|
||||||
|
uint16_t sum = 0;
|
||||||
|
uint8_t clear = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < len; i += 16) {
|
||||||
|
|
||||||
|
sum = 0;
|
||||||
|
for (j = 0; j < 16; j++) {
|
||||||
|
sum += packet[i + j];
|
||||||
|
}
|
||||||
|
if (!sum) {
|
||||||
|
clear = 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (clear) {
|
||||||
|
printf("*\n");
|
||||||
|
clear = 0;
|
||||||
|
}
|
||||||
|
printf("%08x:", addr + i);
|
||||||
|
for (j = 0; j < 16; j++) {
|
||||||
|
printf(" %02x", packet[i + j]);
|
||||||
|
}
|
||||||
|
printf(" |");
|
||||||
|
for (j = 0; j < 16; j++) {
|
||||||
|
if (packet[i + j] >= 33 && packet[i + j] <= 126)
|
||||||
|
printf("%c", packet[i + j]);
|
||||||
|
else
|
||||||
|
printf(".");
|
||||||
|
}
|
||||||
|
printf("|\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint16_t crc_xmodem_update(uint16_t crc, uint8_t data)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
crc = crc ^ ((uint16_t) data << 8);
|
||||||
|
for (i = 0; i < 8; i++) {
|
||||||
|
if (crc & 0x8000)
|
||||||
|
crc = (crc << 1) ^ 0x1021;
|
||||||
|
else
|
||||||
|
crc <<= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return crc;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t do_crc(uint8_t * data, uint16_t size)
|
||||||
|
{
|
||||||
|
uint16_t crc = 0;
|
||||||
|
uint16_t i;
|
||||||
|
for (i = 0; i < size; i++) {
|
||||||
|
crc = crc_xmodem_update(crc, data[i]);
|
||||||
|
}
|
||||||
|
return crc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint16_t do_crc_update(uint16_t crc, uint8_t * data, uint16_t size)
|
||||||
|
{
|
||||||
|
uint16_t i;
|
||||||
|
for (i = 0; i < size; i++)
|
||||||
|
crc = crc_xmodem_update(crc, data[i]);
|
||||||
|
return crc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static void usage(char *name)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "usage:\n");
|
||||||
|
fprintf(stderr, " %s upload filename.. upload\n", name);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
usb_dev_handle *handle = NULL;
|
||||||
|
const unsigned char rawVid[2] = { USB_CFG_VENDOR_ID }, rawPid[2] = {
|
||||||
|
USB_CFG_DEVICE_ID};
|
||||||
|
char vendor[] = { USB_CFG_VENDOR_NAME, 0 }, product[] = {
|
||||||
|
USB_CFG_DEVICE_NAME, 0};
|
||||||
|
int cnt, vid, pid;
|
||||||
|
uint8_t *read_buffer;
|
||||||
|
uint8_t *crc_buffer;
|
||||||
|
uint8_t *ptr;
|
||||||
|
|
||||||
|
uint32_t addr = 0;
|
||||||
|
uint16_t addr_lo = 0;
|
||||||
|
uint16_t addr_hi = 0;
|
||||||
|
uint32_t step = 0;
|
||||||
|
uint16_t crc = 0;
|
||||||
|
uint8_t bank = 0;
|
||||||
|
uint8_t bank_cnt = 0;
|
||||||
|
uint32_t file_size = 0;
|
||||||
|
uint32_t file_offset = 0;
|
||||||
|
|
||||||
|
FILE *fp;
|
||||||
|
usb_init();
|
||||||
|
if (argc < 2) { /* we need at least one argument */
|
||||||
|
usage(argv[0]);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* compute VID/PID from usbconfig.h so that there is a central source
|
||||||
|
* of information
|
||||||
|
*/
|
||||||
|
vid = rawVid[1] * 256 + rawVid[0];
|
||||||
|
pid = rawPid[1] * 256 + rawPid[0];
|
||||||
|
/*
|
||||||
|
* The following function is in opendevice.c:
|
||||||
|
*/
|
||||||
|
if (usbOpenDevice(&handle, vid, vendor, pid, product, NULL, NULL, NULL) !=
|
||||||
|
0) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"Could not find USB device \"%s\" with vid=0x%x pid=0x%x\n",
|
||||||
|
product, vid, pid);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
printf("Open USB device \"%s\" with vid=0x%x pid=0x%x\n", product, vid,
|
||||||
|
pid);
|
||||||
|
if (strcasecmp(argv[1], "upload") == 0) {
|
||||||
|
if (argc < 3) { /* we need at least one argument */
|
||||||
|
usage(argv[0]);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
fp = fopen(argv[2], "r");
|
||||||
|
if (fp == NULL) {
|
||||||
|
fprintf(stderr, "Cannot open file %s ", argv[2]);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
fseek (fp, 0, SEEK_END);
|
||||||
|
file_size = ftell (fp);
|
||||||
|
file_offset = 512;
|
||||||
|
if (strstr(argv[2],".smc") || strstr(argv[2],".swc")){
|
||||||
|
printf("Skip 512 Byte header\n");
|
||||||
|
file_size -= 512;
|
||||||
|
|
||||||
|
fseek (fp, 512, SEEK_SET);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
fseek (fp, 0, SEEK_SET);
|
||||||
|
}
|
||||||
|
|
||||||
|
bank_cnt = file_size / BANK_SIZE;
|
||||||
|
printf("Transfer '%s' %i Bytes, %i Banks\n",argv[2],file_size,bank_cnt);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
read_buffer = (unsigned char *) malloc(READ_BUFFER_SIZE);
|
||||||
|
crc_buffer = (unsigned char *) malloc(0x1000);
|
||||||
|
memset(crc_buffer, 0, 0x1000);
|
||||||
|
addr = 0x000000;
|
||||||
|
|
||||||
|
cnt = usb_control_msg(handle,
|
||||||
|
USB_TYPE_VENDOR | USB_RECIP_DEVICE |
|
||||||
|
USB_ENDPOINT_OUT, USB_MODE_AVR, 0, 0, NULL,
|
||||||
|
0, 5000);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
cnt = usb_control_msg(handle,
|
||||||
|
USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_OUT,
|
||||||
|
USB_BULK_UPLOAD_INIT, BANK_SIZE_SHIFT , bank_cnt, NULL, 0, 5000);
|
||||||
|
|
||||||
|
if (cnt < 0) {
|
||||||
|
fprintf(stderr, "USB error: %s\n", usb_strerror());
|
||||||
|
usb_close(handle);
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
ptr = crc_buffer;
|
||||||
|
while ((cnt = fread(read_buffer, READ_BUFFER_SIZE, 1, fp)) > 0) {
|
||||||
|
ptr = crc_buffer;
|
||||||
|
for (step = 0; step < READ_BUFFER_SIZE; step += SEND_BUFFER_SIZE) {
|
||||||
|
|
||||||
|
|
||||||
|
addr_lo = addr & 0xffff;
|
||||||
|
addr_hi = (addr >> 16) & 0x00ff;
|
||||||
|
if (addr == 0x000000){
|
||||||
|
|
||||||
|
cnt = usb_control_msg(handle,
|
||||||
|
USB_TYPE_VENDOR | USB_RECIP_DEVICE |
|
||||||
|
USB_ENDPOINT_OUT, USB_BULK_UPLOAD_ADDR, addr_hi,
|
||||||
|
addr_lo, (char *) read_buffer + step,
|
||||||
|
SEND_BUFFER_SIZE, 5000);
|
||||||
|
} else {
|
||||||
|
|
||||||
|
cnt = usb_control_msg(handle,
|
||||||
|
USB_TYPE_VENDOR | USB_RECIP_DEVICE |
|
||||||
|
USB_ENDPOINT_OUT, USB_BULK_UPLOAD_NEXT, addr_hi,
|
||||||
|
addr_lo, (char *) read_buffer + step,
|
||||||
|
SEND_BUFFER_SIZE, 5000);
|
||||||
|
|
||||||
|
}
|
||||||
|
if (cnt < 0) {
|
||||||
|
fprintf(stderr, "USB error: %s\n", usb_strerror());
|
||||||
|
usb_close(handle);
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(ptr, read_buffer + step, SEND_BUFFER_SIZE);
|
||||||
|
addr += SEND_BUFFER_SIZE;
|
||||||
|
ptr += SEND_BUFFER_SIZE;
|
||||||
|
if ( addr % BANK_SIZE == 0){
|
||||||
|
crc = do_crc(crc_buffer, 0x1000);
|
||||||
|
printf ("bank=0x%02x addr=0x%08x addr=0x%08x crc=0x%04x\n", bank, addr - 0x1000, addr, crc);
|
||||||
|
ptr = crc_buffer;
|
||||||
|
if ( addr % BANK_SIZE == 0) {
|
||||||
|
bank++;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bank = 0;
|
||||||
|
cnt = usb_control_msg(handle,
|
||||||
|
USB_TYPE_VENDOR | USB_RECIP_DEVICE |
|
||||||
|
USB_ENDPOINT_OUT, USB_BULK_UPLOAD_END, 0, 0, NULL,
|
||||||
|
0, 5000);
|
||||||
|
|
||||||
|
|
||||||
|
fseek(fp, file_offset, SEEK_SET);
|
||||||
|
while ((cnt = fread(read_buffer, READ_BUFFER_SIZE, 1, fp)) > 0) {
|
||||||
|
printf ("bank=0x%02x crc=0x%04x\n", bank++,
|
||||||
|
do_crc(read_buffer, READ_BUFFER_SIZE));
|
||||||
|
}
|
||||||
|
fclose(fp);
|
||||||
|
|
||||||
|
cnt = usb_control_msg(handle,
|
||||||
|
USB_TYPE_VENDOR | USB_RECIP_DEVICE |
|
||||||
|
USB_ENDPOINT_OUT, USB_MODE_SNES, 0, 0, NULL,
|
||||||
|
0, 5000);
|
||||||
|
|
||||||
|
|
||||||
|
if (cnt < 1) {
|
||||||
|
if (cnt < 0) {
|
||||||
|
fprintf(stderr, "USB error: %s\n", usb_strerror());
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "only %d bytes received.\n", cnt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (strcasecmp(argv[1], "crc") == 0) {
|
||||||
|
/*
|
||||||
|
* if(argc < 2){ usage(argv[0]); exit(1); }
|
||||||
|
*/
|
||||||
|
addr = 0x000000;
|
||||||
|
addr_lo = addr & 0xffff;
|
||||||
|
addr_hi = (addr >> 16) & 0xff;
|
||||||
|
printf("Request CRC for Addr: 0x%06x\n", addr);
|
||||||
|
|
||||||
|
cnt = usb_control_msg(handle,
|
||||||
|
USB_TYPE_VENDOR | USB_RECIP_DEVICE |
|
||||||
|
USB_ENDPOINT_OUT, USB_CRC_ADDR, addr_hi, addr_lo,
|
||||||
|
NULL, (1 << 15) / 4, 5000);
|
||||||
|
|
||||||
|
if (cnt < 1) {
|
||||||
|
if (cnt < 0) {
|
||||||
|
fprintf(stderr, "USB error: %s\n", usb_strerror());
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "only %d bytes received.\n", cnt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
usage(argv[0]);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
usb_close(handle);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
809
avr/usbload/commandline/snesuploader.ll
Normal file
809
avr/usbload/commandline/snesuploader.ll
Normal file
@@ -0,0 +1,809 @@
|
|||||||
|
; ModuleID = '/Users/david/Devel/arch/avr/code/snesram/poc/avr_usbload/commandline/snesuploader.c'
|
||||||
|
target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128"
|
||||||
|
target triple = "i386-apple-darwin9"
|
||||||
|
%struct.__sFILE = type <{ i8*, i32, i32, i16, i16, %struct.__sbuf, i32, i8*, i32 (i8*)*, i32 (i8*, i8*, i32)*, i64 (i8*, i64, i32)*, i32 (i8*, i8*, i32)*, %struct.__sbuf, %struct.__sFILEX*, i32, [3 x i8], [1 x i8], %struct.__sbuf, i32, i64 }>
|
||||||
|
%struct.__sFILEX = type opaque
|
||||||
|
%struct.__sbuf = type <{ i8*, i32 }>
|
||||||
|
%struct.usb_dev_handle = type opaque
|
||||||
|
@"\01LC" = internal constant [3 x i8] c"*\0A\00" ; <[3 x i8]*> [#uses=1]
|
||||||
|
@"\01LC1" = internal constant [6 x i8] c"%08x:\00" ; <[6 x i8]*> [#uses=1]
|
||||||
|
@"\01LC2" = internal constant [6 x i8] c" %02x\00" ; <[6 x i8]*> [#uses=1]
|
||||||
|
@"\01LC3" = internal constant [3 x i8] c" |\00" ; <[3 x i8]*> [#uses=1]
|
||||||
|
@"\01LC4" = internal constant [3 x i8] c"%c\00" ; <[3 x i8]*> [#uses=1]
|
||||||
|
@"\01LC5" = internal constant [2 x i8] c".\00" ; <[2 x i8]*> [#uses=1]
|
||||||
|
@"\01LC6" = internal constant [3 x i8] c"|\0A\00" ; <[3 x i8]*> [#uses=1]
|
||||||
|
@__stderrp = external global %struct.__sFILE* ; <%struct.__sFILE**> [#uses=8]
|
||||||
|
@"\01LC7" = internal constant [55 x i8] c"Could not find USB device \22%s\22 with vid=0x%x pid=0x%x\0A\00" ; <[55 x i8]*> [#uses=1]
|
||||||
|
@"\01LC8" = internal constant [45 x i8] c"Open USB device \22%s\22 with vid=0x%x pid=0x%x\0A\00" ; <[45 x i8]*> [#uses=1]
|
||||||
|
@"\01LC9" = internal constant [7 x i8] c"upload\00" ; <[7 x i8]*> [#uses=1]
|
||||||
|
@"\01LC10" = internal constant [2 x i8] c"r\00" ; <[2 x i8]*> [#uses=1]
|
||||||
|
@"\01LC11" = internal constant [21 x i8] c"Cannot open file %s \00" ; <[21 x i8]*> [#uses=1]
|
||||||
|
@"\01LC12" = internal constant [70 x i8] c"Addr: 0x%06x Bank: 0x%02x HiAddr: 0x%02x LoAddr: 0x%04x Crc: 0x%04x\0A\00" ; <[70 x i8]*> [#uses=1]
|
||||||
|
@"\01LC13" = internal constant [15 x i8] c"USB error: %s\0A\00" ; <[15 x i8]*> [#uses=1]
|
||||||
|
@"\01LC14" = internal constant [25 x i8] c"only %d bytes received.\0A\00" ; <[25 x i8]*> [#uses=1]
|
||||||
|
@"\01LC15" = internal constant [4 x i8] c"crc\00" ; <[4 x i8]*> [#uses=1]
|
||||||
|
@"\01LC16" = internal constant [30 x i8] c"Request CRC for Addr: 0x%06x\0A\00" ; <[30 x i8]*> [#uses=1]
|
||||||
|
@"\01LC17" = internal constant [8 x i8] c"usage:\0A\00" ; <[8 x i8]*> [#uses=1]
|
||||||
|
@"\01LC18" = internal constant [31 x i8] c" %s upload filename.. upload\0A\00" ; <[31 x i8]*> [#uses=1]
|
||||||
|
|
||||||
|
define void @dump_packet(i32 %addr, i32 %len, i8* %packet) nounwind {
|
||||||
|
entry:
|
||||||
|
%addr.addr = alloca i32 ; <i32*> [#uses=2]
|
||||||
|
%len.addr = alloca i32 ; <i32*> [#uses=2]
|
||||||
|
%packet.addr = alloca i8* ; <i8**> [#uses=6]
|
||||||
|
%i = alloca i16, align 2 ; <i16*> [#uses=10]
|
||||||
|
%j = alloca i16, align 2 ; <i16*> [#uses=17]
|
||||||
|
%sum = alloca i16, align 2 ; <i16*> [#uses=5]
|
||||||
|
%clear = alloca i8, align 1 ; <i8*> [#uses=4]
|
||||||
|
store i32 %addr, i32* %addr.addr
|
||||||
|
store i32 %len, i32* %len.addr
|
||||||
|
store i8* %packet, i8** %packet.addr
|
||||||
|
store i16 0, i16* %sum
|
||||||
|
store i8 0, i8* %clear
|
||||||
|
store i16 0, i16* %i
|
||||||
|
br label %for.cond
|
||||||
|
|
||||||
|
for.cond: ; preds = %for.inc98, %entry
|
||||||
|
%tmp = load i16* %i ; <i16> [#uses=1]
|
||||||
|
%conv = zext i16 %tmp to i32 ; <i32> [#uses=1]
|
||||||
|
%tmp1 = load i32* %len.addr ; <i32> [#uses=1]
|
||||||
|
%cmp = icmp ult i32 %conv, %tmp1 ; <i1> [#uses=1]
|
||||||
|
br i1 %cmp, label %for.body, label %for.end103
|
||||||
|
|
||||||
|
for.body: ; preds = %for.cond
|
||||||
|
store i16 0, i16* %sum
|
||||||
|
store i16 0, i16* %j
|
||||||
|
br label %for.cond3
|
||||||
|
|
||||||
|
for.cond3: ; preds = %for.inc, %for.body
|
||||||
|
%tmp4 = load i16* %j ; <i16> [#uses=1]
|
||||||
|
%conv5 = zext i16 %tmp4 to i32 ; <i32> [#uses=1]
|
||||||
|
%cmp6 = icmp slt i32 %conv5, 16 ; <i1> [#uses=1]
|
||||||
|
br i1 %cmp6, label %for.body8, label %for.end
|
||||||
|
|
||||||
|
for.body8: ; preds = %for.cond3
|
||||||
|
%tmp9 = load i16* %sum ; <i16> [#uses=1]
|
||||||
|
%conv10 = zext i16 %tmp9 to i32 ; <i32> [#uses=1]
|
||||||
|
%tmp11 = load i16* %i ; <i16> [#uses=1]
|
||||||
|
%conv12 = zext i16 %tmp11 to i32 ; <i32> [#uses=1]
|
||||||
|
%tmp13 = load i16* %j ; <i16> [#uses=1]
|
||||||
|
%conv14 = zext i16 %tmp13 to i32 ; <i32> [#uses=1]
|
||||||
|
%add = add i32 %conv12, %conv14 ; <i32> [#uses=1]
|
||||||
|
%tmp15 = load i8** %packet.addr ; <i8*> [#uses=1]
|
||||||
|
%arrayidx = getelementptr i8* %tmp15, i32 %add ; <i8*> [#uses=1]
|
||||||
|
%tmp16 = load i8* %arrayidx ; <i8> [#uses=1]
|
||||||
|
%conv17 = zext i8 %tmp16 to i32 ; <i32> [#uses=1]
|
||||||
|
%add18 = add i32 %conv10, %conv17 ; <i32> [#uses=1]
|
||||||
|
%conv19 = trunc i32 %add18 to i16 ; <i16> [#uses=1]
|
||||||
|
store i16 %conv19, i16* %sum
|
||||||
|
br label %for.inc
|
||||||
|
|
||||||
|
for.inc: ; preds = %for.body8
|
||||||
|
%tmp20 = load i16* %j ; <i16> [#uses=1]
|
||||||
|
%inc = add i16 %tmp20, 1 ; <i16> [#uses=1]
|
||||||
|
store i16 %inc, i16* %j
|
||||||
|
br label %for.cond3
|
||||||
|
|
||||||
|
for.end: ; preds = %for.cond3
|
||||||
|
%tmp21 = load i16* %sum ; <i16> [#uses=1]
|
||||||
|
%tobool = icmp ne i16 %tmp21, 0 ; <i1> [#uses=1]
|
||||||
|
br i1 %tobool, label %if.end, label %if.then
|
||||||
|
|
||||||
|
if.then: ; preds = %for.end
|
||||||
|
store i8 1, i8* %clear
|
||||||
|
br label %for.inc98
|
||||||
|
|
||||||
|
if.end: ; preds = %for.end
|
||||||
|
%tmp22 = load i8* %clear ; <i8> [#uses=1]
|
||||||
|
%tobool23 = icmp ne i8 %tmp22, 0 ; <i1> [#uses=1]
|
||||||
|
br i1 %tobool23, label %if.then24, label %if.end25
|
||||||
|
|
||||||
|
if.then24: ; preds = %if.end
|
||||||
|
%call = call i32 (i8*, ...)* @printf(i8* getelementptr ([3 x i8]* @"\01LC", i32 0, i32 0)) ; <i32> [#uses=0]
|
||||||
|
store i8 0, i8* %clear
|
||||||
|
br label %if.end25
|
||||||
|
|
||||||
|
if.end25: ; preds = %if.then24, %if.end
|
||||||
|
%tmp26 = load i32* %addr.addr ; <i32> [#uses=1]
|
||||||
|
%tmp27 = load i16* %i ; <i16> [#uses=1]
|
||||||
|
%conv28 = zext i16 %tmp27 to i32 ; <i32> [#uses=1]
|
||||||
|
%add29 = add i32 %tmp26, %conv28 ; <i32> [#uses=1]
|
||||||
|
%call30 = call i32 (i8*, ...)* @printf(i8* getelementptr ([6 x i8]* @"\01LC1", i32 0, i32 0), i32 %add29) ; <i32> [#uses=0]
|
||||||
|
store i16 0, i16* %j
|
||||||
|
br label %for.cond31
|
||||||
|
|
||||||
|
for.cond31: ; preds = %for.inc47, %if.end25
|
||||||
|
%tmp32 = load i16* %j ; <i16> [#uses=1]
|
||||||
|
%conv33 = zext i16 %tmp32 to i32 ; <i32> [#uses=1]
|
||||||
|
%cmp34 = icmp slt i32 %conv33, 16 ; <i1> [#uses=1]
|
||||||
|
br i1 %cmp34, label %for.body36, label %for.end50
|
||||||
|
|
||||||
|
for.body36: ; preds = %for.cond31
|
||||||
|
%tmp37 = load i16* %i ; <i16> [#uses=1]
|
||||||
|
%conv38 = zext i16 %tmp37 to i32 ; <i32> [#uses=1]
|
||||||
|
%tmp39 = load i16* %j ; <i16> [#uses=1]
|
||||||
|
%conv40 = zext i16 %tmp39 to i32 ; <i32> [#uses=1]
|
||||||
|
%add41 = add i32 %conv38, %conv40 ; <i32> [#uses=1]
|
||||||
|
%tmp42 = load i8** %packet.addr ; <i8*> [#uses=1]
|
||||||
|
%arrayidx43 = getelementptr i8* %tmp42, i32 %add41 ; <i8*> [#uses=1]
|
||||||
|
%tmp44 = load i8* %arrayidx43 ; <i8> [#uses=1]
|
||||||
|
%conv45 = zext i8 %tmp44 to i32 ; <i32> [#uses=1]
|
||||||
|
%call46 = call i32 (i8*, ...)* @printf(i8* getelementptr ([6 x i8]* @"\01LC2", i32 0, i32 0), i32 %conv45) ; <i32> [#uses=0]
|
||||||
|
br label %for.inc47
|
||||||
|
|
||||||
|
for.inc47: ; preds = %for.body36
|
||||||
|
%tmp48 = load i16* %j ; <i16> [#uses=1]
|
||||||
|
%inc49 = add i16 %tmp48, 1 ; <i16> [#uses=1]
|
||||||
|
store i16 %inc49, i16* %j
|
||||||
|
br label %for.cond31
|
||||||
|
|
||||||
|
for.end50: ; preds = %for.cond31
|
||||||
|
%call51 = call i32 (i8*, ...)* @printf(i8* getelementptr ([3 x i8]* @"\01LC3", i32 0, i32 0)) ; <i32> [#uses=0]
|
||||||
|
store i16 0, i16* %j
|
||||||
|
br label %for.cond52
|
||||||
|
|
||||||
|
for.cond52: ; preds = %for.inc93, %for.end50
|
||||||
|
%tmp53 = load i16* %j ; <i16> [#uses=1]
|
||||||
|
%conv54 = zext i16 %tmp53 to i32 ; <i32> [#uses=1]
|
||||||
|
%cmp55 = icmp slt i32 %conv54, 16 ; <i1> [#uses=1]
|
||||||
|
br i1 %cmp55, label %for.body57, label %for.end96
|
||||||
|
|
||||||
|
for.body57: ; preds = %for.cond52
|
||||||
|
%tmp58 = load i16* %i ; <i16> [#uses=1]
|
||||||
|
%conv59 = zext i16 %tmp58 to i32 ; <i32> [#uses=1]
|
||||||
|
%tmp60 = load i16* %j ; <i16> [#uses=1]
|
||||||
|
%conv61 = zext i16 %tmp60 to i32 ; <i32> [#uses=1]
|
||||||
|
%add62 = add i32 %conv59, %conv61 ; <i32> [#uses=1]
|
||||||
|
%tmp63 = load i8** %packet.addr ; <i8*> [#uses=1]
|
||||||
|
%arrayidx64 = getelementptr i8* %tmp63, i32 %add62 ; <i8*> [#uses=1]
|
||||||
|
%tmp65 = load i8* %arrayidx64 ; <i8> [#uses=1]
|
||||||
|
%conv66 = zext i8 %tmp65 to i32 ; <i32> [#uses=1]
|
||||||
|
%cmp67 = icmp sge i32 %conv66, 33 ; <i1> [#uses=1]
|
||||||
|
br i1 %cmp67, label %land.lhs.true, label %if.else
|
||||||
|
|
||||||
|
land.lhs.true: ; preds = %for.body57
|
||||||
|
%tmp69 = load i16* %i ; <i16> [#uses=1]
|
||||||
|
%conv70 = zext i16 %tmp69 to i32 ; <i32> [#uses=1]
|
||||||
|
%tmp71 = load i16* %j ; <i16> [#uses=1]
|
||||||
|
%conv72 = zext i16 %tmp71 to i32 ; <i32> [#uses=1]
|
||||||
|
%add73 = add i32 %conv70, %conv72 ; <i32> [#uses=1]
|
||||||
|
%tmp74 = load i8** %packet.addr ; <i8*> [#uses=1]
|
||||||
|
%arrayidx75 = getelementptr i8* %tmp74, i32 %add73 ; <i8*> [#uses=1]
|
||||||
|
%tmp76 = load i8* %arrayidx75 ; <i8> [#uses=1]
|
||||||
|
%conv77 = zext i8 %tmp76 to i32 ; <i32> [#uses=1]
|
||||||
|
%cmp78 = icmp sle i32 %conv77, 126 ; <i1> [#uses=1]
|
||||||
|
br i1 %cmp78, label %if.then80, label %if.else
|
||||||
|
|
||||||
|
if.then80: ; preds = %land.lhs.true
|
||||||
|
%tmp81 = load i16* %i ; <i16> [#uses=1]
|
||||||
|
%conv82 = zext i16 %tmp81 to i32 ; <i32> [#uses=1]
|
||||||
|
%tmp83 = load i16* %j ; <i16> [#uses=1]
|
||||||
|
%conv84 = zext i16 %tmp83 to i32 ; <i32> [#uses=1]
|
||||||
|
%add85 = add i32 %conv82, %conv84 ; <i32> [#uses=1]
|
||||||
|
%tmp86 = load i8** %packet.addr ; <i8*> [#uses=1]
|
||||||
|
%arrayidx87 = getelementptr i8* %tmp86, i32 %add85 ; <i8*> [#uses=1]
|
||||||
|
%tmp88 = load i8* %arrayidx87 ; <i8> [#uses=1]
|
||||||
|
%conv89 = zext i8 %tmp88 to i32 ; <i32> [#uses=1]
|
||||||
|
%call90 = call i32 (i8*, ...)* @printf(i8* getelementptr ([3 x i8]* @"\01LC4", i32 0, i32 0), i32 %conv89) ; <i32> [#uses=0]
|
||||||
|
br label %if.end92
|
||||||
|
|
||||||
|
if.else: ; preds = %land.lhs.true, %for.body57
|
||||||
|
%call91 = call i32 (i8*, ...)* @printf(i8* getelementptr ([2 x i8]* @"\01LC5", i32 0, i32 0)) ; <i32> [#uses=0]
|
||||||
|
br label %if.end92
|
||||||
|
|
||||||
|
if.end92: ; preds = %if.else, %if.then80
|
||||||
|
br label %for.inc93
|
||||||
|
|
||||||
|
for.inc93: ; preds = %if.end92
|
||||||
|
%tmp94 = load i16* %j ; <i16> [#uses=1]
|
||||||
|
%inc95 = add i16 %tmp94, 1 ; <i16> [#uses=1]
|
||||||
|
store i16 %inc95, i16* %j
|
||||||
|
br label %for.cond52
|
||||||
|
|
||||||
|
for.end96: ; preds = %for.cond52
|
||||||
|
%call97 = call i32 (i8*, ...)* @printf(i8* getelementptr ([3 x i8]* @"\01LC6", i32 0, i32 0)) ; <i32> [#uses=0]
|
||||||
|
br label %for.inc98
|
||||||
|
|
||||||
|
for.inc98: ; preds = %for.end96, %if.then
|
||||||
|
%tmp99 = load i16* %i ; <i16> [#uses=1]
|
||||||
|
%conv100 = zext i16 %tmp99 to i32 ; <i32> [#uses=1]
|
||||||
|
%add101 = add i32 %conv100, 16 ; <i32> [#uses=1]
|
||||||
|
%conv102 = trunc i32 %add101 to i16 ; <i16> [#uses=1]
|
||||||
|
store i16 %conv102, i16* %i
|
||||||
|
br label %for.cond
|
||||||
|
|
||||||
|
for.end103: ; preds = %for.cond
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
|
||||||
|
declare i32 @printf(i8*, ...)
|
||||||
|
|
||||||
|
define zeroext i16 @crc_xmodem_update(i16 zeroext %crc, i8 zeroext %data) nounwind {
|
||||||
|
entry:
|
||||||
|
%retval = alloca i16 ; <i16*> [#uses=2]
|
||||||
|
%crc.addr = alloca i16 ; <i16*> [#uses=9]
|
||||||
|
%data.addr = alloca i8 ; <i8*> [#uses=2]
|
||||||
|
%i = alloca i32, align 4 ; <i32*> [#uses=4]
|
||||||
|
store i16 %crc, i16* %crc.addr
|
||||||
|
store i8 %data, i8* %data.addr
|
||||||
|
%tmp = load i16* %crc.addr ; <i16> [#uses=1]
|
||||||
|
%conv = zext i16 %tmp to i32 ; <i32> [#uses=1]
|
||||||
|
%tmp1 = load i8* %data.addr ; <i8> [#uses=1]
|
||||||
|
%conv2 = zext i8 %tmp1 to i32 ; <i32> [#uses=1]
|
||||||
|
%conv3 = trunc i32 %conv2 to i16 ; <i16> [#uses=1]
|
||||||
|
%conv4 = zext i16 %conv3 to i32 ; <i32> [#uses=1]
|
||||||
|
%shl = shl i32 %conv4, 8 ; <i32> [#uses=1]
|
||||||
|
%xor = xor i32 %conv, %shl ; <i32> [#uses=1]
|
||||||
|
%conv5 = trunc i32 %xor to i16 ; <i16> [#uses=1]
|
||||||
|
store i16 %conv5, i16* %crc.addr
|
||||||
|
store i32 0, i32* %i
|
||||||
|
br label %for.cond
|
||||||
|
|
||||||
|
for.cond: ; preds = %for.inc, %entry
|
||||||
|
%tmp6 = load i32* %i ; <i32> [#uses=1]
|
||||||
|
%cmp = icmp slt i32 %tmp6, 8 ; <i1> [#uses=1]
|
||||||
|
br i1 %cmp, label %for.body, label %for.end
|
||||||
|
|
||||||
|
for.body: ; preds = %for.cond
|
||||||
|
%tmp8 = load i16* %crc.addr ; <i16> [#uses=1]
|
||||||
|
%conv9 = zext i16 %tmp8 to i32 ; <i32> [#uses=1]
|
||||||
|
%and = and i32 %conv9, 32768 ; <i32> [#uses=1]
|
||||||
|
%tobool = icmp ne i32 %and, 0 ; <i1> [#uses=1]
|
||||||
|
br i1 %tobool, label %if.then, label %if.else
|
||||||
|
|
||||||
|
if.then: ; preds = %for.body
|
||||||
|
%tmp10 = load i16* %crc.addr ; <i16> [#uses=1]
|
||||||
|
%conv11 = zext i16 %tmp10 to i32 ; <i32> [#uses=1]
|
||||||
|
%shl12 = shl i32 %conv11, 1 ; <i32> [#uses=1]
|
||||||
|
%xor13 = xor i32 %shl12, 4129 ; <i32> [#uses=1]
|
||||||
|
%conv14 = trunc i32 %xor13 to i16 ; <i16> [#uses=1]
|
||||||
|
store i16 %conv14, i16* %crc.addr
|
||||||
|
br label %if.end
|
||||||
|
|
||||||
|
if.else: ; preds = %for.body
|
||||||
|
%tmp15 = load i16* %crc.addr ; <i16> [#uses=1]
|
||||||
|
%conv16 = zext i16 %tmp15 to i32 ; <i32> [#uses=1]
|
||||||
|
%shl17 = shl i32 %conv16, 1 ; <i32> [#uses=1]
|
||||||
|
%conv18 = trunc i32 %shl17 to i16 ; <i16> [#uses=1]
|
||||||
|
store i16 %conv18, i16* %crc.addr
|
||||||
|
br label %if.end
|
||||||
|
|
||||||
|
if.end: ; preds = %if.else, %if.then
|
||||||
|
br label %for.inc
|
||||||
|
|
||||||
|
for.inc: ; preds = %if.end
|
||||||
|
%tmp19 = load i32* %i ; <i32> [#uses=1]
|
||||||
|
%inc = add i32 %tmp19, 1 ; <i32> [#uses=1]
|
||||||
|
store i32 %inc, i32* %i
|
||||||
|
br label %for.cond
|
||||||
|
|
||||||
|
for.end: ; preds = %for.cond
|
||||||
|
%tmp20 = load i16* %crc.addr ; <i16> [#uses=1]
|
||||||
|
store i16 %tmp20, i16* %retval
|
||||||
|
%0 = load i16* %retval ; <i16> [#uses=1]
|
||||||
|
ret i16 %0
|
||||||
|
}
|
||||||
|
|
||||||
|
define zeroext i16 @do_crc(i8* %data, i16 zeroext %size) nounwind {
|
||||||
|
entry:
|
||||||
|
%retval = alloca i16 ; <i16*> [#uses=2]
|
||||||
|
%data.addr = alloca i8* ; <i8**> [#uses=2]
|
||||||
|
%size.addr = alloca i16 ; <i16*> [#uses=2]
|
||||||
|
%crc = alloca i16, align 2 ; <i16*> [#uses=4]
|
||||||
|
%i = alloca i16, align 2 ; <i16*> [#uses=5]
|
||||||
|
store i8* %data, i8** %data.addr
|
||||||
|
store i16 %size, i16* %size.addr
|
||||||
|
store i16 0, i16* %crc
|
||||||
|
store i16 0, i16* %i
|
||||||
|
br label %for.cond
|
||||||
|
|
||||||
|
for.cond: ; preds = %for.inc, %entry
|
||||||
|
%tmp = load i16* %i ; <i16> [#uses=1]
|
||||||
|
%conv = zext i16 %tmp to i32 ; <i32> [#uses=1]
|
||||||
|
%tmp1 = load i16* %size.addr ; <i16> [#uses=1]
|
||||||
|
%conv2 = zext i16 %tmp1 to i32 ; <i32> [#uses=1]
|
||||||
|
%cmp = icmp slt i32 %conv, %conv2 ; <i1> [#uses=1]
|
||||||
|
br i1 %cmp, label %for.body, label %for.end
|
||||||
|
|
||||||
|
for.body: ; preds = %for.cond
|
||||||
|
%tmp4 = load i16* %crc ; <i16> [#uses=1]
|
||||||
|
%tmp5 = load i16* %i ; <i16> [#uses=1]
|
||||||
|
%tmp6 = load i8** %data.addr ; <i8*> [#uses=1]
|
||||||
|
%idxprom = zext i16 %tmp5 to i32 ; <i32> [#uses=1]
|
||||||
|
%arrayidx = getelementptr i8* %tmp6, i32 %idxprom ; <i8*> [#uses=1]
|
||||||
|
%tmp7 = load i8* %arrayidx ; <i8> [#uses=1]
|
||||||
|
%call = call zeroext i16 @crc_xmodem_update(i16 zeroext %tmp4, i8 zeroext %tmp7) ; <i16> [#uses=1]
|
||||||
|
store i16 %call, i16* %crc
|
||||||
|
br label %for.inc
|
||||||
|
|
||||||
|
for.inc: ; preds = %for.body
|
||||||
|
%tmp8 = load i16* %i ; <i16> [#uses=1]
|
||||||
|
%inc = add i16 %tmp8, 1 ; <i16> [#uses=1]
|
||||||
|
store i16 %inc, i16* %i
|
||||||
|
br label %for.cond
|
||||||
|
|
||||||
|
for.end: ; preds = %for.cond
|
||||||
|
%tmp9 = load i16* %crc ; <i16> [#uses=1]
|
||||||
|
store i16 %tmp9, i16* %retval
|
||||||
|
%0 = load i16* %retval ; <i16> [#uses=1]
|
||||||
|
ret i16 %0
|
||||||
|
}
|
||||||
|
|
||||||
|
define zeroext i16 @do_crc_update(i16 zeroext %crc, i8* %data, i16 zeroext %size) nounwind {
|
||||||
|
entry:
|
||||||
|
%retval = alloca i16 ; <i16*> [#uses=2]
|
||||||
|
%crc.addr = alloca i16 ; <i16*> [#uses=4]
|
||||||
|
%data.addr = alloca i8* ; <i8**> [#uses=2]
|
||||||
|
%size.addr = alloca i16 ; <i16*> [#uses=2]
|
||||||
|
%i = alloca i16, align 2 ; <i16*> [#uses=5]
|
||||||
|
store i16 %crc, i16* %crc.addr
|
||||||
|
store i8* %data, i8** %data.addr
|
||||||
|
store i16 %size, i16* %size.addr
|
||||||
|
store i16 0, i16* %i
|
||||||
|
br label %for.cond
|
||||||
|
|
||||||
|
for.cond: ; preds = %for.inc, %entry
|
||||||
|
%tmp = load i16* %i ; <i16> [#uses=1]
|
||||||
|
%conv = zext i16 %tmp to i32 ; <i32> [#uses=1]
|
||||||
|
%tmp1 = load i16* %size.addr ; <i16> [#uses=1]
|
||||||
|
%conv2 = zext i16 %tmp1 to i32 ; <i32> [#uses=1]
|
||||||
|
%cmp = icmp slt i32 %conv, %conv2 ; <i1> [#uses=1]
|
||||||
|
br i1 %cmp, label %for.body, label %for.end
|
||||||
|
|
||||||
|
for.body: ; preds = %for.cond
|
||||||
|
%tmp4 = load i16* %crc.addr ; <i16> [#uses=1]
|
||||||
|
%tmp5 = load i16* %i ; <i16> [#uses=1]
|
||||||
|
%tmp6 = load i8** %data.addr ; <i8*> [#uses=1]
|
||||||
|
%idxprom = zext i16 %tmp5 to i32 ; <i32> [#uses=1]
|
||||||
|
%arrayidx = getelementptr i8* %tmp6, i32 %idxprom ; <i8*> [#uses=1]
|
||||||
|
%tmp7 = load i8* %arrayidx ; <i8> [#uses=1]
|
||||||
|
%call = call zeroext i16 @crc_xmodem_update(i16 zeroext %tmp4, i8 zeroext %tmp7) ; <i16> [#uses=1]
|
||||||
|
store i16 %call, i16* %crc.addr
|
||||||
|
br label %for.inc
|
||||||
|
|
||||||
|
for.inc: ; preds = %for.body
|
||||||
|
%tmp8 = load i16* %i ; <i16> [#uses=1]
|
||||||
|
%inc = add i16 %tmp8, 1 ; <i16> [#uses=1]
|
||||||
|
store i16 %inc, i16* %i
|
||||||
|
br label %for.cond
|
||||||
|
|
||||||
|
for.end: ; preds = %for.cond
|
||||||
|
%tmp9 = load i16* %crc.addr ; <i16> [#uses=1]
|
||||||
|
store i16 %tmp9, i16* %retval
|
||||||
|
%0 = load i16* %retval ; <i16> [#uses=1]
|
||||||
|
ret i16 %0
|
||||||
|
}
|
||||||
|
|
||||||
|
define i32 @main(i32 %argc, i8** %argv) nounwind {
|
||||||
|
entry:
|
||||||
|
%retval = alloca i32 ; <i32*> [#uses=2]
|
||||||
|
%argc.addr = alloca i32 ; <i32*> [#uses=3]
|
||||||
|
%argv.addr = alloca i8** ; <i8***> [#uses=8]
|
||||||
|
%handle = alloca %struct.usb_dev_handle*, align 4 ; <%struct.usb_dev_handle**> [#uses=7]
|
||||||
|
%rawVid = alloca [2 x i8], align 1 ; <[2 x i8]*> [#uses=4]
|
||||||
|
%rawPid = alloca [2 x i8], align 1 ; <[2 x i8]*> [#uses=4]
|
||||||
|
%vendor = alloca [11 x i8], align 1 ; <[11 x i8]*> [#uses=12]
|
||||||
|
%product = alloca [8 x i8], align 1 ; <[8 x i8]*> [#uses=11]
|
||||||
|
%cnt = alloca i32, align 4 ; <i32*> [#uses=9]
|
||||||
|
%vid = alloca i32, align 4 ; <i32*> [#uses=4]
|
||||||
|
%pid = alloca i32, align 4 ; <i32*> [#uses=4]
|
||||||
|
%cnt_crc = alloca i32, align 4 ; <i32*> [#uses=6]
|
||||||
|
%read_buffer = alloca i8*, align 4 ; <i8**> [#uses=4]
|
||||||
|
%crc_buffer = alloca i8*, align 4 ; <i8**> [#uses=5]
|
||||||
|
%addr = alloca i32, align 4 ; <i32*> [#uses=11]
|
||||||
|
%addr_lo = alloca i16, align 2 ; <i16*> [#uses=7]
|
||||||
|
%addr_hi = alloca i16, align 2 ; <i16*> [#uses=7]
|
||||||
|
%step = alloca i16, align 2 ; <i16*> [#uses=6]
|
||||||
|
%crc = alloca i16, align 2 ; <i16*> [#uses=3]
|
||||||
|
%bank = alloca i8, align 1 ; <i8*> [#uses=4]
|
||||||
|
%fp = alloca %struct.__sFILE*, align 4 ; <%struct.__sFILE**> [#uses=3]
|
||||||
|
store i32 %argc, i32* %argc.addr
|
||||||
|
store i8** %argv, i8*** %argv.addr
|
||||||
|
store %struct.usb_dev_handle* null, %struct.usb_dev_handle** %handle
|
||||||
|
%.array = getelementptr [2 x i8]* %rawVid, i32 0, i32 0 ; <i8*> [#uses=1]
|
||||||
|
store i8 -64, i8* %.array
|
||||||
|
%.array1 = getelementptr [2 x i8]* %rawVid, i32 0, i32 1 ; <i8*> [#uses=1]
|
||||||
|
store i8 22, i8* %.array1
|
||||||
|
%.array2 = getelementptr [2 x i8]* %rawPid, i32 0, i32 0 ; <i8*> [#uses=1]
|
||||||
|
store i8 -36, i8* %.array2
|
||||||
|
%.array3 = getelementptr [2 x i8]* %rawPid, i32 0, i32 1 ; <i8*> [#uses=1]
|
||||||
|
store i8 5, i8* %.array3
|
||||||
|
%.array4 = getelementptr [11 x i8]* %vendor, i32 0, i32 0 ; <i8*> [#uses=1]
|
||||||
|
store i8 111, i8* %.array4
|
||||||
|
%.array5 = getelementptr [11 x i8]* %vendor, i32 0, i32 1 ; <i8*> [#uses=1]
|
||||||
|
store i8 112, i8* %.array5
|
||||||
|
%.array6 = getelementptr [11 x i8]* %vendor, i32 0, i32 2 ; <i8*> [#uses=1]
|
||||||
|
store i8 116, i8* %.array6
|
||||||
|
%.array7 = getelementptr [11 x i8]* %vendor, i32 0, i32 3 ; <i8*> [#uses=1]
|
||||||
|
store i8 105, i8* %.array7
|
||||||
|
%.array8 = getelementptr [11 x i8]* %vendor, i32 0, i32 4 ; <i8*> [#uses=1]
|
||||||
|
store i8 120, i8* %.array8
|
||||||
|
%.array9 = getelementptr [11 x i8]* %vendor, i32 0, i32 5 ; <i8*> [#uses=1]
|
||||||
|
store i8 120, i8* %.array9
|
||||||
|
%.array10 = getelementptr [11 x i8]* %vendor, i32 0, i32 6 ; <i8*> [#uses=1]
|
||||||
|
store i8 46, i8* %.array10
|
||||||
|
%.array11 = getelementptr [11 x i8]* %vendor, i32 0, i32 7 ; <i8*> [#uses=1]
|
||||||
|
store i8 111, i8* %.array11
|
||||||
|
%.array12 = getelementptr [11 x i8]* %vendor, i32 0, i32 8 ; <i8*> [#uses=1]
|
||||||
|
store i8 114, i8* %.array12
|
||||||
|
%.array13 = getelementptr [11 x i8]* %vendor, i32 0, i32 9 ; <i8*> [#uses=1]
|
||||||
|
store i8 103, i8* %.array13
|
||||||
|
%.array14 = getelementptr [11 x i8]* %vendor, i32 0, i32 10 ; <i8*> [#uses=1]
|
||||||
|
store i8 0, i8* %.array14
|
||||||
|
%.array15 = getelementptr [8 x i8]* %product, i32 0, i32 0 ; <i8*> [#uses=1]
|
||||||
|
store i8 83, i8* %.array15
|
||||||
|
%.array16 = getelementptr [8 x i8]* %product, i32 0, i32 1 ; <i8*> [#uses=1]
|
||||||
|
store i8 78, i8* %.array16
|
||||||
|
%.array17 = getelementptr [8 x i8]* %product, i32 0, i32 2 ; <i8*> [#uses=1]
|
||||||
|
store i8 69, i8* %.array17
|
||||||
|
%.array18 = getelementptr [8 x i8]* %product, i32 0, i32 3 ; <i8*> [#uses=1]
|
||||||
|
store i8 83, i8* %.array18
|
||||||
|
%.array19 = getelementptr [8 x i8]* %product, i32 0, i32 4 ; <i8*> [#uses=1]
|
||||||
|
store i8 82, i8* %.array19
|
||||||
|
%.array20 = getelementptr [8 x i8]* %product, i32 0, i32 5 ; <i8*> [#uses=1]
|
||||||
|
store i8 65, i8* %.array20
|
||||||
|
%.array21 = getelementptr [8 x i8]* %product, i32 0, i32 6 ; <i8*> [#uses=1]
|
||||||
|
store i8 77, i8* %.array21
|
||||||
|
%.array22 = getelementptr [8 x i8]* %product, i32 0, i32 7 ; <i8*> [#uses=1]
|
||||||
|
store i8 0, i8* %.array22
|
||||||
|
store i32 0, i32* %cnt_crc
|
||||||
|
store i32 0, i32* %addr
|
||||||
|
store i16 0, i16* %addr_lo
|
||||||
|
store i16 0, i16* %addr_hi
|
||||||
|
store i16 0, i16* %step
|
||||||
|
store i16 0, i16* %crc
|
||||||
|
store i8 0, i8* %bank
|
||||||
|
call void @usb_init()
|
||||||
|
%tmp = load i32* %argc.addr ; <i32> [#uses=1]
|
||||||
|
%cmp = icmp slt i32 %tmp, 2 ; <i1> [#uses=1]
|
||||||
|
br i1 %cmp, label %if.then, label %if.end
|
||||||
|
|
||||||
|
if.then: ; preds = %entry
|
||||||
|
%tmp23 = load i8*** %argv.addr ; <i8**> [#uses=1]
|
||||||
|
%arrayidx = getelementptr i8** %tmp23, i32 0 ; <i8**> [#uses=1]
|
||||||
|
%tmp24 = load i8** %arrayidx ; <i8*> [#uses=1]
|
||||||
|
call void @usage(i8* %tmp24)
|
||||||
|
call void @exit(i32 1) noreturn
|
||||||
|
unreachable
|
||||||
|
; No predecessors!
|
||||||
|
br label %if.end
|
||||||
|
|
||||||
|
if.end: ; preds = %0, %entry
|
||||||
|
%arraydecay = getelementptr [2 x i8]* %rawVid, i32 0, i32 0 ; <i8*> [#uses=1]
|
||||||
|
%arrayidx25 = getelementptr i8* %arraydecay, i32 1 ; <i8*> [#uses=1]
|
||||||
|
%tmp26 = load i8* %arrayidx25 ; <i8> [#uses=1]
|
||||||
|
%conv = zext i8 %tmp26 to i32 ; <i32> [#uses=1]
|
||||||
|
%mul = mul i32 %conv, 256 ; <i32> [#uses=1]
|
||||||
|
%arraydecay27 = getelementptr [2 x i8]* %rawVid, i32 0, i32 0 ; <i8*> [#uses=1]
|
||||||
|
%arrayidx28 = getelementptr i8* %arraydecay27, i32 0 ; <i8*> [#uses=1]
|
||||||
|
%tmp29 = load i8* %arrayidx28 ; <i8> [#uses=1]
|
||||||
|
%conv30 = zext i8 %tmp29 to i32 ; <i32> [#uses=1]
|
||||||
|
%add = add i32 %mul, %conv30 ; <i32> [#uses=1]
|
||||||
|
store i32 %add, i32* %vid
|
||||||
|
%arraydecay31 = getelementptr [2 x i8]* %rawPid, i32 0, i32 0 ; <i8*> [#uses=1]
|
||||||
|
%arrayidx32 = getelementptr i8* %arraydecay31, i32 1 ; <i8*> [#uses=1]
|
||||||
|
%tmp33 = load i8* %arrayidx32 ; <i8> [#uses=1]
|
||||||
|
%conv34 = zext i8 %tmp33 to i32 ; <i32> [#uses=1]
|
||||||
|
%mul35 = mul i32 %conv34, 256 ; <i32> [#uses=1]
|
||||||
|
%arraydecay36 = getelementptr [2 x i8]* %rawPid, i32 0, i32 0 ; <i8*> [#uses=1]
|
||||||
|
%arrayidx37 = getelementptr i8* %arraydecay36, i32 0 ; <i8*> [#uses=1]
|
||||||
|
%tmp38 = load i8* %arrayidx37 ; <i8> [#uses=1]
|
||||||
|
%conv39 = zext i8 %tmp38 to i32 ; <i32> [#uses=1]
|
||||||
|
%add40 = add i32 %mul35, %conv39 ; <i32> [#uses=1]
|
||||||
|
store i32 %add40, i32* %pid
|
||||||
|
%tmp41 = load i32* %vid ; <i32> [#uses=1]
|
||||||
|
%arraydecay42 = getelementptr [11 x i8]* %vendor, i32 0, i32 0 ; <i8*> [#uses=1]
|
||||||
|
%tmp43 = load i32* %pid ; <i32> [#uses=1]
|
||||||
|
%arraydecay44 = getelementptr [8 x i8]* %product, i32 0, i32 0 ; <i8*> [#uses=1]
|
||||||
|
%call = call i32 @usbOpenDevice(%struct.usb_dev_handle** %handle, i32 %tmp41, i8* %arraydecay42, i32 %tmp43, i8* %arraydecay44, i8* null, %struct.__sFILE* null, %struct.__sFILE* null) ; <i32> [#uses=1]
|
||||||
|
%cmp45 = icmp ne i32 %call, 0 ; <i1> [#uses=1]
|
||||||
|
br i1 %cmp45, label %if.then47, label %if.end53
|
||||||
|
|
||||||
|
if.then47: ; preds = %if.end
|
||||||
|
%tmp48 = load %struct.__sFILE** @__stderrp ; <%struct.__sFILE*> [#uses=1]
|
||||||
|
%arraydecay49 = getelementptr [8 x i8]* %product, i32 0, i32 0 ; <i8*> [#uses=1]
|
||||||
|
%tmp50 = load i32* %vid ; <i32> [#uses=1]
|
||||||
|
%tmp51 = load i32* %pid ; <i32> [#uses=1]
|
||||||
|
%call52 = call i32 (%struct.__sFILE*, i8*, ...)* @fprintf(%struct.__sFILE* %tmp48, i8* getelementptr ([55 x i8]* @"\01LC7", i32 0, i32 0), i8* %arraydecay49, i32 %tmp50, i32 %tmp51) ; <i32> [#uses=0]
|
||||||
|
call void @exit(i32 1) noreturn
|
||||||
|
unreachable
|
||||||
|
; No predecessors!
|
||||||
|
br label %if.end53
|
||||||
|
|
||||||
|
if.end53: ; preds = %1, %if.end
|
||||||
|
%arraydecay54 = getelementptr [8 x i8]* %product, i32 0, i32 0 ; <i8*> [#uses=1]
|
||||||
|
%tmp55 = load i32* %vid ; <i32> [#uses=1]
|
||||||
|
%tmp56 = load i32* %pid ; <i32> [#uses=1]
|
||||||
|
%call57 = call i32 (i8*, ...)* @printf(i8* getelementptr ([45 x i8]* @"\01LC8", i32 0, i32 0), i8* %arraydecay54, i32 %tmp55, i32 %tmp56) ; <i32> [#uses=0]
|
||||||
|
%tmp58 = load i8*** %argv.addr ; <i8**> [#uses=1]
|
||||||
|
%arrayidx59 = getelementptr i8** %tmp58, i32 1 ; <i8**> [#uses=1]
|
||||||
|
%tmp60 = load i8** %arrayidx59 ; <i8*> [#uses=1]
|
||||||
|
%call61 = call i32 @strcasecmp(i8* %tmp60, i8* getelementptr ([7 x i8]* @"\01LC9", i32 0, i32 0)) ; <i32> [#uses=1]
|
||||||
|
%cmp62 = icmp eq i32 %call61, 0 ; <i1> [#uses=1]
|
||||||
|
br i1 %cmp62, label %if.then64, label %if.else171
|
||||||
|
|
||||||
|
if.then64: ; preds = %if.end53
|
||||||
|
%tmp65 = load i32* %argc.addr ; <i32> [#uses=1]
|
||||||
|
%cmp66 = icmp slt i32 %tmp65, 3 ; <i1> [#uses=1]
|
||||||
|
br i1 %cmp66, label %if.then68, label %if.end72
|
||||||
|
|
||||||
|
if.then68: ; preds = %if.then64
|
||||||
|
%tmp69 = load i8*** %argv.addr ; <i8**> [#uses=1]
|
||||||
|
%arrayidx70 = getelementptr i8** %tmp69, i32 0 ; <i8**> [#uses=1]
|
||||||
|
%tmp71 = load i8** %arrayidx70 ; <i8*> [#uses=1]
|
||||||
|
call void @usage(i8* %tmp71)
|
||||||
|
call void @exit(i32 1) noreturn
|
||||||
|
unreachable
|
||||||
|
; No predecessors!
|
||||||
|
br label %if.end72
|
||||||
|
|
||||||
|
if.end72: ; preds = %2, %if.then64
|
||||||
|
%tmp73 = load i8*** %argv.addr ; <i8**> [#uses=1]
|
||||||
|
%arrayidx74 = getelementptr i8** %tmp73, i32 2 ; <i8**> [#uses=1]
|
||||||
|
%tmp75 = load i8** %arrayidx74 ; <i8*> [#uses=1]
|
||||||
|
%call76 = call %struct.__sFILE* @fopen(i8* %tmp75, i8* getelementptr ([2 x i8]* @"\01LC10", i32 0, i32 0)) ; <%struct.__sFILE*> [#uses=1]
|
||||||
|
store %struct.__sFILE* %call76, %struct.__sFILE** %fp
|
||||||
|
%tmp77 = load %struct.__sFILE** %fp ; <%struct.__sFILE*> [#uses=1]
|
||||||
|
%cmp78 = icmp eq %struct.__sFILE* %tmp77, null ; <i1> [#uses=1]
|
||||||
|
br i1 %cmp78, label %if.then80, label %if.end86
|
||||||
|
|
||||||
|
if.then80: ; preds = %if.end72
|
||||||
|
%tmp81 = load %struct.__sFILE** @__stderrp ; <%struct.__sFILE*> [#uses=1]
|
||||||
|
%tmp82 = load i8*** %argv.addr ; <i8**> [#uses=1]
|
||||||
|
%arrayidx83 = getelementptr i8** %tmp82, i32 2 ; <i8**> [#uses=1]
|
||||||
|
%tmp84 = load i8** %arrayidx83 ; <i8*> [#uses=1]
|
||||||
|
%call85 = call i32 (%struct.__sFILE*, i8*, ...)* @fprintf(%struct.__sFILE* %tmp81, i8* getelementptr ([21 x i8]* @"\01LC11", i32 0, i32 0), i8* %tmp84) ; <i32> [#uses=0]
|
||||||
|
call void @exit(i32 1) noreturn
|
||||||
|
unreachable
|
||||||
|
; No predecessors!
|
||||||
|
br label %if.end86
|
||||||
|
|
||||||
|
if.end86: ; preds = %3, %if.end72
|
||||||
|
%call87 = call i8* @malloc(i32 1024) ; <i8*> [#uses=1]
|
||||||
|
store i8* %call87, i8** %read_buffer
|
||||||
|
%call88 = call i8* @malloc(i32 32768) ; <i8*> [#uses=1]
|
||||||
|
store i8* %call88, i8** %crc_buffer
|
||||||
|
%tmp89 = load i8** %crc_buffer ; <i8*> [#uses=1]
|
||||||
|
%call90 = call i8* @memset(i8* %tmp89, i32 0, i32 32768) ; <i8*> [#uses=0]
|
||||||
|
store i32 0, i32* %addr
|
||||||
|
%tmp91 = load %struct.usb_dev_handle** %handle ; <%struct.usb_dev_handle*> [#uses=1]
|
||||||
|
%call92 = call i32 @usb_control_msg(%struct.usb_dev_handle* %tmp91, i32 64, i32 0, i32 0, i32 0, i8* null, i32 0, i32 5000) ; <i32> [#uses=0]
|
||||||
|
br label %while.cond
|
||||||
|
|
||||||
|
while.cond: ; preds = %if.end148, %if.end86
|
||||||
|
%tmp93 = load i8** %read_buffer ; <i8*> [#uses=1]
|
||||||
|
%tmp94 = load %struct.__sFILE** %fp ; <%struct.__sFILE*> [#uses=1]
|
||||||
|
%call95 = call i32 @fread(i8* %tmp93, i32 1024, i32 1, %struct.__sFILE* %tmp94) ; <i32> [#uses=2]
|
||||||
|
store i32 %call95, i32* %cnt
|
||||||
|
%cmp96 = icmp sgt i32 %call95, 0 ; <i1> [#uses=1]
|
||||||
|
br i1 %cmp96, label %while.body, label %while.end
|
||||||
|
|
||||||
|
while.body: ; preds = %while.cond
|
||||||
|
store i16 0, i16* %step
|
||||||
|
br label %for.cond
|
||||||
|
|
||||||
|
for.cond: ; preds = %for.inc, %while.body
|
||||||
|
%tmp98 = load i16* %step ; <i16> [#uses=1]
|
||||||
|
%conv99 = zext i16 %tmp98 to i32 ; <i32> [#uses=1]
|
||||||
|
%cmp100 = icmp slt i32 %conv99, 1024 ; <i1> [#uses=1]
|
||||||
|
br i1 %cmp100, label %for.body, label %for.end
|
||||||
|
|
||||||
|
for.body: ; preds = %for.cond
|
||||||
|
%tmp102 = load i32* %addr ; <i32> [#uses=1]
|
||||||
|
%and = and i32 %tmp102, 65535 ; <i32> [#uses=1]
|
||||||
|
%conv103 = trunc i32 %and to i16 ; <i16> [#uses=1]
|
||||||
|
store i16 %conv103, i16* %addr_lo
|
||||||
|
%tmp104 = load i32* %addr ; <i32> [#uses=1]
|
||||||
|
%shr = lshr i32 %tmp104, 16 ; <i32> [#uses=1]
|
||||||
|
%and105 = and i32 %shr, 255 ; <i32> [#uses=1]
|
||||||
|
%conv106 = trunc i32 %and105 to i16 ; <i16> [#uses=1]
|
||||||
|
store i16 %conv106, i16* %addr_hi
|
||||||
|
%tmp107 = load %struct.usb_dev_handle** %handle ; <%struct.usb_dev_handle*> [#uses=1]
|
||||||
|
%tmp108 = load i16* %addr_hi ; <i16> [#uses=1]
|
||||||
|
%conv109 = zext i16 %tmp108 to i32 ; <i32> [#uses=1]
|
||||||
|
%tmp110 = load i16* %addr_lo ; <i16> [#uses=1]
|
||||||
|
%conv111 = zext i16 %tmp110 to i32 ; <i32> [#uses=1]
|
||||||
|
%tmp112 = load i8** %read_buffer ; <i8*> [#uses=1]
|
||||||
|
%tmp113 = load i16* %step ; <i16> [#uses=1]
|
||||||
|
%conv114 = zext i16 %tmp113 to i32 ; <i32> [#uses=1]
|
||||||
|
%add.ptr = getelementptr i8* %tmp112, i32 %conv114 ; <i8*> [#uses=1]
|
||||||
|
%call115 = call i32 @usb_control_msg(%struct.usb_dev_handle* %tmp107, i32 64, i32 1, i32 %conv109, i32 %conv111, i8* %add.ptr, i32 128, i32 5000) ; <i32> [#uses=0]
|
||||||
|
%tmp116 = load i32* %addr ; <i32> [#uses=1]
|
||||||
|
%add117 = add i32 %tmp116, 128 ; <i32> [#uses=1]
|
||||||
|
store i32 %add117, i32* %addr
|
||||||
|
br label %for.inc
|
||||||
|
|
||||||
|
for.inc: ; preds = %for.body
|
||||||
|
%tmp118 = load i16* %step ; <i16> [#uses=1]
|
||||||
|
%conv119 = zext i16 %tmp118 to i32 ; <i32> [#uses=1]
|
||||||
|
%add120 = add i32 %conv119, 128 ; <i32> [#uses=1]
|
||||||
|
%conv121 = trunc i32 %add120 to i16 ; <i16> [#uses=1]
|
||||||
|
store i16 %conv121, i16* %step
|
||||||
|
br label %for.cond
|
||||||
|
|
||||||
|
for.end: ; preds = %for.cond
|
||||||
|
%tmp122 = load i8** %crc_buffer ; <i8*> [#uses=1]
|
||||||
|
%tmp123 = load i32* %cnt_crc ; <i32> [#uses=1]
|
||||||
|
%add.ptr124 = getelementptr i8* %tmp122, i32 %tmp123 ; <i8*> [#uses=1]
|
||||||
|
%tmp125 = load i8** %read_buffer ; <i8*> [#uses=1]
|
||||||
|
%call126 = call i8* @memcpy(i8* %add.ptr124, i8* %tmp125, i32 1024) ; <i8*> [#uses=0]
|
||||||
|
%tmp127 = load i32* %cnt_crc ; <i32> [#uses=1]
|
||||||
|
%add128 = add i32 %tmp127, 1024 ; <i32> [#uses=1]
|
||||||
|
store i32 %add128, i32* %cnt_crc
|
||||||
|
%tmp129 = load i32* %cnt_crc ; <i32> [#uses=1]
|
||||||
|
%cmp130 = icmp sge i32 %tmp129, 32768 ; <i1> [#uses=1]
|
||||||
|
br i1 %cmp130, label %if.then132, label %if.end148
|
||||||
|
|
||||||
|
if.then132: ; preds = %for.end
|
||||||
|
%tmp133 = load i8** %crc_buffer ; <i8*> [#uses=1]
|
||||||
|
%call134 = call zeroext i16 @do_crc(i8* %tmp133, i16 zeroext -32768) ; <i16> [#uses=1]
|
||||||
|
store i16 %call134, i16* %crc
|
||||||
|
%tmp135 = load i32* %addr ; <i32> [#uses=1]
|
||||||
|
%tmp136 = load i8* %bank ; <i8> [#uses=1]
|
||||||
|
%conv137 = zext i8 %tmp136 to i32 ; <i32> [#uses=1]
|
||||||
|
%tmp138 = load i16* %addr_hi ; <i16> [#uses=1]
|
||||||
|
%conv139 = zext i16 %tmp138 to i32 ; <i32> [#uses=1]
|
||||||
|
%tmp140 = load i16* %addr_lo ; <i16> [#uses=1]
|
||||||
|
%conv141 = zext i16 %tmp140 to i32 ; <i32> [#uses=1]
|
||||||
|
%tmp142 = load i16* %crc ; <i16> [#uses=1]
|
||||||
|
%conv143 = zext i16 %tmp142 to i32 ; <i32> [#uses=1]
|
||||||
|
%call144 = call i32 (i8*, ...)* @printf(i8* getelementptr ([70 x i8]* @"\01LC12", i32 0, i32 0), i32 %tmp135, i32 %conv137, i32 %conv139, i32 %conv141, i32 %conv143) ; <i32> [#uses=0]
|
||||||
|
%tmp145 = load i8** %crc_buffer ; <i8*> [#uses=1]
|
||||||
|
%call146 = call i8* @memset(i8* %tmp145, i32 0, i32 32768) ; <i8*> [#uses=0]
|
||||||
|
%tmp147 = load i8* %bank ; <i8> [#uses=1]
|
||||||
|
%inc = add i8 %tmp147, 1 ; <i8> [#uses=1]
|
||||||
|
store i8 %inc, i8* %bank
|
||||||
|
store i32 0, i32* %cnt_crc
|
||||||
|
br label %if.end148
|
||||||
|
|
||||||
|
if.end148: ; preds = %if.then132, %for.end
|
||||||
|
br label %while.cond
|
||||||
|
|
||||||
|
while.end: ; preds = %while.cond
|
||||||
|
%tmp149 = load %struct.usb_dev_handle** %handle ; <%struct.usb_dev_handle*> [#uses=1]
|
||||||
|
%tmp150 = load i16* %addr_hi ; <i16> [#uses=1]
|
||||||
|
%conv151 = zext i16 %tmp150 to i32 ; <i32> [#uses=1]
|
||||||
|
%tmp152 = load i16* %addr_lo ; <i16> [#uses=1]
|
||||||
|
%conv153 = zext i16 %tmp152 to i32 ; <i32> [#uses=1]
|
||||||
|
%call154 = call i32 @usb_control_msg(%struct.usb_dev_handle* %tmp149, i32 64, i32 4, i32 %conv151, i32 %conv153, i8* null, i32 0, i32 5000) ; <i32> [#uses=1]
|
||||||
|
store i32 %call154, i32* %cnt
|
||||||
|
%tmp155 = load i32* %cnt ; <i32> [#uses=1]
|
||||||
|
%cmp156 = icmp slt i32 %tmp155, 1 ; <i1> [#uses=1]
|
||||||
|
br i1 %cmp156, label %if.then158, label %if.end170
|
||||||
|
|
||||||
|
if.then158: ; preds = %while.end
|
||||||
|
%tmp159 = load i32* %cnt ; <i32> [#uses=1]
|
||||||
|
%cmp160 = icmp slt i32 %tmp159, 0 ; <i1> [#uses=1]
|
||||||
|
br i1 %cmp160, label %if.then162, label %if.else
|
||||||
|
|
||||||
|
if.then162: ; preds = %if.then158
|
||||||
|
%tmp163 = load %struct.__sFILE** @__stderrp ; <%struct.__sFILE*> [#uses=1]
|
||||||
|
%call164 = call i8* @usb_strerror() ; <i8*> [#uses=1]
|
||||||
|
%call165 = call i32 (%struct.__sFILE*, i8*, ...)* @fprintf(%struct.__sFILE* %tmp163, i8* getelementptr ([15 x i8]* @"\01LC13", i32 0, i32 0), i8* %call164) ; <i32> [#uses=0]
|
||||||
|
br label %if.end169
|
||||||
|
|
||||||
|
if.else: ; preds = %if.then158
|
||||||
|
%tmp166 = load %struct.__sFILE** @__stderrp ; <%struct.__sFILE*> [#uses=1]
|
||||||
|
%tmp167 = load i32* %cnt ; <i32> [#uses=1]
|
||||||
|
%call168 = call i32 (%struct.__sFILE*, i8*, ...)* @fprintf(%struct.__sFILE* %tmp166, i8* getelementptr ([25 x i8]* @"\01LC14", i32 0, i32 0), i32 %tmp167) ; <i32> [#uses=0]
|
||||||
|
br label %if.end169
|
||||||
|
|
||||||
|
if.end169: ; preds = %if.else, %if.then162
|
||||||
|
br label %if.end170
|
||||||
|
|
||||||
|
if.end170: ; preds = %if.end169, %while.end
|
||||||
|
br label %if.end216
|
||||||
|
|
||||||
|
if.else171: ; preds = %if.end53
|
||||||
|
%tmp172 = load i8*** %argv.addr ; <i8**> [#uses=1]
|
||||||
|
%arrayidx173 = getelementptr i8** %tmp172, i32 1 ; <i8**> [#uses=1]
|
||||||
|
%tmp174 = load i8** %arrayidx173 ; <i8*> [#uses=1]
|
||||||
|
%call175 = call i32 @strcasecmp(i8* %tmp174, i8* getelementptr ([4 x i8]* @"\01LC15", i32 0, i32 0)) ; <i32> [#uses=1]
|
||||||
|
%cmp176 = icmp eq i32 %call175, 0 ; <i1> [#uses=1]
|
||||||
|
br i1 %cmp176, label %if.then178, label %if.else211
|
||||||
|
|
||||||
|
if.then178: ; preds = %if.else171
|
||||||
|
store i32 0, i32* %addr
|
||||||
|
%tmp179 = load i32* %addr ; <i32> [#uses=1]
|
||||||
|
%and180 = and i32 %tmp179, 65535 ; <i32> [#uses=1]
|
||||||
|
%conv181 = trunc i32 %and180 to i16 ; <i16> [#uses=1]
|
||||||
|
store i16 %conv181, i16* %addr_lo
|
||||||
|
%tmp182 = load i32* %addr ; <i32> [#uses=1]
|
||||||
|
%shr183 = lshr i32 %tmp182, 16 ; <i32> [#uses=1]
|
||||||
|
%and184 = and i32 %shr183, 255 ; <i32> [#uses=1]
|
||||||
|
%conv185 = trunc i32 %and184 to i16 ; <i16> [#uses=1]
|
||||||
|
store i16 %conv185, i16* %addr_hi
|
||||||
|
%tmp186 = load i32* %addr ; <i32> [#uses=1]
|
||||||
|
%call187 = call i32 (i8*, ...)* @printf(i8* getelementptr ([30 x i8]* @"\01LC16", i32 0, i32 0), i32 %tmp186) ; <i32> [#uses=0]
|
||||||
|
%tmp188 = load %struct.usb_dev_handle** %handle ; <%struct.usb_dev_handle*> [#uses=1]
|
||||||
|
%tmp189 = load i16* %addr_hi ; <i16> [#uses=1]
|
||||||
|
%conv190 = zext i16 %tmp189 to i32 ; <i32> [#uses=1]
|
||||||
|
%tmp191 = load i16* %addr_lo ; <i16> [#uses=1]
|
||||||
|
%conv192 = zext i16 %tmp191 to i32 ; <i32> [#uses=1]
|
||||||
|
%call193 = call i32 @usb_control_msg(%struct.usb_dev_handle* %tmp188, i32 64, i32 5, i32 %conv190, i32 %conv192, i8* null, i32 8192, i32 5000) ; <i32> [#uses=1]
|
||||||
|
store i32 %call193, i32* %cnt
|
||||||
|
%tmp194 = load i32* %cnt ; <i32> [#uses=1]
|
||||||
|
%cmp195 = icmp slt i32 %tmp194, 1 ; <i1> [#uses=1]
|
||||||
|
br i1 %cmp195, label %if.then197, label %if.end210
|
||||||
|
|
||||||
|
if.then197: ; preds = %if.then178
|
||||||
|
%tmp198 = load i32* %cnt ; <i32> [#uses=1]
|
||||||
|
%cmp199 = icmp slt i32 %tmp198, 0 ; <i1> [#uses=1]
|
||||||
|
br i1 %cmp199, label %if.then201, label %if.else205
|
||||||
|
|
||||||
|
if.then201: ; preds = %if.then197
|
||||||
|
%tmp202 = load %struct.__sFILE** @__stderrp ; <%struct.__sFILE*> [#uses=1]
|
||||||
|
%call203 = call i8* @usb_strerror() ; <i8*> [#uses=1]
|
||||||
|
%call204 = call i32 (%struct.__sFILE*, i8*, ...)* @fprintf(%struct.__sFILE* %tmp202, i8* getelementptr ([15 x i8]* @"\01LC13", i32 0, i32 0), i8* %call203) ; <i32> [#uses=0]
|
||||||
|
br label %if.end209
|
||||||
|
|
||||||
|
if.else205: ; preds = %if.then197
|
||||||
|
%tmp206 = load %struct.__sFILE** @__stderrp ; <%struct.__sFILE*> [#uses=1]
|
||||||
|
%tmp207 = load i32* %cnt ; <i32> [#uses=1]
|
||||||
|
%call208 = call i32 (%struct.__sFILE*, i8*, ...)* @fprintf(%struct.__sFILE* %tmp206, i8* getelementptr ([25 x i8]* @"\01LC14", i32 0, i32 0), i32 %tmp207) ; <i32> [#uses=0]
|
||||||
|
br label %if.end209
|
||||||
|
|
||||||
|
if.end209: ; preds = %if.else205, %if.then201
|
||||||
|
br label %if.end210
|
||||||
|
|
||||||
|
if.end210: ; preds = %if.end209, %if.then178
|
||||||
|
br label %if.end215
|
||||||
|
|
||||||
|
if.else211: ; preds = %if.else171
|
||||||
|
%tmp212 = load i8*** %argv.addr ; <i8**> [#uses=1]
|
||||||
|
%arrayidx213 = getelementptr i8** %tmp212, i32 0 ; <i8**> [#uses=1]
|
||||||
|
%tmp214 = load i8** %arrayidx213 ; <i8*> [#uses=1]
|
||||||
|
call void @usage(i8* %tmp214)
|
||||||
|
call void @exit(i32 1) noreturn
|
||||||
|
unreachable
|
||||||
|
; No predecessors!
|
||||||
|
br label %if.end215
|
||||||
|
|
||||||
|
if.end215: ; preds = %4, %if.end210
|
||||||
|
br label %if.end216
|
||||||
|
|
||||||
|
if.end216: ; preds = %if.end215, %if.end170
|
||||||
|
%tmp217 = load %struct.usb_dev_handle** %handle ; <%struct.usb_dev_handle*> [#uses=1]
|
||||||
|
%call218 = call i32 @usb_close(%struct.usb_dev_handle* %tmp217) ; <i32> [#uses=0]
|
||||||
|
store i32 0, i32* %retval
|
||||||
|
%5 = load i32* %retval ; <i32> [#uses=1]
|
||||||
|
ret i32 %5
|
||||||
|
}
|
||||||
|
|
||||||
|
declare void @usb_init()
|
||||||
|
|
||||||
|
define internal void @usage(i8* %name) nounwind {
|
||||||
|
entry:
|
||||||
|
%name.addr = alloca i8* ; <i8**> [#uses=2]
|
||||||
|
store i8* %name, i8** %name.addr
|
||||||
|
%tmp = load %struct.__sFILE** @__stderrp ; <%struct.__sFILE*> [#uses=1]
|
||||||
|
%call = call i32 (%struct.__sFILE*, i8*, ...)* @fprintf(%struct.__sFILE* %tmp, i8* getelementptr ([8 x i8]* @"\01LC17", i32 0, i32 0)) ; <i32> [#uses=0]
|
||||||
|
%tmp1 = load %struct.__sFILE** @__stderrp ; <%struct.__sFILE*> [#uses=1]
|
||||||
|
%tmp2 = load i8** %name.addr ; <i8*> [#uses=1]
|
||||||
|
%call3 = call i32 (%struct.__sFILE*, i8*, ...)* @fprintf(%struct.__sFILE* %tmp1, i8* getelementptr ([31 x i8]* @"\01LC18", i32 0, i32 0), i8* %tmp2) ; <i32> [#uses=0]
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
|
||||||
|
declare void @exit(i32) noreturn
|
||||||
|
|
||||||
|
declare i32 @usbOpenDevice(%struct.usb_dev_handle**, i32, i8*, i32, i8*, i8*, %struct.__sFILE*, %struct.__sFILE*)
|
||||||
|
|
||||||
|
declare i32 @fprintf(%struct.__sFILE*, i8*, ...)
|
||||||
|
|
||||||
|
declare i32 @strcasecmp(i8*, i8*)
|
||||||
|
|
||||||
|
declare %struct.__sFILE* @fopen(i8*, i8*)
|
||||||
|
|
||||||
|
declare i8* @malloc(i32)
|
||||||
|
|
||||||
|
declare i8* @memset(i8*, i32, i32)
|
||||||
|
|
||||||
|
declare i32 @usb_control_msg(%struct.usb_dev_handle*, i32, i32, i32, i32, i8*, i32, i32)
|
||||||
|
|
||||||
|
declare i32 @fread(i8*, i32, i32, %struct.__sFILE*)
|
||||||
|
|
||||||
|
declare i8* @memcpy(i8*, i8*, i32)
|
||||||
|
|
||||||
|
declare i8* @usb_strerror()
|
||||||
|
|
||||||
|
declare i32 @usb_close(%struct.usb_dev_handle*)
|
||||||
50
avr/usbload/config.h
Normal file
50
avr/usbload/config.h
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
/*
|
||||||
|
* =====================================================================================
|
||||||
|
*
|
||||||
|
* ________ .__ __ ________ ____ ________
|
||||||
|
* \_____ \ __ __|__| ____ | | __\______ \ _______ _/_ |/ _____/
|
||||||
|
* / / \ \| | \ |/ ___\| |/ / | | \_/ __ \ \/ /| / __ \
|
||||||
|
* / \_/. \ | / \ \___| < | ` \ ___/\ / | \ |__\ \
|
||||||
|
* \_____\ \_/____/|__|\___ >__|_ \/_______ /\___ >\_/ |___|\_____ /
|
||||||
|
* \__> \/ \/ \/ \/ \/
|
||||||
|
*
|
||||||
|
* www.optixx.org
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Version: 1.0
|
||||||
|
* Created: 07/21/2009 03:32:16 PM
|
||||||
|
* Author: david@optixx.org
|
||||||
|
*
|
||||||
|
* =====================================================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __CONFIH_H__
|
||||||
|
#define __CONFIH_H__
|
||||||
|
|
||||||
|
|
||||||
|
#define DEBUG 1
|
||||||
|
#define DEBUG_USB 2
|
||||||
|
#define DEBUG_USB_TRANS 4
|
||||||
|
#define DEBUG_SRAM 8
|
||||||
|
#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
|
||||||
|
#define REQ_STATUS_BULK_UPLOAD 0x03
|
||||||
|
#define REQ_STATUS_BULK_NEXT 0x04
|
||||||
|
#define REQ_STATUS_CRC 0x05
|
||||||
|
#define REQ_STATUS_SNES 0x06
|
||||||
|
#define REQ_STATUS_AVR 0x07
|
||||||
|
|
||||||
|
#define USB_MAX_TRANS 0xff
|
||||||
|
#define USB_CRC_CHECK 0x01
|
||||||
|
|
||||||
|
#define TRANSFER_BUFFER_SIZE 0x200
|
||||||
|
#define FORMAT_BUFFER_LEN 0x0FF
|
||||||
|
#define HW_VERSION "2.6"
|
||||||
|
#define SW_VERSION "1.0"
|
||||||
|
|
||||||
|
#endif
|
||||||
106
avr/usbload/crc.c
Normal file
106
avr/usbload/crc.c
Normal file
@@ -0,0 +1,106 @@
|
|||||||
|
/*
|
||||||
|
* =====================================================================================
|
||||||
|
*
|
||||||
|
* ________ .__ __ ________ ____ ________
|
||||||
|
* \_____ \ __ __|__| ____ | | __\______ \ _______ _/_ |/ _____/
|
||||||
|
* / / \ \| | \ |/ ___\| |/ / | | \_/ __ \ \/ /| / __ \
|
||||||
|
* / \_/. \ | / \ \___| < | ` \ ___/\ / | \ |__\ \
|
||||||
|
* \_____\ \_/____/|__|\___ >__|_ \/_______ /\___ >\_/ |___|\_____ /
|
||||||
|
* \__> \/ \/ \/ \/ \/
|
||||||
|
*
|
||||||
|
* 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 "crc.h"
|
||||||
|
#include "uart.h"
|
||||||
|
#include "config.h"
|
||||||
|
#include "sram.h"
|
||||||
|
#include "debug.h"
|
||||||
|
#include "info.h"
|
||||||
|
|
||||||
|
extern FILE uart_stdout;
|
||||||
|
|
||||||
|
uint16_t crc_xmodem_update(uint16_t crc, uint8_t data)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
crc = crc ^ ((uint16_t) data << 8);
|
||||||
|
for (i = 0; i < 8; i++) {
|
||||||
|
if (crc & 0x8000)
|
||||||
|
crc = (crc << 1) ^ 0x1021;
|
||||||
|
else
|
||||||
|
crc <<= 1;
|
||||||
|
}
|
||||||
|
return crc;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t do_crc(uint8_t * data, uint16_t size)
|
||||||
|
{
|
||||||
|
uint16_t crc = 0;
|
||||||
|
uint16_t i;
|
||||||
|
for (i = 0; i < size; i++) {
|
||||||
|
crc = crc_xmodem_update(crc, data[i]);
|
||||||
|
|
||||||
|
}
|
||||||
|
return crc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint16_t do_crc_update(uint16_t crc, uint8_t * data, uint16_t size)
|
||||||
|
{
|
||||||
|
uint16_t i;
|
||||||
|
for (i = 0; i < size; i++)
|
||||||
|
crc = crc_xmodem_update(crc, data[i]);
|
||||||
|
return crc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint16_t crc_check_bulk_memory(uint32_t bottom_addr, uint32_t top_addr, uint32_t bank_size)
|
||||||
|
{
|
||||||
|
uint16_t crc = 0;
|
||||||
|
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_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;
|
||||||
|
}
|
||||||
|
crc = crc_xmodem_update(crc, sram_bulk_read());
|
||||||
|
sram_bulk_read_next();
|
||||||
|
}
|
||||||
|
if (addr % 0x8000 == 0)
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
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_bulk_copy_into_buffer(addr, buffer, TRANSFER_BUFFER_SIZE);
|
||||||
|
crc = do_crc_update(crc, buffer, TRANSFER_BUFFER_SIZE);
|
||||||
|
}
|
||||||
|
return crc;
|
||||||
|
}
|
||||||
35
avr/usbload/crc.h
Normal file
35
avr/usbload/crc.h
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
/*
|
||||||
|
* =====================================================================================
|
||||||
|
*
|
||||||
|
* ________ .__ __ ________ ____ ________
|
||||||
|
* \_____ \ __ __|__| ____ | | __\______ \ _______ _/_ |/ _____/
|
||||||
|
* / / \ \| | \ |/ ___\| |/ / | | \_/ __ \ \/ /| / __ \
|
||||||
|
* / \_/. \ | / \ \___| < | ` \ ___/\ / | \ |__\ \
|
||||||
|
* \_____\ \_/____/|__|\___ >__|_ \/_______ /\___ >\_/ |___|\_____ /
|
||||||
|
* \__> \/ \/ \/ \/ \/
|
||||||
|
*
|
||||||
|
* www.optixx.org
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Version: 1.0
|
||||||
|
* Created: 07/21/2009 03:32:16 PM
|
||||||
|
* Author: david@optixx.org
|
||||||
|
*
|
||||||
|
* =====================================================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef __CRC_H__
|
||||||
|
#define __CRC_H__
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
|
||||||
|
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);
|
||||||
|
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);
|
||||||
|
|
||||||
|
#endif
|
||||||
68
avr/usbload/debug.c
Normal file
68
avr/usbload/debug.c
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
/*
|
||||||
|
* =====================================================================================
|
||||||
|
*
|
||||||
|
* ________ .__ __ ________ ____ ________
|
||||||
|
* \_____ \ __ __|__| ____ | | __\______ \ _______ _/_ |/ _____/
|
||||||
|
* / / \ \| | \ |/ ___\| |/ / | | \_/ __ \ \/ /| / __ \
|
||||||
|
* / \_/. \ | / \ \___| < | ` \ ___/\ / | \ |__\ \
|
||||||
|
* \_____\ \_/____/|__|\___ >__|_ \/_______ /\___ >\_/ |___|\_____ /
|
||||||
|
* \__> \/ \/ \/ \/ \/
|
||||||
|
*
|
||||||
|
* 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/pgmspace.h>
|
||||||
|
|
||||||
|
#include "debug.h"
|
||||||
|
#include "uart.h"
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
extern FILE uart_stdout;
|
||||||
|
|
||||||
|
extern int debug_level; /* the higher, the more messages... */
|
||||||
|
|
||||||
|
#if defined(NO_DEBUG) && defined(__GNUC__)
|
||||||
|
#else
|
||||||
|
void debug(int level, char* format, ...) {
|
||||||
|
#ifdef NO_DEBUG
|
||||||
|
|
||||||
|
#else
|
||||||
|
va_list args;
|
||||||
|
if (!(debug_level & level))
|
||||||
|
return;
|
||||||
|
va_start(args, format);
|
||||||
|
vprintf(format, args);
|
||||||
|
va_end(args);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef NO_INFO
|
||||||
|
uint8_t buffer_debug[FORMAT_BUFFER_LEN];
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(NO_DEBUG) && defined(__GNUC__)
|
||||||
|
#else
|
||||||
|
void debug_P(int level, PGM_P format, ...) {
|
||||||
|
#ifdef NO_DEBUG
|
||||||
|
|
||||||
|
#else
|
||||||
|
va_list args;
|
||||||
|
if (!(debug_level & level))
|
||||||
|
return;
|
||||||
|
strlcpy_P(buffer_debug,format,FORMAT_BUFFER_LEN);
|
||||||
|
va_start(args, format);
|
||||||
|
vprintf(buffer_debug, args);
|
||||||
|
va_end(args);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
55
avr/usbload/debug.h
Normal file
55
avr/usbload/debug.h
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
/*
|
||||||
|
* =====================================================================================
|
||||||
|
*
|
||||||
|
* ________ .__ __ ________ ____ ________
|
||||||
|
* \_____ \ __ __|__| ____ | | __\______ \ _______ _/_ |/ _____/
|
||||||
|
* / / \ \| | \ |/ ___\| |/ / | | \_/ __ \ \/ /| / __ \
|
||||||
|
* / \_/. \ | / \ \___| < | ` \ ___/\ / | \ |__\ \
|
||||||
|
* \_____\ \_/____/|__|\___ >__|_ \/_______ /\___ >\_/ |___|\_____ /
|
||||||
|
* \__> \/ \/ \/ \/ \/
|
||||||
|
*
|
||||||
|
* www.optixx.org
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Version: 1.0
|
||||||
|
* Created: 07/21/2009 03:32:16 PM
|
||||||
|
* Author: david@optixx.org
|
||||||
|
*
|
||||||
|
* =====================================================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef __DEBUG_H__
|
||||||
|
#define __DEBUG_H__
|
||||||
|
|
||||||
|
#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
|
||||||
|
arguments. We use this extension here to preprocess pmesg away. */
|
||||||
|
#define debug(level, format, args...) ((void)0)
|
||||||
|
#else
|
||||||
|
void debug(int level, char *format, ...);
|
||||||
|
/* print a message, if it is considered significant enough.
|
||||||
|
Adapted from [K&R2], p. 174 */
|
||||||
|
#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 */
|
||||||
|
|
||||||
82
avr/usbload/dump.c
Normal file
82
avr/usbload/dump.c
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
/*
|
||||||
|
* =====================================================================================
|
||||||
|
*
|
||||||
|
* ________ .__ __ ________ ____ ________
|
||||||
|
* \_____ \ __ __|__| ____ | | __\______ \ _______ _/_ |/ _____/
|
||||||
|
* / / \ \| | \ |/ ___\| |/ / | | \_/ __ \ \/ /| / __ \
|
||||||
|
* / \_/. \ | / \ \___| < | ` \ ___/\ / | \ |__\ \
|
||||||
|
* \_____\ \_/____/|__|\___ >__|_ \/_______ /\___ >\_/ |___|\_____ /
|
||||||
|
* \__> \/ \/ \/ \/ \/
|
||||||
|
*
|
||||||
|
* 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 "debug.h"
|
||||||
|
#include "info.h"
|
||||||
|
#include "uart.h"
|
||||||
|
#include "sram.h"
|
||||||
|
|
||||||
|
|
||||||
|
extern FILE uart_stdout;
|
||||||
|
|
||||||
|
void dump_packet(uint32_t addr, uint32_t len, uint8_t * packet)
|
||||||
|
{
|
||||||
|
uint16_t i,j;
|
||||||
|
uint16_t sum = 0;
|
||||||
|
uint8_t clear = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < len; i += 16) {
|
||||||
|
|
||||||
|
sum = 0;
|
||||||
|
for (j = 0; j < 16; j++) {
|
||||||
|
sum += packet[i + j];
|
||||||
|
}
|
||||||
|
if (!sum) {
|
||||||
|
clear = 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (clear) {
|
||||||
|
info_P(PSTR("*\n"));
|
||||||
|
clear = 0;
|
||||||
|
}
|
||||||
|
info_P(PSTR("%08lx:"), addr + i);
|
||||||
|
for (j = 0; j < 16; j++) {
|
||||||
|
info_P(PSTR(" %02x"), packet[i + j]);
|
||||||
|
}
|
||||||
|
info_P(PSTR(" |"));
|
||||||
|
for (j = 0; j < 16; j++) {
|
||||||
|
if (packet[i + j] >= 33 && packet[i + j] <= 126)
|
||||||
|
info_P(PSTR("%c"), packet[i + j]);
|
||||||
|
else
|
||||||
|
info_P(PSTR("."));
|
||||||
|
}
|
||||||
|
info_P(PSTR("|\n"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void dump_memory(uint32_t bottom_addr, uint32_t top_addr)
|
||||||
|
{
|
||||||
|
uint32_t addr;
|
||||||
|
uint8_t byte;
|
||||||
|
sram_bulk_read_start(bottom_addr);
|
||||||
|
for ( addr = bottom_addr; addr < top_addr; addr++) {
|
||||||
|
if (addr%0x10 == 0)
|
||||||
|
info_P(PSTR("\n%08lx:"), addr);
|
||||||
|
byte = sram_bulk_read();
|
||||||
|
sram_bulk_read_next();
|
||||||
|
info_P(PSTR(" %02x"), byte);
|
||||||
|
}
|
||||||
|
info_P(PSTR("\n"));
|
||||||
|
sram_bulk_read_end();
|
||||||
|
}
|
||||||
34
avr/usbload/dump.h
Normal file
34
avr/usbload/dump.h
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
/*
|
||||||
|
* =====================================================================================
|
||||||
|
*
|
||||||
|
* ________ .__ __ ________ ____ ________
|
||||||
|
* \_____ \ __ __|__| ____ | | __\______ \ _______ _/_ |/ _____/
|
||||||
|
* / / \ \| | \ |/ ___\| |/ / | | \_/ __ \ \/ /| / __ \
|
||||||
|
* / \_/. \ | / \ \___| < | ` \ ___/\ / | \ |__\ \
|
||||||
|
* \_____\ \_/____/|__|\___ >__|_ \/_______ /\___ >\_/ |___|\_____ /
|
||||||
|
* \__> \/ \/ \/ \/ \/
|
||||||
|
*
|
||||||
|
* www.optixx.org
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Version: 1.0
|
||||||
|
* Created: 07/21/2009 03:32:16 PM
|
||||||
|
* Author: david@optixx.org
|
||||||
|
*
|
||||||
|
* =====================================================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef __DUMP_H__
|
||||||
|
#define __DUMP_H__
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
void dump_memory(uint32_t bottom_addr, uint32_t top_addr);
|
||||||
|
|
||||||
|
void dump_packet(uint32_t addr,uint32_t len,uint8_t *packet);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
50
avr/usbload/fifo.c
Normal file
50
avr/usbload/fifo.c
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
/*
|
||||||
|
* =====================================================================================
|
||||||
|
*
|
||||||
|
* ________ .__ __ ________ ____ ________
|
||||||
|
* \_____ \ __ __|__| ____ | | __\______ \ _______ _/_ |/ _____/
|
||||||
|
* / / \ \| | \ |/ ___\| |/ / | | \_/ __ \ \/ /| / __ \
|
||||||
|
* / \_/. \ | / \ \___| < | ` \ ___/\ / | \ |__\ \
|
||||||
|
* \_____\ \_/____/|__|\___ >__|_ \/_______ /\___ >\_/ |___|\_____ /
|
||||||
|
* \__> \/ \/ \/ \/ \/
|
||||||
|
*
|
||||||
|
* www.optixx.org
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Version: 1.0
|
||||||
|
* Created: 07/21/2009 03:32:16 PM
|
||||||
|
* Author: david@optixx.org
|
||||||
|
*
|
||||||
|
* =====================================================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#include "fifo.h"
|
||||||
|
|
||||||
|
void fifo_init(fifo_t * f, uint8_t * buffer, const uint8_t size)
|
||||||
|
{
|
||||||
|
f->count = 0;
|
||||||
|
f->pread = f->pwrite = buffer;
|
||||||
|
f->read2end = f->write2end = f->size = size;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t fifo_put(fifo_t * f, const uint8_t data)
|
||||||
|
{
|
||||||
|
return _inline_fifo_put(f, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t fifo_get_wait(fifo_t * f)
|
||||||
|
{
|
||||||
|
while (!f->count);
|
||||||
|
|
||||||
|
return _inline_fifo_get(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
int fifo_get_nowait(fifo_t * f)
|
||||||
|
{
|
||||||
|
if (!f->count)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return (int) _inline_fifo_get(f);
|
||||||
|
}
|
||||||
88
avr/usbload/fifo.h
Normal file
88
avr/usbload/fifo.h
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
/*
|
||||||
|
* =====================================================================================
|
||||||
|
*
|
||||||
|
* ________ .__ __ ________ ____ ________
|
||||||
|
* \_____ \ __ __|__| ____ | | __\______ \ _______ _/_ |/ _____/
|
||||||
|
* / / \ \| | \ |/ ___\| |/ / | | \_/ __ \ \/ /| / __ \
|
||||||
|
* / \_/. \ | / \ \___| < | ` \ ___/\ / | \ |__\ \
|
||||||
|
* \_____\ \_/____/|__|\___ >__|_ \/_______ /\___ >\_/ |___|\_____ /
|
||||||
|
* \__> \/ \/ \/ \/ \/
|
||||||
|
*
|
||||||
|
* www.optixx.org
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Version: 1.0
|
||||||
|
* Created: 07/21/2009 03:32:16 PM
|
||||||
|
* Author: david@optixx.org
|
||||||
|
*
|
||||||
|
* =====================================================================================
|
||||||
|
*/
|
||||||
|
#ifndef __FIFO_H__
|
||||||
|
#define __FIFO_H__
|
||||||
|
|
||||||
|
#include <avr/io.h>
|
||||||
|
#include <avr/interrupt.h>
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint8_t volatile count; // # Zeichen im Puffer
|
||||||
|
uint8_t size; // Puffer-Größe
|
||||||
|
uint8_t *pread; // Lesezeiger
|
||||||
|
uint8_t *pwrite; // Schreibzeiger
|
||||||
|
uint8_t read2end, write2end; // # Zeichen bis zum Überlauf Lese-/Schreibzeiger
|
||||||
|
} fifo_t;
|
||||||
|
|
||||||
|
extern void fifo_init(fifo_t *, uint8_t * buf, const uint8_t size);
|
||||||
|
extern uint8_t fifo_put(fifo_t *, const uint8_t data);
|
||||||
|
extern uint8_t fifo_get_wait(fifo_t *);
|
||||||
|
extern int fifo_get_nowait(fifo_t *);
|
||||||
|
|
||||||
|
static inline uint8_t _inline_fifo_put(fifo_t * f, const uint8_t data)
|
||||||
|
{
|
||||||
|
if (f->count >= f->size)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
uint8_t *pwrite = f->pwrite;
|
||||||
|
|
||||||
|
*(pwrite++) = data;
|
||||||
|
|
||||||
|
uint8_t write2end = f->write2end;
|
||||||
|
|
||||||
|
if (--write2end == 0) {
|
||||||
|
write2end = f->size;
|
||||||
|
pwrite -= write2end;
|
||||||
|
}
|
||||||
|
|
||||||
|
f->write2end = write2end;
|
||||||
|
f->pwrite = pwrite;
|
||||||
|
|
||||||
|
uint8_t sreg = SREG;
|
||||||
|
cli();
|
||||||
|
f->count++;
|
||||||
|
SREG = sreg;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint8_t _inline_fifo_get(fifo_t * f)
|
||||||
|
{
|
||||||
|
uint8_t *pread = f->pread;
|
||||||
|
uint8_t data = *(pread++);
|
||||||
|
uint8_t read2end = f->read2end;
|
||||||
|
|
||||||
|
if (--read2end == 0) {
|
||||||
|
read2end = f->size;
|
||||||
|
pread -= read2end;
|
||||||
|
}
|
||||||
|
|
||||||
|
f->pread = pread;
|
||||||
|
f->read2end = read2end;
|
||||||
|
|
||||||
|
uint8_t sreg = SREG;
|
||||||
|
cli();
|
||||||
|
f->count--;
|
||||||
|
SREG = sreg;
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* _FIFO_H_ */
|
||||||
74
avr/usbload/info.c
Normal file
74
avr/usbload/info.c
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
/*
|
||||||
|
* =====================================================================================
|
||||||
|
*
|
||||||
|
* ________ .__ __ ________ ____ ________
|
||||||
|
* \_____ \ __ __|__| ____ | | __\______ \ _______ _/_ |/ _____/
|
||||||
|
* / / \ \| | \ |/ ___\| |/ / | | \_/ __ \ \/ /| / __ \
|
||||||
|
* / \_/. \ | / \ \___| < | ` \ ___/\ / | \ |__\ \
|
||||||
|
* \_____\ \_/____/|__|\___ >__|_ \/_______ /\___ >\_/ |___|\_____ /
|
||||||
|
* \__> \/ \/ \/ \/ \/
|
||||||
|
*
|
||||||
|
* 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/pgmspace.h>
|
||||||
|
|
||||||
|
#include "info.h"
|
||||||
|
#include "uart.h"
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
extern FILE uart_stdout;
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(NO_INFO) && defined(__GNUC__)
|
||||||
|
|
||||||
|
#define info(format, args...) ((void)0)
|
||||||
|
|
||||||
|
#else
|
||||||
|
void info(char* format, ...) {
|
||||||
|
#ifdef NO_INFO
|
||||||
|
|
||||||
|
#else
|
||||||
|
va_list args;
|
||||||
|
va_start(args, format);
|
||||||
|
vprintf(format, args);
|
||||||
|
va_end(args);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef NO_INFO
|
||||||
|
uint8_t buffer_info[FORMAT_BUFFER_LEN];
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(NO_INFO) && defined(__GNUC__)
|
||||||
|
|
||||||
|
#define info(format, args...) ((void)0)
|
||||||
|
|
||||||
|
#else
|
||||||
|
void info_P(PGM_P format, ...) {
|
||||||
|
#ifdef NO_INFO
|
||||||
|
|
||||||
|
#else
|
||||||
|
strlcpy_P(buffer_info,format,FORMAT_BUFFER_LEN);
|
||||||
|
va_list args;
|
||||||
|
va_start(args, format);
|
||||||
|
vprintf(buffer_info, args);
|
||||||
|
va_end(args);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
53
avr/usbload/info.h
Normal file
53
avr/usbload/info.h
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
/*
|
||||||
|
* =====================================================================================
|
||||||
|
*
|
||||||
|
* ________ .__ __ ________ ____ ________
|
||||||
|
* \_____ \ __ __|__| ____ | | __\______ \ _______ _/_ |/ _____/
|
||||||
|
* / / \ \| | \ |/ ___\| |/ / | | \_/ __ \ \/ /| / __ \
|
||||||
|
* / \_/. \ | / \ \___| < | ` \ ___/\ / | \ |__\ \
|
||||||
|
* \_____\ \_/____/|__|\___ >__|_ \/_______ /\___ >\_/ |___|\_____ /
|
||||||
|
* \__> \/ \/ \/ \/ \/
|
||||||
|
*
|
||||||
|
* www.optixx.org
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Version: 1.0
|
||||||
|
* Created: 07/21/2009 03:32:16 PM
|
||||||
|
* Author: david@optixx.org
|
||||||
|
*
|
||||||
|
* =====================================================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef __INFO_H__
|
||||||
|
#define __INFO_H__
|
||||||
|
|
||||||
|
#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
|
||||||
|
arguments. We use this extension here to preprocess pmesg away. */
|
||||||
|
#define info(format, args...) ((void)0)
|
||||||
|
#else
|
||||||
|
void info(char *format, ...);
|
||||||
|
/* print a message, if it is considered significant enough.
|
||||||
|
Adapted from [K&R2], p. 174 */
|
||||||
|
#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
|
||||||
72
avr/usbload/irq.c
Normal file
72
avr/usbload/irq.c
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
/*
|
||||||
|
* =====================================================================================
|
||||||
|
*
|
||||||
|
* ________ .__ __ ________ ____ ________
|
||||||
|
* \_____ \ __ __|__| ____ | | __\______ \ _______ _/_ |/ _____/
|
||||||
|
* / / \ \| | \ |/ ___\| |/ / | | \_/ __ \ \/ /| / __ \
|
||||||
|
* / \_/. \ | / \ \___| < | ` \ ___/\ / | \ |__\ \
|
||||||
|
* \_____\ \_/____/|__|\___ >__|_ \/_______ /\___ >\_/ |___|\_____ /
|
||||||
|
* \__> \/ \/ \/ \/ \/
|
||||||
|
*
|
||||||
|
* www.optixx.org
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Version: 1.0
|
||||||
|
* Created: 07/21/2009 03:32:16 PM
|
||||||
|
* Author: david@optixx.org
|
||||||
|
*
|
||||||
|
* =====================================================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <avr/io.h>
|
||||||
|
#include <avr/interrupt.h> /* for sei() */
|
||||||
|
#include <avr/wdt.h>
|
||||||
|
|
||||||
|
|
||||||
|
#include "usbdrv.h"
|
||||||
|
#include "oddebug.h" /* This is also an example for using debug
|
||||||
|
* macros */
|
||||||
|
#include "debug.h"
|
||||||
|
#include "info.h"
|
||||||
|
#include "sram.h"
|
||||||
|
|
||||||
|
|
||||||
|
void (*jump_to_app) (void) = 0x0000;
|
||||||
|
|
||||||
|
void irq_init(){
|
||||||
|
cli();
|
||||||
|
PCMSK3 |=(1<<PCINT27);
|
||||||
|
PCICR |= (1<<PCIE3);
|
||||||
|
sei();
|
||||||
|
}
|
||||||
|
|
||||||
|
void irq_stop(){
|
||||||
|
cli();
|
||||||
|
PCMSK3 &=~(1<<PCINT27);
|
||||||
|
sei();
|
||||||
|
}
|
||||||
|
|
||||||
|
void leave_application(void)
|
||||||
|
{
|
||||||
|
cli();
|
||||||
|
usbDeviceDisconnect();
|
||||||
|
wdt_enable(WDTO_15MS);
|
||||||
|
while (1);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ISR (SIG_PIN_CHANGE3)
|
||||||
|
{
|
||||||
|
if (snes_reset_test()){
|
||||||
|
info_P(PSTR("Catch SNES reset button\n"));
|
||||||
|
info_P(PSTR("Set watchdog...\n"));
|
||||||
|
leave_application();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
25
avr/usbload/irq.h
Normal file
25
avr/usbload/irq.h
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
/*
|
||||||
|
* =====================================================================================
|
||||||
|
*
|
||||||
|
* ________ .__ __ ________ ____ ________
|
||||||
|
* \_____ \ __ __|__| ____ | | __\______ \ _______ _/_ |/ _____/
|
||||||
|
* / / \ \| | \ |/ ___\| |/ / | | \_/ __ \ \/ /| / __ \
|
||||||
|
* / \_/. \ | / \ \___| < | ` \ ___/\ / | \ |__\ \
|
||||||
|
* \_____\ \_/____/|__|\___ >__|_ \/_______ /\___ >\_/ |___|\_____ /
|
||||||
|
* \__> \/ \/ \/ \/ \/
|
||||||
|
*
|
||||||
|
* www.optixx.org
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Version: 1.0
|
||||||
|
* Created: 07/21/2009 03:32:16 PM
|
||||||
|
* Author: david@optixx.org
|
||||||
|
*
|
||||||
|
* =====================================================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef __IRQ_H__
|
||||||
|
#define __IRQ_H__
|
||||||
|
|
||||||
|
#endif
|
||||||
1953
avr/usbload/loader.c
Normal file
1953
avr/usbload/loader.c
Normal file
File diff suppressed because it is too large
Load Diff
11
avr/usbload/loader.h
Normal file
11
avr/usbload/loader.h
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
|
||||||
|
#ifndef __FIFO_H__
|
||||||
|
#define __FIFO_H__
|
||||||
|
|
||||||
|
#define ROM_BUFFER_SIZE 31091
|
||||||
|
#define ROM_HUFFMAN_SIZE 0
|
||||||
|
#define ROM_RLE_SIZE 31091
|
||||||
|
|
||||||
|
void irq_init();
|
||||||
|
|
||||||
|
#endif
|
||||||
424
avr/usbload/main.c
Normal file
424
avr/usbload/main.c
Normal file
@@ -0,0 +1,424 @@
|
|||||||
|
/*
|
||||||
|
* =====================================================================================
|
||||||
|
*
|
||||||
|
* ________ .__ __ ________ ____ ________
|
||||||
|
* \_____ \ __ __|__| ____ | | __\______ \ _______ _/_ |/ _____/
|
||||||
|
* / / \ \| | \ |/ ___\| |/ / | | \_/ __ \ \/ /| / __ \
|
||||||
|
* / \_/. \ | / \ \___| < | ` \ ___/\ / | \ |__\ \
|
||||||
|
* \_____\ \_/____/|__|\___ >__|_ \/_______ /\___ >\_/ |___|\_____ /
|
||||||
|
* \__> \/ \/ \/ \/ \/
|
||||||
|
*
|
||||||
|
* 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 <avr/pgmspace.h>
|
||||||
|
#include <avr/eeprom.h>
|
||||||
|
|
||||||
|
#include "usbdrv.h"
|
||||||
|
#include "oddebug.h"
|
||||||
|
#include "config.h"
|
||||||
|
#include "requests.h"
|
||||||
|
#include "uart.h"
|
||||||
|
#include "sram.h"
|
||||||
|
#include "debug.h"
|
||||||
|
#include "info.h"
|
||||||
|
#include "dump.h"
|
||||||
|
#include "crc.h"
|
||||||
|
#include "usb_bulk.h"
|
||||||
|
#include "timer.h"
|
||||||
|
#include "watchdog.h"
|
||||||
|
#include "rle.h"
|
||||||
|
#include "loader.h"
|
||||||
|
#include "command.h"
|
||||||
|
#include "shared_memory.h"
|
||||||
|
#include "testing.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
extern const char _rom[] PROGMEM;
|
||||||
|
extern FILE uart_stdout;
|
||||||
|
|
||||||
|
uint8_t debug_level = (DEBUG | DEBUG_USB | DEBUG_CRC | DEBUG_SHM);
|
||||||
|
|
||||||
|
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_percent;
|
||||||
|
uint8_t req_percent_last;
|
||||||
|
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;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
usbMsgLen_t usbFunctionSetup(uchar data[8])
|
||||||
|
{
|
||||||
|
|
||||||
|
usbRequest_t *rq = (void *) data;
|
||||||
|
uint8_t ret_len = 0;
|
||||||
|
|
||||||
|
if (rq->bRequest == USB_BULK_UPLOAD_INIT) {
|
||||||
|
|
||||||
|
req_bank = 0;
|
||||||
|
rx_remaining = 0;
|
||||||
|
debug_P(DEBUG_USB, PSTR("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;
|
||||||
|
req_percent = 0;
|
||||||
|
req_percent_last = 0;
|
||||||
|
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"),
|
||||||
|
req_bank_size, req_bank_cnt, req_addr_end);
|
||||||
|
|
||||||
|
shared_memory_write(SHARED_MEM_TX_CMD_BANK_COUNT, req_bank_cnt);
|
||||||
|
if (req_addr == 0x000000) {
|
||||||
|
timer_start();
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* -------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
} 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_P(DEBUG_USB,
|
||||||
|
PSTR("USB_BULK_UPLOAD_ADDR: req_bank=0x%02x addr=0x%08lx time=%.4f\n"),
|
||||||
|
req_bank, req_addr, timer_stop());
|
||||||
|
#else
|
||||||
|
debug_P(DEBUG_USB,
|
||||||
|
PSTR("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_write(SHARED_MEM_TX_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) {
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
req_percent = (uint32_t)( 100 * req_addr ) / req_addr_end;
|
||||||
|
if (req_percent!=req_percent_last){
|
||||||
|
//debug_P(DEBUG_USB,
|
||||||
|
// PSTR("USB_BULK_UPLOAD_ADDR: precent=%i\n", req_percent);
|
||||||
|
shared_memory_write(SHARED_MEM_TX_CMD_UPLOAD_PROGESS, req_percent);
|
||||||
|
sram_bulk_write_start(req_addr);
|
||||||
|
}
|
||||||
|
req_percent_last = req_percent;
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
if (req_addr && (req_addr % 0x1000) == 0) {
|
||||||
|
debug_P(DEBUG_USB,
|
||||||
|
PSTR("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);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if SHM_SCRATCHPAD
|
||||||
|
if (!shared_memory_scratchpad_region_save_helper(req_addr)){
|
||||||
|
debug_P(DEBUG_USB,
|
||||||
|
PSTR("USB_BULK_UPLOAD_NEXT: scratchpad_region_save_helper was dirty\n"));
|
||||||
|
sram_bulk_write_start(req_addr);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
if (req_addr && (req_addr % req_bank_size) == 0) {
|
||||||
|
#ifdef FLT_DEBUG
|
||||||
|
debug_P(DEBUG_USB,
|
||||||
|
PSTR("USB_BULK_UPLOAD_NEXT: req_bank=0x%02x addr=0x%08lx time=%.4f\n"),
|
||||||
|
req_bank, req_addr, timer_stop());
|
||||||
|
#else
|
||||||
|
debug_P(DEBUG_USB,
|
||||||
|
PSTR("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_write(SHARED_MEM_TX_CMD_BANK_CURRENT, req_bank);
|
||||||
|
sram_bulk_write_start(req_addr);
|
||||||
|
|
||||||
|
}
|
||||||
|
ret_len = USB_MAX_TRANS;
|
||||||
|
/*
|
||||||
|
* -------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
} else if (rq->bRequest == USB_BULK_UPLOAD_END) {
|
||||||
|
if (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_P(DEBUG_USB, PSTR("USB_BULK_UPLOAD_END:\n"));
|
||||||
|
req_state = REQ_STATUS_IDLE;
|
||||||
|
sram_bulk_write_end();
|
||||||
|
shared_memory_write(SHARED_MEM_TX_CMD_UPLOAD_END, 0);
|
||||||
|
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_P(DEBUG_USB, PSTR("USB_CRC: addr=0x%08lx \n"), req_addr);
|
||||||
|
crc_check_bulk_memory(0x000000, req_addr, req_bank_size);
|
||||||
|
ret_len = 0;
|
||||||
|
/*
|
||||||
|
* -------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
} else if (rq->bRequest == USB_MODE_SNES) {
|
||||||
|
req_state = REQ_STATUS_SNES;
|
||||||
|
debug_P(DEBUG_USB, PSTR("USB_MODE_SNES:\n"));
|
||||||
|
ret_len = 0;
|
||||||
|
/*
|
||||||
|
* -------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
} else if (rq->bRequest == USB_MODE_AVR) {
|
||||||
|
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_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_P(DEBUG_USB, PSTR("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_P(DEBUG_USB, PSTR("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;
|
||||||
|
}
|
||||||
|
|
||||||
|
usbMsgPtr = data_buffer;
|
||||||
|
return ret_len; /* default for not implemented requests: return no data back to host */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* -------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
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 */
|
||||||
|
led_on();
|
||||||
|
_delay_ms(15);
|
||||||
|
led_off();
|
||||||
|
_delay_ms(35);
|
||||||
|
}
|
||||||
|
led_on();
|
||||||
|
usbDeviceConnect();
|
||||||
|
info_P(PSTR("USB connect\n"));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void boot_startup_rom()
|
||||||
|
{
|
||||||
|
info_P(PSTR("Boot startup rom\n"));
|
||||||
|
info_P(PSTR("Activate AVR bus\n"));
|
||||||
|
avr_bus_active();
|
||||||
|
info_P(PSTR("IRQ off\n"));
|
||||||
|
snes_irq_lo();
|
||||||
|
snes_irq_off();
|
||||||
|
snes_lorom();
|
||||||
|
rle_decode(&_rom, ROM_BUFFER_SIZE, 0x000000);
|
||||||
|
info_P(PSTR("\n"));
|
||||||
|
#if 1
|
||||||
|
dump_memory(0x10000 - 0x100, 0x10000);
|
||||||
|
#endif
|
||||||
|
snes_hirom();
|
||||||
|
snes_wr_disable();
|
||||||
|
snes_bus_active();
|
||||||
|
info_P(PSTR("Activate SNES bus\n"));
|
||||||
|
send_reset();
|
||||||
|
_delay_ms(50);
|
||||||
|
send_reset();
|
||||||
|
_delay_ms(50);
|
||||||
|
}
|
||||||
|
|
||||||
|
void banner(){
|
||||||
|
uint8_t i;
|
||||||
|
for (i=0;i<40;i++)
|
||||||
|
info_P(PSTR("\n"));
|
||||||
|
info_P(PSTR(" ________ .__ __ ________ ____ ________\n"));
|
||||||
|
info_P(PSTR(" \\_____ \\ __ __|__| ____ | | __\\______ \\ _______ _/_ |/ _____/\n"));
|
||||||
|
info_P(PSTR(" / / \\ \\| | \\ |/ ___\\| |/ / | | \\_/ __ \\ \\/ /| / __ \\ \n"));
|
||||||
|
info_P(PSTR(" / \\_/. \\ | / \\ \\___| < | ` \\ ___/\\ / | \\ |__\\ \\ \n"));
|
||||||
|
info_P(PSTR(" \\_____\\ \\_/____/|__|\\___ >__|_ \\/_______ /\\___ >\\_/ |___|\\_____ / \n"));
|
||||||
|
info_P(PSTR(" \\__> \\/ \\/ \\/ \\/ \\/ \n"));
|
||||||
|
info_P(PSTR("\n"));
|
||||||
|
info_P(PSTR(" www.optixx.org\n"));
|
||||||
|
info_P(PSTR("\n"));
|
||||||
|
info_P(PSTR("System Hw: %s Sw: %s\n"),HW_VERSION,SW_VERSION);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void globals_init(){
|
||||||
|
req_addr = 0;
|
||||||
|
req_addr_end = 0;
|
||||||
|
req_state = REQ_STATUS_IDLE;
|
||||||
|
rx_remaining = 0;
|
||||||
|
tx_remaining = 0;
|
||||||
|
sync_errors = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
|
||||||
|
uart_init();
|
||||||
|
stdout = &uart_stdout;
|
||||||
|
banner();
|
||||||
|
system_init();
|
||||||
|
snes_reset_hi();
|
||||||
|
snes_reset_off();
|
||||||
|
irq_init();
|
||||||
|
boot_startup_rom();
|
||||||
|
globals_init();
|
||||||
|
usbInit();
|
||||||
|
usb_connect();
|
||||||
|
while (1) {
|
||||||
|
avr_bus_active();
|
||||||
|
info_P(PSTR("Activate AVR bus\n"));
|
||||||
|
snes_lorom();
|
||||||
|
info_P(PSTR("Disable SNES WR\n"));
|
||||||
|
snes_wr_disable();
|
||||||
|
sei();
|
||||||
|
info_P(PSTR("USB poll\n"));
|
||||||
|
while (req_state != REQ_STATUS_SNES) {
|
||||||
|
usbPoll();
|
||||||
|
}
|
||||||
|
shared_memory_write(SHARED_MEM_TX_CMD_TERMINATE, 0);
|
||||||
|
|
||||||
|
#if SHM_SCRATCHPAD
|
||||||
|
shared_memory_scratchpad_region_tx_restore();
|
||||||
|
shared_memory_scratchpad_region_rx_restore();
|
||||||
|
#endif
|
||||||
|
info_P(PSTR("USB poll done\n"));
|
||||||
|
set_rom_mode();
|
||||||
|
snes_wr_disable();
|
||||||
|
info_P(PSTR("Disable SNES WR\n"));
|
||||||
|
snes_bus_active();
|
||||||
|
info_P(PSTR("Activate SNES bus\n"));
|
||||||
|
irq_stop();
|
||||||
|
send_reset();
|
||||||
|
info_P(PSTR("Poll USB\n"));
|
||||||
|
while ((req_state != REQ_STATUS_AVR)) {
|
||||||
|
usbPoll();
|
||||||
|
|
||||||
|
#ifdef DO_IRQ
|
||||||
|
uint8_t i;
|
||||||
|
uint16_t irq_count = 0;
|
||||||
|
i = 10;
|
||||||
|
while (--i) {
|
||||||
|
_delay_ms(100);
|
||||||
|
}
|
||||||
|
info_P(PSTR("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_P(PSTR("Wait to switch to snes mode %i\n"), i);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (req_bank_size == 0x8000) {
|
||||||
|
snes_lorom();
|
||||||
|
} else {
|
||||||
|
snes_hirom();
|
||||||
|
}
|
||||||
|
snes_wr_disable();
|
||||||
|
info_P(PSTR("Disable SNES WR\n"));
|
||||||
|
snes_bus_active();
|
||||||
|
info_P(PSTR("Activate SNES bus\n"));
|
||||||
|
info_P(PSTR("Read 0x3000=%c\n"), c);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
irq_init();
|
||||||
|
boot_startup_rom();
|
||||||
|
globals_init();
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
42
avr/usbload/requests.h
Normal file
42
avr/usbload/requests.h
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
/*
|
||||||
|
* =====================================================================================
|
||||||
|
*
|
||||||
|
* ________ .__ __ ________ ____ ________
|
||||||
|
* \_____ \ __ __|__| ____ | | __\______ \ _______ _/_ |/ _____/
|
||||||
|
* / / \ \| | \ |/ ___\| |/ / | | \_/ __ \ \/ /| / __ \
|
||||||
|
* / \_/. \ | / \ \___| < | ` \ ___/\ / | \ |__\ \
|
||||||
|
* \_____\ \_/____/|__|\___ >__|_ \/_______ /\___ >\_/ |___|\_____ /
|
||||||
|
* \__> \/ \/ \/ \/ \/
|
||||||
|
*
|
||||||
|
* www.optixx.org
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Version: 1.0
|
||||||
|
* Created: 07/21/2009 03:32:16 PM
|
||||||
|
* Author: david@optixx.org
|
||||||
|
*
|
||||||
|
* =====================================================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef __REQUESTS_H__
|
||||||
|
#define __REQUESTS_H__
|
||||||
|
|
||||||
|
#define USB_UPLOAD_INIT 0
|
||||||
|
#define USB_UPLOAD_ADDR 1
|
||||||
|
|
||||||
|
#define USB_DOWNLOAD_INIT 2
|
||||||
|
#define USB_DOWNLOAD_ADDR 3
|
||||||
|
|
||||||
|
#define USB_CRC 4
|
||||||
|
#define USB_CRC_ADDR 5
|
||||||
|
|
||||||
|
#define USB_BULK_UPLOAD_INIT 6
|
||||||
|
#define USB_BULK_UPLOAD_ADDR 7
|
||||||
|
#define USB_BULK_UPLOAD_NEXT 8
|
||||||
|
#define USB_BULK_UPLOAD_END 9
|
||||||
|
#define USB_MODE_SNES 10
|
||||||
|
#define USB_MODE_AVR 11
|
||||||
|
#define USB_AVR_RESET 12
|
||||||
|
|
||||||
|
#endif /* __REQUESTS_H_INCLUDED__ */
|
||||||
103
avr/usbload/rle.c
Normal file
103
avr/usbload/rle.c
Normal file
@@ -0,0 +1,103 @@
|
|||||||
|
/*
|
||||||
|
* =====================================================================================
|
||||||
|
*
|
||||||
|
* ________ .__ __ ________ ____ ________
|
||||||
|
* \_____ \ __ __|__| ____ | | __\______ \ _______ _/_ |/ _____/
|
||||||
|
* / / \ \| | \ |/ ___\| |/ / | | \_/ __ \ \/ /| / __ \
|
||||||
|
* / \_/. \ | / \ \___| < | ` \ ___/\ / | \ |__\ \
|
||||||
|
* \_____\ \_/____/|__|\___ >__|_ \/_______ /\___ >\_/ |___|\_____ /
|
||||||
|
* \__> \/ \/ \/ \/ \/
|
||||||
|
*
|
||||||
|
* www.optixx.org
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Version: 1.0
|
||||||
|
* Created: 07/21/2009 03:32:16 PM
|
||||||
|
* Author: david@optixx.org
|
||||||
|
*
|
||||||
|
* =====================================================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <avr/io.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <avr/pgmspace.h> /* required by usbdrv.h */
|
||||||
|
#include <util/delay.h> /* for _delay_ms() */
|
||||||
|
#include <avr/interrupt.h> /* for sei() */
|
||||||
|
|
||||||
|
#include "sram.h"
|
||||||
|
#include "debug.h"
|
||||||
|
#include "info.h"
|
||||||
|
|
||||||
|
#define RUNCHAR 0x90
|
||||||
|
|
||||||
|
uint8_t rle_decode(PGM_VOID_P in_addr, int32_t in_len, uint32_t out_addr)
|
||||||
|
{
|
||||||
|
uint8_t in_byte, in_repeat, last_byte;
|
||||||
|
uint32_t out_len, out_len_left;
|
||||||
|
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 { \
|
||||||
|
if ( --in_len < 0 ) { \
|
||||||
|
return 1; \
|
||||||
|
} \
|
||||||
|
cli();\
|
||||||
|
b = pgm_read_byte((PGM_VOID_P)in_addr++); \
|
||||||
|
sei();\
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
#define OUTBYTE(b) \
|
||||||
|
do { \
|
||||||
|
sram_bulk_write(b);\
|
||||||
|
sram_bulk_write_next();\
|
||||||
|
out_addr++;\
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
INBYTE(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_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;
|
||||||
|
}
|
||||||
28
avr/usbload/rle.h
Normal file
28
avr/usbload/rle.h
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
/*
|
||||||
|
* =====================================================================================
|
||||||
|
*
|
||||||
|
* ________ .__ __ ________ ____ ________
|
||||||
|
* \_____ \ __ __|__| ____ | | __\______ \ _______ _/_ |/ _____/
|
||||||
|
* / / \ \| | \ |/ ___\| |/ / | | \_/ __ \ \/ /| / __ \
|
||||||
|
* / \_/. \ | / \ \___| < | ` \ ___/\ / | \ |__\ \
|
||||||
|
* \_____\ \_/____/|__|\___ >__|_ \/_______ /\___ >\_/ |___|\_____ /
|
||||||
|
* \__> \/ \/ \/ \/ \/
|
||||||
|
*
|
||||||
|
* www.optixx.org
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Version: 1.0
|
||||||
|
* Created: 07/21/2009 03:32:16 PM
|
||||||
|
* Author: david@optixx.org
|
||||||
|
*
|
||||||
|
* =====================================================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __RLE_H__
|
||||||
|
#define __RLE_H__
|
||||||
|
|
||||||
|
#include <avr/pgmspace.h>
|
||||||
|
|
||||||
|
uint8_t rle_decode(PGM_VOID_P in_addr, uint32_t in_len, uint32_t out_addr);
|
||||||
|
|
||||||
|
#endif
|
||||||
280
avr/usbload/shared_memory.c
Normal file
280
avr/usbload/shared_memory.c
Normal file
@@ -0,0 +1,280 @@
|
|||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* =====================================================================================
|
||||||
|
*
|
||||||
|
* ________ .__ __ ________ ____ ________
|
||||||
|
* \_____ \ __ __|__| ____ | | __\______ \ _______ _/_ |/ _____/
|
||||||
|
* / / \ \| | \ |/ ___\| |/ / | | \_/ __ \ \/ /| / __ \
|
||||||
|
* / \_/. \ | / \ \___| < | ` \ ___/\ / | \ |__\ \
|
||||||
|
* \_____\ \_/____/|__|\___ >__|_ \/_______ /\___ >\_/ |___|\_____ /
|
||||||
|
* \__> \/ \/ \/ \/ \/
|
||||||
|
*
|
||||||
|
* 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 "dump.h"
|
||||||
|
#include "info.h"
|
||||||
|
|
||||||
|
uint8_t irq_addr_lo;
|
||||||
|
uint8_t irq_addr_hi;
|
||||||
|
|
||||||
|
uint8_t scratchpad_state;
|
||||||
|
uint8_t scratchpad_cmd;
|
||||||
|
uint8_t scratchpad_payload;
|
||||||
|
|
||||||
|
uint8_t scratchpad_region_rx[SHARED_MEM_RX_LOC_SIZE];
|
||||||
|
uint8_t scratchpad_region_tx[SHARED_MEM_TX_LOC_SIZE];
|
||||||
|
|
||||||
|
uint8_t scratchpad_locked_rx = 1;
|
||||||
|
uint8_t scratchpad_locked_tx = 1;
|
||||||
|
|
||||||
|
|
||||||
|
uint8_t shared_memory_scratchpad_region_save_helper(uint32_t addr){
|
||||||
|
|
||||||
|
if(addr > (SHARED_MEM_TX_LOC_STATE + SHARED_MEM_TX_LOC_SIZE) && scratchpad_locked_tx){
|
||||||
|
debug_P(DEBUG_SHM, PSTR("shared_memory_scratchpad_region_save_helper: open tx addr=0x%06lx\n"),addr);
|
||||||
|
shared_memory_scratchpad_region_tx_save();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if(addr > (SHARED_MEM_RX_LOC_STATE + SHARED_MEM_RX_LOC_SIZE) && scratchpad_locked_rx){
|
||||||
|
debug_P(DEBUG_SHM, PSTR("shared_memory_scratchpad_region_save_helper: open rx addr=0x%06lx\n"),addr);
|
||||||
|
shared_memory_scratchpad_region_rx_save();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void shared_memory_scratchpad_region_tx_save()
|
||||||
|
{
|
||||||
|
#if 0
|
||||||
|
uint16_t crc;
|
||||||
|
crc = crc_check_bulk_memory((uint32_t)SHARED_MEM_TX_LOC_STATE,
|
||||||
|
(uint32_t)(SHARED_MEM_TX_LOC_STATE + SHARED_MEM_TX_LOC_SIZE), 0x8000);
|
||||||
|
debug_P(DEBUG_SHM, PSTR("shared_memory_scratchpad_region_tx_save: crc=%x\n"),crc);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
debug_P(DEBUG_SHM, PSTR("shared_memory_scratchpad_region_tx_save: unlock\n"));
|
||||||
|
sram_bulk_copy_into_buffer((uint32_t)SHARED_MEM_TX_LOC_STATE,scratchpad_region_tx,
|
||||||
|
(uint32_t)SHARED_MEM_TX_LOC_SIZE);
|
||||||
|
scratchpad_locked_tx = 0;
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
dump_packet(SHARED_MEM_TX_LOC_STATE, SHARED_MEM_TX_LOC_SIZE, scratchpad_region_tx);
|
||||||
|
dump_memory(SHARED_MEM_TX_LOC_STATE, SHARED_MEM_TX_LOC_STATE + SHARED_MEM_TX_LOC_SIZE);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void shared_memory_scratchpad_region_rx_save()
|
||||||
|
{
|
||||||
|
#if 0
|
||||||
|
uint16_t crc;
|
||||||
|
crc = crc_check_bulk_memory((uint32_t)SHARED_MEM_RX_LOC_STATE,
|
||||||
|
(uint32_t)(SHARED_MEM_RX_LOC_STATE + SHARED_MEM_RX_LOC_SIZE), 0x8000);
|
||||||
|
debug_P(DEBUG_SHM, PSTR("shared_memory_scratchpad_region_tx_save: crc=%x\n"),crc);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
debug_P(DEBUG_SHM, PSTR("shared_memory_scratchpad_region_rx_save: unlock\n"));
|
||||||
|
sram_bulk_copy_into_buffer((uint32_t)SHARED_MEM_RX_LOC_STATE,scratchpad_region_rx,
|
||||||
|
(uint32_t)SHARED_MEM_RX_LOC_SIZE);
|
||||||
|
scratchpad_locked_rx = 0;
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
dump_packet(SHARED_MEM_RX_LOC_STATE, SHARED_MEM_RX_LOC_SIZE, scratchpad_region_tx);
|
||||||
|
dump_memory(SHARED_MEM_RX_LOC_STATE, SHARED_MEM_RX_LOC_STATE + SHARED_MEM_RX_LOC_SIZE);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void shared_memory_scratchpad_region_tx_restore()
|
||||||
|
{
|
||||||
|
if (scratchpad_locked_tx)
|
||||||
|
return;
|
||||||
|
|
||||||
|
debug_P(DEBUG_SHM, PSTR("shared_memory_scratchpad_region_tx_restore: lock\n"));
|
||||||
|
sram_bulk_copy_from_buffer((uint32_t)SHARED_MEM_TX_LOC_STATE,scratchpad_region_tx,
|
||||||
|
(uint32_t)SHARED_MEM_TX_LOC_SIZE);
|
||||||
|
scratchpad_locked_tx = 1;
|
||||||
|
#if 0
|
||||||
|
dump_packet(SHARED_MEM_TX_LOC_STATE, SHARED_MEM_TX_LOC_SIZE, scratchpad_region_tx);
|
||||||
|
dump_memory(SHARED_MEM_TX_LOC_STATE, SHARED_MEM_TX_LOC_STATE + SHARED_MEM_TX_LOC_SIZE);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
uint16_t crc;
|
||||||
|
crc = crc_check_bulk_memory((uint32_t)SHARED_MEM_TX_LOC_STATE,
|
||||||
|
(uint32_t)(SHARED_MEM_TX_LOC_STATE + SHARED_MEM_TX_LOC_SIZE), 0x8000);
|
||||||
|
debug_P(DEBUG_SHM, PSTR("shared_memory_scratchpad_region_tx_restore: crc=%x\n"),crc);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void shared_memory_scratchpad_region_rx_restore()
|
||||||
|
{
|
||||||
|
if (scratchpad_locked_rx)
|
||||||
|
return;
|
||||||
|
debug_P(DEBUG_SHM, PSTR("shared_memory_scratchpad_region_tx_save: lock\n"));
|
||||||
|
sram_bulk_copy_from_buffer((uint32_t)SHARED_MEM_RX_LOC_STATE,scratchpad_region_rx,
|
||||||
|
(uint32_t)SHARED_MEM_RX_LOC_SIZE);
|
||||||
|
scratchpad_locked_rx = 1;
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
dump_packet(SHARED_MEM_RX_LOC_STATE, SHARED_MEM_TX_LOC_SIZE, scratchpad_region_rx);
|
||||||
|
dump_memory(SHARED_MEM_RX_LOC_STATE, SHARED_MEM_TX_LOC_STATE + SHARED_MEM_RX_LOC_SIZE);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
uint16_t crc;
|
||||||
|
crc = crc_check_bulk_memory((uint32_t)SHARED_MEM_RX_LOC_STATE,
|
||||||
|
(uint32_t)(SHARED_MEM_RX_LOC_STATE + SHARED_MEM_RX_LOC_SIZE), 0x8000);
|
||||||
|
debug_P(DEBUG_SHM, PSTR("shared_memory_scratchpad_region_rx_restore: crc=%x\n"),crc);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void shared_memory_scratchpad_tx_save()
|
||||||
|
{
|
||||||
|
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()
|
||||||
|
{
|
||||||
|
sram_write(SHARED_IRQ_LOC_LO, irq_addr_lo);
|
||||||
|
sram_write(SHARED_IRQ_LOC_HI, irq_addr_hi);
|
||||||
|
}
|
||||||
|
|
||||||
|
void shared_memory_write(uint8_t cmd, uint8_t value)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (scratchpad_locked_tx)
|
||||||
|
debug_P(DEBUG_SHM, PSTR("shared_memory_write: locked_tx\n"));
|
||||||
|
|
||||||
|
debug_P(DEBUG_SHM, PSTR("shared_memory_write: 0x%04x=0x%02x 0x%04x=0x%02x \n"),
|
||||||
|
SHARED_MEM_TX_LOC_CMD, cmd, SHARED_MEM_TX_LOC_PAYLOAD, value);
|
||||||
|
|
||||||
|
sram_bulk_addr_save();
|
||||||
|
shared_memory_scratchpad_tx_save();
|
||||||
|
shared_memory_irq_hook();
|
||||||
|
|
||||||
|
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_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_irq_lo();
|
||||||
|
snes_irq_off();
|
||||||
|
snes_lorom();
|
||||||
|
snes_wr_disable();
|
||||||
|
|
||||||
|
shared_memory_scratchpad_tx_restore();
|
||||||
|
shared_memory_irq_restore();
|
||||||
|
//sram_bulk_addr_restore();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
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 (scratchpad_locked_rx)
|
||||||
|
debug_P(DEBUG_SHM, PSTR("shared_memory_write: locked_tx\n"));
|
||||||
|
|
||||||
|
|
||||||
|
state = sram_read(SHARED_MEM_RX_LOC_STATE);
|
||||||
|
if (state != SHARED_MEM_RX_AVR_ACK){
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
sram_bulk_addr_save();
|
||||||
|
|
||||||
|
*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();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
73
avr/usbload/shared_memory.h
Normal file
73
avr/usbload/shared_memory.h
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
/*
|
||||||
|
* =====================================================================================
|
||||||
|
*
|
||||||
|
* ________ .__ __ ________ ____ ________
|
||||||
|
* \_____ \ __ __|__| ____ | | __\______ \ _______ _/_ |/ _____/
|
||||||
|
* / / \ \| | \ |/ ___\| |/ / | | \_/ __ \ \/ /| / __ \
|
||||||
|
* / \_/. \ | / \ \___| < | ` \ ___/\ / | \ |__\ \
|
||||||
|
* \_____\ \_/____/|__|\___ >__|_ \/_______ /\___ >\_/ |___|\_____ /
|
||||||
|
* \__> \/ \/ \/ \/ \/
|
||||||
|
*
|
||||||
|
* www.optixx.org
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Version: 1.0
|
||||||
|
* Created: 07/21/2009 03:32:16 PM
|
||||||
|
* Author: david@optixx.org
|
||||||
|
*
|
||||||
|
* =====================================================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __SHARED_MEMORY_H__
|
||||||
|
#define __SHARED_MEMORY_H__
|
||||||
|
|
||||||
|
|
||||||
|
#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_TX_CMD_BANK_COUNT 0x00
|
||||||
|
#define SHARED_MEM_TX_CMD_BANK_CURRENT 0x01
|
||||||
|
|
||||||
|
#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_RX_AVR_ACK 0xa5
|
||||||
|
#define SHARED_MEM_RX_AVR_RTS 0x5a
|
||||||
|
|
||||||
|
#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_LOC_LO 0x00fffe
|
||||||
|
#define SHARED_IRQ_LOC_HI 0x00ffff
|
||||||
|
|
||||||
|
/* Use COP IRQ LOC for hooked IRQ handler */
|
||||||
|
#define SHARED_IRQ_HANDLER_LO 0x0ffe4
|
||||||
|
#define SHARED_IRQ_HANDLER_HI 0x0ffe5
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
uint8_t shared_memory_scratchpad_region_save_helper(uint32_t addr);
|
||||||
|
void shared_memory_scratchpad_region_tx_save();
|
||||||
|
void shared_memory_scratchpad_region_tx_restore();
|
||||||
|
void shared_memory_scratchpad_region_rx_save();
|
||||||
|
void shared_memory_scratchpad_region_rx_restore();
|
||||||
|
void shared_memory_write(uint8_t cmd, uint8_t value);
|
||||||
|
int shared_memory_read(uint8_t *cmd, uint8_t *len,uint8_t *buffer);
|
||||||
|
|
||||||
|
#endif
|
||||||
327
avr/usbload/sram.c
Normal file
327
avr/usbload/sram.c
Normal file
@@ -0,0 +1,327 @@
|
|||||||
|
/*
|
||||||
|
* =====================================================================================
|
||||||
|
*
|
||||||
|
* ________ .__ __ ________ ____ ________
|
||||||
|
* \_____ \ __ __|__| ____ | | __\______ \ _______ _/_ |/ _____/
|
||||||
|
* / / \ \| | \ |/ ___\| |/ / | | \_/ __ \ \/ /| / __ \
|
||||||
|
* / \_/. \ | / \ \___| < | ` \ ___/\ / | \ |__\ \
|
||||||
|
* \_____\ \_/____/|__|\___ >__|_ \/_______ /\___ >\_/ |___|\_____ /
|
||||||
|
* \__> \/ \/ \/ \/ \/
|
||||||
|
*
|
||||||
|
* 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 "config.h"
|
||||||
|
#include "sram.h"
|
||||||
|
#include "uart.h"
|
||||||
|
#include "debug.h"
|
||||||
|
#include "info.h"
|
||||||
|
|
||||||
|
uint32_t addr_current = 0;
|
||||||
|
uint32_t addr_stash = 0;
|
||||||
|
|
||||||
|
void system_init(void)
|
||||||
|
{
|
||||||
|
/*-------------------------------------------------*/
|
||||||
|
|
||||||
|
DDRA = 0x00;
|
||||||
|
PORTA = 0x00;
|
||||||
|
|
||||||
|
/*-------------------------------------------------*/
|
||||||
|
|
||||||
|
DDRC |= ( (1 << AVR_ADDR_LATCH_PIN)
|
||||||
|
| (1 << AVR_ADDR_SCK_PIN)
|
||||||
|
| (1 << AVR_ADDR_SER_PIN)
|
||||||
|
| (1 << AVR_ADDR_LOAD_PIN)
|
||||||
|
| (1 << AVR_ADDR_UP_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_UP_PIN)
|
||||||
|
| (1 << AVR_ADDR_LOAD_PIN));
|
||||||
|
|
||||||
|
//| (1 << SNES_WR_PIN));
|
||||||
|
/*-------------------------------------------------*/
|
||||||
|
|
||||||
|
DDRB |= ( (1 << AVR_RD_PIN)
|
||||||
|
| (1 << AVR_WR_PIN)
|
||||||
|
| (1 << AVR_CS_PIN)
|
||||||
|
| (1 << SNES_IRQ_PIN));
|
||||||
|
|
||||||
|
|
||||||
|
PORTB |= ( (1 << AVR_RD_PIN)
|
||||||
|
| (1 << AVR_WR_PIN)
|
||||||
|
| (1 << AVR_CS_PIN)
|
||||||
|
| (1 << SNES_IRQ_PIN));
|
||||||
|
|
||||||
|
/*-------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
DDRD |= ( (1 << AVR_SNES_SW_PIN)
|
||||||
|
| (1 << HI_LOROM_SW_PIN)
|
||||||
|
| (1 << SNES_WR_EN_PIN));
|
||||||
|
|
||||||
|
PORTD |= (1 << HI_LOROM_SW_PIN);
|
||||||
|
|
||||||
|
PORTD &= ~((1 << AVR_SNES_SW_PIN)
|
||||||
|
| (1 << SNES_WR_EN_PIN));
|
||||||
|
|
||||||
|
/*-------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void sreg_set(uint32_t addr)
|
||||||
|
{
|
||||||
|
uint8_t i = 24;
|
||||||
|
debug_P(DEBUG_SREG, PSTR("sreg_set: addr=0x%08lx"),addr);
|
||||||
|
while(i--) {
|
||||||
|
if ((addr & ( 1L << i))){
|
||||||
|
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_P(DEBUG_SREG, PSTR("0"));
|
||||||
|
}
|
||||||
|
AVR_ADDR_SCK_PORT |= (1 << AVR_ADDR_SCK_PIN);
|
||||||
|
AVR_ADDR_SCK_PORT &= ~(1 << AVR_ADDR_SCK_PIN);
|
||||||
|
}
|
||||||
|
debug_P(DEBUG_SREG, PSTR("\n"));
|
||||||
|
AVR_ADDR_LATCH_PORT |= (1 << AVR_ADDR_LATCH_PIN);
|
||||||
|
AVR_ADDR_LATCH_PORT &= ~(1 << AVR_ADDR_LATCH_PIN);
|
||||||
|
|
||||||
|
counter_load();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void sram_bulk_addr_save()
|
||||||
|
{
|
||||||
|
addr_stash = addr_current;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void sram_bulk_addr_restore()
|
||||||
|
{
|
||||||
|
sreg_set(addr_stash);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void sram_bulk_read_start(uint32_t addr)
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
AVR_WR_PORT |= (1 << AVR_WR_PIN);
|
||||||
|
AVR_RD_PORT |= (1 << AVR_RD_PIN);
|
||||||
|
|
||||||
|
sreg_set(addr);
|
||||||
|
|
||||||
|
AVR_RD_PORT &= ~(1 << AVR_RD_PIN);
|
||||||
|
asm volatile ("nop");
|
||||||
|
asm volatile ("nop");
|
||||||
|
asm volatile ("nop");
|
||||||
|
asm volatile ("nop");
|
||||||
|
asm volatile ("nop");
|
||||||
|
asm volatile ("nop");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
asm volatile ("nop");
|
||||||
|
asm volatile ("nop");
|
||||||
|
asm volatile ("nop");
|
||||||
|
asm volatile ("nop");
|
||||||
|
asm volatile ("nop");
|
||||||
|
asm volatile ("nop");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline uint8_t sram_bulk_read(void)
|
||||||
|
{
|
||||||
|
return AVR_DATA_PIN;
|
||||||
|
}
|
||||||
|
|
||||||
|
void sram_bulk_read_end(void)
|
||||||
|
{
|
||||||
|
debug_P(DEBUG_SRAM, PSTR("sram_bulk_read_end:\n"));
|
||||||
|
|
||||||
|
AVR_RD_PORT |= (1 << AVR_RD_PIN);
|
||||||
|
AVR_CS_PORT |= (1 << AVR_CS_PIN);
|
||||||
|
avr_data_in();
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t sram_read(uint32_t addr)
|
||||||
|
{
|
||||||
|
uint8_t byte;
|
||||||
|
debug_P(DEBUG_SRAM_RAW, PSTR("sram_read: addr=0x%08lx\n\r"), addr);
|
||||||
|
|
||||||
|
avr_data_in();
|
||||||
|
|
||||||
|
AVR_CS_PORT &= ~(1 << AVR_CS_PIN);
|
||||||
|
|
||||||
|
AVR_WR_PORT |= (1 << AVR_WR_PIN);
|
||||||
|
AVR_RD_PORT |= (1 << AVR_RD_PIN);
|
||||||
|
|
||||||
|
sreg_set(addr);
|
||||||
|
|
||||||
|
AVR_RD_PORT &= ~(1 << AVR_RD_PIN);
|
||||||
|
|
||||||
|
asm volatile ("nop");
|
||||||
|
asm volatile ("nop");
|
||||||
|
asm volatile ("nop");
|
||||||
|
asm volatile ("nop");
|
||||||
|
asm volatile ("nop");
|
||||||
|
asm volatile ("nop");
|
||||||
|
|
||||||
|
byte = AVR_DATA_PIN;
|
||||||
|
|
||||||
|
AVR_RD_PORT |= (1 << AVR_RD_PIN);
|
||||||
|
AVR_CS_PORT |= (1 << AVR_CS_PIN);
|
||||||
|
|
||||||
|
avr_data_in();
|
||||||
|
return byte;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void sram_bulk_write_start(uint32_t addr)
|
||||||
|
{
|
||||||
|
debug_P(DEBUG_SRAM, PSTR("sram_bulk_write_start: addr=0x%08lx\n\r"), addr);
|
||||||
|
|
||||||
|
avr_data_out();
|
||||||
|
|
||||||
|
AVR_CS_PORT &= ~(1 << AVR_CS_PIN);
|
||||||
|
AVR_WR_PORT |= (1 << AVR_WR_PIN);
|
||||||
|
AVR_RD_PORT |= (1 << AVR_RD_PIN);
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void sram_bulk_write( uint8_t data)
|
||||||
|
{
|
||||||
|
AVR_DATA_PORT = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
void sram_bulk_write_end(void)
|
||||||
|
{
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void sram_write(uint32_t addr, uint8_t data)
|
||||||
|
{
|
||||||
|
debug_P(DEBUG_SRAM_RAW, PSTR("sram_write: addr=0x%08lx data=%x\n\r"), addr, data);
|
||||||
|
|
||||||
|
avr_data_out();
|
||||||
|
|
||||||
|
AVR_CS_PORT &= ~(1 << AVR_CS_PIN);
|
||||||
|
AVR_WR_PORT |= (1 << AVR_WR_PIN);
|
||||||
|
AVR_RD_PORT |= (1 << AVR_RD_PIN);
|
||||||
|
|
||||||
|
sreg_set(addr);
|
||||||
|
|
||||||
|
AVR_WR_PORT &= ~(1 << AVR_WR_PIN);
|
||||||
|
|
||||||
|
|
||||||
|
AVR_DATA_PORT = data;
|
||||||
|
|
||||||
|
|
||||||
|
AVR_WR_PORT |= (1 << AVR_WR_PIN);
|
||||||
|
asm volatile ("nop");
|
||||||
|
asm volatile ("nop");
|
||||||
|
asm volatile ("nop");
|
||||||
|
asm volatile ("nop");
|
||||||
|
asm volatile ("nop");
|
||||||
|
asm volatile ("nop");
|
||||||
|
AVR_CS_PORT |= (1 << AVR_CS_PIN);
|
||||||
|
|
||||||
|
avr_data_in();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void sram_bulk_copy_from_buffer(uint32_t addr, uint8_t * src, uint32_t len)
|
||||||
|
{
|
||||||
|
|
||||||
|
uint32_t i;
|
||||||
|
uint8_t *ptr = src;
|
||||||
|
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_end();
|
||||||
|
}
|
||||||
|
|
||||||
|
void sram_bulk_copy_into_buffer(uint32_t addr, uint8_t * dst, uint32_t len)
|
||||||
|
{
|
||||||
|
|
||||||
|
uint32_t i;
|
||||||
|
uint8_t *ptr = dst;
|
||||||
|
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();
|
||||||
|
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_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_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();
|
||||||
|
}
|
||||||
|
|
||||||
222
avr/usbload/sram.h
Normal file
222
avr/usbload/sram.h
Normal file
@@ -0,0 +1,222 @@
|
|||||||
|
/*
|
||||||
|
* =====================================================================================
|
||||||
|
*
|
||||||
|
* ________ .__ __ ________ ____ ________
|
||||||
|
* \_____ \ __ __|__| ____ | | __\______ \ _______ _/_ |/ _____/
|
||||||
|
* / / \ \| | \ |/ ___\| |/ / | | \_/ __ \ \/ /| / __ \
|
||||||
|
* / \_/. \ | / \ \___| < | ` \ ___/\ / | \ |__\ \
|
||||||
|
* \_____\ \_/____/|__|\___ >__|_ \/_______ /\___ >\_/ |___|\_____ /
|
||||||
|
* \__> \/ \/ \/ \/ \/
|
||||||
|
*
|
||||||
|
* www.optixx.org
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Version: 1.0
|
||||||
|
* Created: 07/21/2009 03:32:16 PM
|
||||||
|
* Author: david@optixx.org
|
||||||
|
*
|
||||||
|
* =====================================================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef __SRAM_H__
|
||||||
|
#define __SRAM_H__
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <avr/io.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ---------------------------- PORT A ---------------------------- */
|
||||||
|
|
||||||
|
#define AVR_DATA_PORT PORTA
|
||||||
|
#define AVR_DATA_DIR DDRA
|
||||||
|
#define AVR_DATA_PIN PINA
|
||||||
|
|
||||||
|
#define avr_data_in() ((AVR_DATA_DIR = 0x00),\
|
||||||
|
(AVR_DATA_PORT = 0x00))
|
||||||
|
|
||||||
|
#define avr_data_out() (AVR_DATA_DIR = 0xff)
|
||||||
|
|
||||||
|
|
||||||
|
/* ---------------------------- PORT B ---------------------------- */
|
||||||
|
|
||||||
|
#define AVR_PORT PORTB
|
||||||
|
#define AVR_DIR DDRB
|
||||||
|
#define AVR_RD_PORT PORTB
|
||||||
|
#define AVR_RD_DIR DDRB
|
||||||
|
#define AVR_RD_PIN PB2
|
||||||
|
|
||||||
|
#define avr_rd_hi() (AVR_RD_PORT |= (1 << AVR_RD_PIN))
|
||||||
|
#define avr_rd_lo() (AVR_RD_PORT &= ~(1 << AVR_RD_PIN))
|
||||||
|
|
||||||
|
#define AVR_WR_PORT PORTB
|
||||||
|
#define AVR_WR_DIR DDRB
|
||||||
|
#define AVR_WR_PIN PB1
|
||||||
|
|
||||||
|
#define avr_wr_hi() (AVR_WR_PORT |= (1 << AVR_WR_PIN))
|
||||||
|
#define avr_wr_lo() (AVR_WR_PORT &= ~(1 << AVR_WR_PIN))
|
||||||
|
|
||||||
|
#define AVR_CS_PORT PORTB
|
||||||
|
#define AVR_CS_DIR DDRB
|
||||||
|
#define AVR_CS_PIN PB0
|
||||||
|
|
||||||
|
#define avr_cs_hi() (AVR_CS_PORT |= (1 << AVR_CS_PIN))
|
||||||
|
#define avr_cs_lo() (AVR_CS_PORT &= ~(1 << AVR_CS_PIN))
|
||||||
|
|
||||||
|
#define SNES_IRQ_PORT PORTB
|
||||||
|
#define SNES_IRQ_DIR DDRB
|
||||||
|
#define SNES_IRQ_PIN PB3
|
||||||
|
|
||||||
|
|
||||||
|
#define snes_irq_on() (SNES_IRQ_DIR |= (1 << SNES_IRQ_PIN))
|
||||||
|
#define snes_irq_hi() (SNES_IRQ_PORT |= (1 << SNES_IRQ_PIN))
|
||||||
|
|
||||||
|
#define snes_irq_off() (SNES_IRQ_DIR &= ~(1 << SNES_IRQ_PIN))
|
||||||
|
#define snes_irq_lo() (SNES_IRQ_PORT &= ~(1 << SNES_IRQ_PIN))
|
||||||
|
|
||||||
|
|
||||||
|
/* ---------------------------- PORT C ---------------------------- */
|
||||||
|
|
||||||
|
#define AVR_ADDR_PORT PORTC
|
||||||
|
#define AVR_ADDR_DIR DDRC
|
||||||
|
#define AVR_ADDR_LATCH_PORT PORTC
|
||||||
|
#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_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_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_LOAD_PORT PORTC
|
||||||
|
#define AVR_ADDR_LOAD_DIR DDRC
|
||||||
|
#define AVR_ADDR_LOAD_PIN PC2
|
||||||
|
|
||||||
|
#define counter_load() ((AVR_ADDR_LOAD_PORT &= ~(1 << AVR_ADDR_LOAD_PIN)),\
|
||||||
|
(AVR_ADDR_LOAD_PORT |= (1 << AVR_ADDR_LOAD_PIN)))
|
||||||
|
|
||||||
|
#define AVR_BTLDR_EN_PORT PORTC
|
||||||
|
#define AVR_BTLDR_EN_DIR DDRC
|
||||||
|
#define AVR_BTLDR_EN_PIN PC1
|
||||||
|
|
||||||
|
#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
|
||||||
|
#define AVR_ADDR_UP_PIN PC0
|
||||||
|
|
||||||
|
#define counter_up() ((AVR_ADDR_UP_PORT &= ~(1 << AVR_ADDR_UP_PIN)),\
|
||||||
|
(AVR_ADDR_UP_PORT |= (1 << AVR_ADDR_UP_PIN)))
|
||||||
|
|
||||||
|
#define SNES_WR_PORT PORTC
|
||||||
|
#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)))
|
||||||
|
|
||||||
|
|
||||||
|
/* ---------------------------- PORT D ---------------------------- */
|
||||||
|
|
||||||
|
#define AVR_SNES_PORT PORTD
|
||||||
|
#define AVR_SNES_DIR DDRD
|
||||||
|
#define AVR_SNES_SW_PORT PORTD
|
||||||
|
#define AVR_SNES_SW_DIR DDRD
|
||||||
|
#define AVR_SNES_SW_PIN PD5
|
||||||
|
|
||||||
|
#define avr_bus_active() ((AVR_SNES_SW_PORT &= ~(1 << AVR_SNES_SW_PIN)),\
|
||||||
|
(HI_LOROM_SW_PORT |= (1 << HI_LOROM_SW_PIN)),\
|
||||||
|
(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)))
|
||||||
|
|
||||||
|
#define HI_LOROM_SW_PORT PORTD
|
||||||
|
#define HI_LOROM_SW_DIR DDRD
|
||||||
|
#define HI_LOROM_SW_PIN PD6
|
||||||
|
|
||||||
|
#define snes_hirom() (HI_LOROM_SW_PORT &= ~(1 << HI_LOROM_SW_PIN))
|
||||||
|
#define snes_lorom() (HI_LOROM_SW_PORT |= (1 << HI_LOROM_SW_PIN))
|
||||||
|
|
||||||
|
#define SNES_WR_EN_PORT PORTD
|
||||||
|
#define SNES_WR_EN_DIR DDRD
|
||||||
|
#define SNES_WR_EN_PIN PD7
|
||||||
|
|
||||||
|
#define snes_wr_disable() (SNES_WR_EN_PORT &= ~(1 << SNES_WR_EN_PIN))
|
||||||
|
|
||||||
|
#define snes_wr_enable() (SNES_WR_EN_PORT |= (1 << SNES_WR_EN_PIN))
|
||||||
|
|
||||||
|
#define SNES_RESET_PORT PORTD
|
||||||
|
#define SNES_RESET_DIR DDRD
|
||||||
|
#define SNES_RESET_PIN PD3
|
||||||
|
#define SNES_RESET_INP PIND
|
||||||
|
|
||||||
|
#define snes_reset_on() (SNES_RESET_DIR |= (1 << SNES_RESET_PIN))
|
||||||
|
#define snes_reset_hi() (SNES_RESET_PORT |= (1 << SNES_RESET_PIN))
|
||||||
|
|
||||||
|
#define snes_reset_off() (SNES_RESET_DIR &= ~(1 << SNES_RESET_PIN))
|
||||||
|
#define snes_reset_lo() (SNES_RESET_PORT &= ~(1 << SNES_RESET_PIN))
|
||||||
|
|
||||||
|
#define snes_reset_test() ((SNES_RESET_INP & (1 << SNES_RESET_PIN)) == 0)
|
||||||
|
|
||||||
|
#define MMC_PORT PORTB
|
||||||
|
#define MMC_DIR DDRB
|
||||||
|
|
||||||
|
#define MMC_MISO_PIN PB6
|
||||||
|
#define MMC_MOSI_PIN PB5
|
||||||
|
#define MMC_SCK_PIN PB7
|
||||||
|
#define MMC_CS_PIN PB4
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void system_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_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);
|
||||||
|
|
||||||
|
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_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
|
||||||
428
avr/usbload/tags
Normal file
428
avr/usbload/tags
Normal file
@@ -0,0 +1,428 @@
|
|||||||
|
!_TAG_FILE_FORMAT 2 /extended format; --format=1 will not append ;" to lines/
|
||||||
|
!_TAG_FILE_SORTED 1 /0=unsorted, 1=sorted, 2=foldcase/
|
||||||
|
!_TAG_PROGRAM_AUTHOR Darren Hiebert /dhiebert@users.sourceforge.net/
|
||||||
|
!_TAG_PROGRAM_NAME Exuberant Ctags //
|
||||||
|
!_TAG_PROGRAM_URL http://ctags.sourceforge.net /official site/
|
||||||
|
!_TAG_PROGRAM_VERSION 5.7 //
|
||||||
|
AVR_ADDR_DIR sram.h 103;" d
|
||||||
|
AVR_ADDR_DOWN_DIR sram.h 133;" d
|
||||||
|
AVR_ADDR_DOWN_PIN sram.h 134;" d
|
||||||
|
AVR_ADDR_DOWN_PORT sram.h 132;" d
|
||||||
|
AVR_ADDR_LATCH_DIR sram.h 105;" d
|
||||||
|
AVR_ADDR_LATCH_PIN sram.h 106;" d
|
||||||
|
AVR_ADDR_LATCH_PORT sram.h 104;" d
|
||||||
|
AVR_ADDR_LOAD_DIR sram.h 126;" d
|
||||||
|
AVR_ADDR_LOAD_PIN sram.h 127;" d
|
||||||
|
AVR_ADDR_LOAD_PORT sram.h 125;" d
|
||||||
|
AVR_ADDR_PORT sram.h 102;" d
|
||||||
|
AVR_ADDR_SCK_DIR sram.h 112;" d
|
||||||
|
AVR_ADDR_SCK_PIN sram.h 113;" d
|
||||||
|
AVR_ADDR_SCK_PORT sram.h 111;" d
|
||||||
|
AVR_ADDR_SER_DIR sram.h 119;" d
|
||||||
|
AVR_ADDR_SER_PIN sram.h 120;" d
|
||||||
|
AVR_ADDR_SER_PORT sram.h 118;" d
|
||||||
|
AVR_ADDR_UP_DIR sram.h 140;" d
|
||||||
|
AVR_ADDR_UP_PIN sram.h 141;" d
|
||||||
|
AVR_ADDR_UP_PORT sram.h 139;" d
|
||||||
|
AVR_CS_DIR sram.h 71;" d
|
||||||
|
AVR_CS_PIN sram.h 72;" d
|
||||||
|
AVR_CS_PORT sram.h 70;" d
|
||||||
|
AVR_DATA_DIR sram.h 35;" d
|
||||||
|
AVR_DATA_PIN sram.h 36;" d
|
||||||
|
AVR_DATA_PORT sram.h 34;" d
|
||||||
|
AVR_DIR sram.h 55;" d
|
||||||
|
AVR_PORT sram.h 54;" d
|
||||||
|
AVR_RD_DIR sram.h 57;" d
|
||||||
|
AVR_RD_PIN sram.h 58;" d
|
||||||
|
AVR_RD_PORT sram.h 56;" d
|
||||||
|
AVR_SNES_DIR sram.h 153;" d
|
||||||
|
AVR_SNES_PORT sram.h 152;" d
|
||||||
|
AVR_SNES_SW_DIR sram.h 155;" d
|
||||||
|
AVR_SNES_SW_PIN sram.h 156;" d
|
||||||
|
AVR_SNES_SW_PORT sram.h 154;" d
|
||||||
|
AVR_WR_DIR sram.h 64;" d
|
||||||
|
AVR_WR_PIN sram.h 65;" d
|
||||||
|
AVR_WR_PORT sram.h 63;" d
|
||||||
|
CR uart.h 25;" d
|
||||||
|
DEBOUNCE timer.c 44;" d file:
|
||||||
|
DEBUG config.h 25;" d
|
||||||
|
DEBUG_CRC config.h 31;" d
|
||||||
|
DEBUG_SHM config.h 32;" d
|
||||||
|
DEBUG_SRAM config.h 28;" d
|
||||||
|
DEBUG_SRAM_RAW config.h 29;" d
|
||||||
|
DEBUG_SREG config.h 30;" d
|
||||||
|
DEBUG_USB config.h 26;" d
|
||||||
|
DEBUG_USB_TRANS config.h 27;" d
|
||||||
|
FILE_MKDIR config.h 48;" d
|
||||||
|
FILE_RM config.h 49;" d
|
||||||
|
FILE_WRITE config.h 47;" d
|
||||||
|
Fat fat.h /^ extern struct Fat{ \/\/ fat daten (1.cluster, root-dir, dir usw.)$/;" s
|
||||||
|
File fat.h /^ extern struct File{ \/\/ datei infos$/;" s
|
||||||
|
HI_LOROM_SW_DIR sram.h 166;" d
|
||||||
|
HI_LOROM_SW_PIN sram.h 167;" d
|
||||||
|
HI_LOROM_SW_PORT sram.h 165;" d
|
||||||
|
INBYTE rle.c 44;" d file:
|
||||||
|
ISR timer.c /^ISR (SIG_OUTPUT_COMPARE1A)$/;" f
|
||||||
|
ISR uart.c /^ISR(USART0_RX_vect)$/;" f
|
||||||
|
LED_DIR sram.h 44;" d
|
||||||
|
LED_PIN sram.h 45;" d
|
||||||
|
LED_PORT sram.h 43;" d
|
||||||
|
MAX_CLUSTERS_IN_ROW fat.h 11;" d
|
||||||
|
MMC_CLK mmc.h 21;" d
|
||||||
|
MMC_CS mmc.h 18;" d
|
||||||
|
MMC_DI mmc.h 20;" d
|
||||||
|
MMC_DO mmc.h 19;" d
|
||||||
|
MMC_READ mmc.h 15;" d
|
||||||
|
MMC_READ mmc.h 24;" d
|
||||||
|
MMC_REG mmc.h 16;" d
|
||||||
|
MMC_REG mmc.h 25;" d
|
||||||
|
MMC_WRITE mmc.h 14;" d
|
||||||
|
MMC_WRITE mmc.h 23;" d
|
||||||
|
OCR1A timer.c 34;" d file:
|
||||||
|
OUTBYTE rle.c 54;" d file:
|
||||||
|
OVER_WRITE fat.h 10;" d
|
||||||
|
PROGMEM loader.c /^const char _rom[ROM_BUFFER_SIZE] PROGMEM = {$/;" v
|
||||||
|
REQ_STATUS_AVR config.h 40;" d
|
||||||
|
REQ_STATUS_BULK_NEXT config.h 37;" d
|
||||||
|
REQ_STATUS_BULK_UPLOAD config.h 36;" d
|
||||||
|
REQ_STATUS_CRC config.h 38;" d
|
||||||
|
REQ_STATUS_IDLE config.h 34;" d
|
||||||
|
REQ_STATUS_SNES config.h 39;" d
|
||||||
|
REQ_STATUS_UPLOAD config.h 35;" d
|
||||||
|
ROM_BUFFER_SIZE loader.h 5;" d
|
||||||
|
ROM_HUFFMAN_SIZE loader.h 6;" d
|
||||||
|
ROM_RLE_SIZE loader.h 7;" d
|
||||||
|
RUNCHAR rle.c 33;" d file:
|
||||||
|
SHARED_IRQ_HANDLER_HI shared_memory.h 59;" d
|
||||||
|
SHARED_IRQ_HANDLER_LO shared_memory.h 58;" d
|
||||||
|
SHARED_IRQ_LOC_HI shared_memory.h 55;" d
|
||||||
|
SHARED_IRQ_LOC_LO shared_memory.h 54;" d
|
||||||
|
SHARED_MEM_RX_AVR_ACK shared_memory.h 43;" d
|
||||||
|
SHARED_MEM_RX_AVR_RTS shared_memory.h 44;" d
|
||||||
|
SHARED_MEM_RX_CMD_FILESEL shared_memory.h 47;" d
|
||||||
|
SHARED_MEM_RX_CMD_PRINFT shared_memory.h 46;" d
|
||||||
|
SHARED_MEM_RX_LOC_CMD shared_memory.h 50;" d
|
||||||
|
SHARED_MEM_RX_LOC_LEN shared_memory.h 51;" d
|
||||||
|
SHARED_MEM_RX_LOC_PAYLOAD shared_memory.h 52;" d
|
||||||
|
SHARED_MEM_RX_LOC_STATE shared_memory.h 49;" d
|
||||||
|
SHARED_MEM_SWITCH_DELAY shared_memory.h 26;" d
|
||||||
|
SHARED_MEM_SWITCH_IRQ shared_memory.h 25;" d
|
||||||
|
SHARED_MEM_TX_CMD_BANK_COUNT shared_memory.h 31;" d
|
||||||
|
SHARED_MEM_TX_CMD_BANK_CURRENT shared_memory.h 32;" d
|
||||||
|
SHARED_MEM_TX_CMD_TERMINATE shared_memory.h 37;" d
|
||||||
|
SHARED_MEM_TX_CMD_UPLOAD_END shared_memory.h 35;" d
|
||||||
|
SHARED_MEM_TX_CMD_UPLOAD_PROGESS shared_memory.h 36;" d
|
||||||
|
SHARED_MEM_TX_CMD_UPLOAD_START shared_memory.h 34;" d
|
||||||
|
SHARED_MEM_TX_LOC_CMD shared_memory.h 40;" d
|
||||||
|
SHARED_MEM_TX_LOC_PAYLOAD shared_memory.h 41;" d
|
||||||
|
SHARED_MEM_TX_LOC_STATE shared_memory.h 39;" d
|
||||||
|
SHARED_MEM_TX_SNES_ACK shared_memory.h 28;" d
|
||||||
|
SHARED_MEM_TX_SNES_RTS shared_memory.h 29;" d
|
||||||
|
SMALL_FILE_SYSTEM config.h 50;" d
|
||||||
|
SMALL_FILE_SYSTEM fat.h 8;" d
|
||||||
|
SNES_IRQ_DIR sram.h 78;" d
|
||||||
|
SNES_IRQ_PIN sram.h 79;" d
|
||||||
|
SNES_IRQ_PORT sram.h 77;" d
|
||||||
|
SNES_RESET_DIR sram.h 89;" d
|
||||||
|
SNES_RESET_PIN sram.h 90;" d
|
||||||
|
SNES_RESET_PORT sram.h 88;" d
|
||||||
|
SNES_WR_DIR sram.h 147;" d
|
||||||
|
SNES_WR_EN_DIR sram.h 173;" d
|
||||||
|
SNES_WR_EN_PIN sram.h 174;" d
|
||||||
|
SNES_WR_EN_PORT sram.h 172;" d
|
||||||
|
SNES_WR_PIN sram.h 148;" d
|
||||||
|
SNES_WR_PORT sram.h 146;" d
|
||||||
|
SPI_Mode mmc.h 12;" d
|
||||||
|
TRANSFER_BUFFER_SIZE config.h 45;" d
|
||||||
|
USB_AVR_RESET requests.h 40;" d
|
||||||
|
USB_BULK_UPLOAD_ADDR requests.h 35;" d
|
||||||
|
USB_BULK_UPLOAD_END requests.h 37;" d
|
||||||
|
USB_BULK_UPLOAD_INIT requests.h 34;" d
|
||||||
|
USB_BULK_UPLOAD_NEXT requests.h 36;" d
|
||||||
|
USB_CFG_CHECK_CRC usbconfig.h 72;" d
|
||||||
|
USB_CFG_CHECK_DATA_TOGGLING usbconfig.h 211;" d
|
||||||
|
USB_CFG_CLOCK_KHZ usbconfig.h 65;" d
|
||||||
|
USB_CFG_DESCR_PROPS_CONFIGURATION usbconfig.h 346;" d
|
||||||
|
USB_CFG_DESCR_PROPS_DEVICE usbconfig.h 345;" d
|
||||||
|
USB_CFG_DESCR_PROPS_HID usbconfig.h 352;" d
|
||||||
|
USB_CFG_DESCR_PROPS_HID_REPORT usbconfig.h 353;" d
|
||||||
|
USB_CFG_DESCR_PROPS_STRINGS usbconfig.h 347;" d
|
||||||
|
USB_CFG_DESCR_PROPS_STRING_0 usbconfig.h 348;" d
|
||||||
|
USB_CFG_DESCR_PROPS_STRING_PRODUCT usbconfig.h 350;" d
|
||||||
|
USB_CFG_DESCR_PROPS_STRING_SERIAL_NUMBER usbconfig.h 351;" d
|
||||||
|
USB_CFG_DESCR_PROPS_STRING_VENDOR usbconfig.h 349;" d
|
||||||
|
USB_CFG_DESCR_PROPS_UNKNOWN usbconfig.h 354;" d
|
||||||
|
USB_CFG_DEVICE_CLASS usbconfig.h 266;" d
|
||||||
|
USB_CFG_DEVICE_ID usbconfig.h 231;" d
|
||||||
|
USB_CFG_DEVICE_NAME usbconfig.h 251;" d
|
||||||
|
USB_CFG_DEVICE_NAME_LEN usbconfig.h 252;" d
|
||||||
|
USB_CFG_DEVICE_SUBCLASS usbconfig.h 267;" d
|
||||||
|
USB_CFG_DEVICE_VERSION usbconfig.h 238;" d
|
||||||
|
USB_CFG_DMINUS_BIT usbconfig.h 52;" d
|
||||||
|
USB_CFG_DPLUS_BIT usbconfig.h 56;" d
|
||||||
|
USB_CFG_EP3_NUMBER usbconfig.h 106;" d
|
||||||
|
USB_CFG_HAVE_FLOWCONTROL usbconfig.h 161;" d
|
||||||
|
USB_CFG_HAVE_INTRIN_ENDPOINT usbconfig.h 95;" d
|
||||||
|
USB_CFG_HAVE_INTRIN_ENDPOINT3 usbconfig.h 100;" d
|
||||||
|
USB_CFG_HAVE_MEASURE_FRAME_LENGTH usbconfig.h 219;" d
|
||||||
|
USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH usbconfig.h 279;" d
|
||||||
|
USB_CFG_IMPLEMENT_FN_READ usbconfig.h 149;" d
|
||||||
|
USB_CFG_IMPLEMENT_FN_WRITE usbconfig.h 144;" d
|
||||||
|
USB_CFG_IMPLEMENT_FN_WRITEOUT usbconfig.h 155;" d
|
||||||
|
USB_CFG_IMPLEMENT_HALT usbconfig.h 116;" d
|
||||||
|
USB_CFG_INTERFACE_CLASS usbconfig.h 271;" d
|
||||||
|
USB_CFG_INTERFACE_PROTOCOL usbconfig.h 273;" d
|
||||||
|
USB_CFG_INTERFACE_SUBCLASS usbconfig.h 272;" d
|
||||||
|
USB_CFG_INTR_POLL_INTERVAL usbconfig.h 130;" d
|
||||||
|
USB_CFG_IOPORTNAME usbconfig.h 48;" d
|
||||||
|
USB_CFG_IS_SELF_POWERED usbconfig.h 135;" d
|
||||||
|
USB_CFG_LONG_TRANSFERS usbconfig.h 166;" d
|
||||||
|
USB_CFG_MAX_BUS_POWER usbconfig.h 139;" d
|
||||||
|
USB_CFG_SUPPRESS_INTR_CODE usbconfig.h 122;" d
|
||||||
|
USB_CFG_VENDOR_ID usbconfig.h 226;" d
|
||||||
|
USB_CFG_VENDOR_NAME usbconfig.h 241;" d
|
||||||
|
USB_CFG_VENDOR_NAME_LEN usbconfig.h 242;" d
|
||||||
|
USB_COUNT_SOF usbconfig.h 187;" d
|
||||||
|
USB_CRC requests.h 31;" d
|
||||||
|
USB_CRC_ADDR requests.h 32;" d
|
||||||
|
USB_CRC_CHECK config.h 43;" d
|
||||||
|
USB_DOWNLOAD_ADDR requests.h 29;" d
|
||||||
|
USB_DOWNLOAD_INIT requests.h 28;" d
|
||||||
|
USB_MAX_TRANS config.h 42;" d
|
||||||
|
USB_MODE_AVR requests.h 39;" d
|
||||||
|
USB_MODE_SNES requests.h 38;" d
|
||||||
|
USB_UPLOAD_ADDR requests.h 26;" d
|
||||||
|
USB_UPLOAD_INIT requests.h 25;" d
|
||||||
|
WGM12 timer.c 38;" d file:
|
||||||
|
WRITE fat.h 9;" d
|
||||||
|
XTAL timer.c 42;" d file:
|
||||||
|
_FAT_H fat.h 4;" d
|
||||||
|
_FILE_H file.h 6;" d
|
||||||
|
_HARDWARE_H hardware.h 7;" d
|
||||||
|
_MMC_H mmc.h 9;" d
|
||||||
|
__COMMAND_H__ command.h 23;" d
|
||||||
|
__CONFIH_H__ config.h 22;" d
|
||||||
|
__CRC_H__ crc.h 23;" d
|
||||||
|
__DEBUG_H__ debug.h 24;" d
|
||||||
|
__DUMP_H__ dump.h 23;" d
|
||||||
|
__FIFO_H__ fifo.h 21;" d
|
||||||
|
__FIFO_H__ loader.h 3;" d
|
||||||
|
__INFO_H__ info.h 24;" d
|
||||||
|
__REQUESTS_H__ requests.h 23;" d
|
||||||
|
__RLE_H__ rle.h 22;" d
|
||||||
|
__SHARED_MEMORY_H__ shared_memory.h 22;" d
|
||||||
|
__SRAM_H__ sram.h 24;" d
|
||||||
|
__TESTING_H__ testing.h 23;" d
|
||||||
|
__TIMER_H__ timer.h 22;" d
|
||||||
|
__UART_H__ uart.h 23;" d
|
||||||
|
__USB_BULK_H__ usb_bulk.h 23;" d
|
||||||
|
__WATCHDOG_H__ watchdog.h 27;" d
|
||||||
|
__usbconfig_h_included__ usbconfig.h 34;" d
|
||||||
|
_inline_fifo_get fifo.h /^static inline uint8_t _inline_fifo_get(fifo_t * f)$/;" f
|
||||||
|
_inline_fifo_put fifo.h /^static inline uint8_t _inline_fifo_put(fifo_t * f, const uint8_t data)$/;" f
|
||||||
|
adc_int uart.c /^ uint8_t adc_int:1;$/;" m struct:__anon2 file:
|
||||||
|
addr main.c /^uint32_t addr;$/;" v
|
||||||
|
addr_current sram.c /^uint32_t addr_current = 0;$/;" v
|
||||||
|
addr_stash sram.c /^uint32_t addr_stash = 0;$/;" v
|
||||||
|
attrib fat.h /^ unsigned char attrib; \/\/ 11,1 datei Attribut: 8=value name, 32=datei, 16=Verzeichniss, 15=linux kleingeschrieben eintrag$/;" m struct:File
|
||||||
|
avr_addr_latch_hi sram.h 108;" d
|
||||||
|
avr_addr_latch_lo sram.h 109;" d
|
||||||
|
avr_addr_sck_hi sram.h 115;" d
|
||||||
|
avr_addr_sck_lo sram.h 116;" d
|
||||||
|
avr_addr_ser_hi sram.h 122;" d
|
||||||
|
avr_addr_ser_lo sram.h 123;" d
|
||||||
|
avr_bus_active sram.h 158;" d
|
||||||
|
avr_cs_hi sram.h 74;" d
|
||||||
|
avr_cs_lo sram.h 75;" d
|
||||||
|
avr_data_in sram.h 38;" d
|
||||||
|
avr_data_out sram.h 41;" d
|
||||||
|
avr_rd_hi sram.h 60;" d
|
||||||
|
avr_rd_lo sram.h 61;" d
|
||||||
|
avr_wr_hi sram.h 67;" d
|
||||||
|
avr_wr_lo sram.h 68;" d
|
||||||
|
boot_startup_rom main.c /^void boot_startup_rom()$/;" f
|
||||||
|
bufferDirty fat.h /^ unsigned char bufferDirty; \/\/ puffer wurde beschrieben, sector muss geschrieben werden bevor er neu geladen wird$/;" m struct:Fat
|
||||||
|
cntOfBytes fat.h /^ unsigned int cntOfBytes; \/\/ -nicht direkt aus dem dateisystem- zäht geschriebene bytes eines sektors$/;" m struct:File
|
||||||
|
count fifo.h /^ uint8_t volatile count; \/\/ # Zeichen im Puffer$/;" m struct:__anon1
|
||||||
|
counter_down sram.h 136;" d
|
||||||
|
counter_load sram.h 129;" d
|
||||||
|
counter_up sram.h 143;" d
|
||||||
|
crc main.c /^uint16_t crc = 0;$/;" v
|
||||||
|
crc_check_bulk_memory crc.c /^uint16_t crc_check_bulk_memory(uint32_t bottom_addr, uint32_t top_addr, uint32_t bank_size)$/;" f
|
||||||
|
crc_check_memory_range crc.c /^uint16_t crc_check_memory_range(uint32_t start_addr, uint32_t size,uint8_t *buffer)$/;" f
|
||||||
|
crc_xmodem_update crc.c /^uint16_t crc_xmodem_update(uint16_t crc, uint8_t data)$/;" f
|
||||||
|
currentSectorNr fat.h /^ unsigned long int currentSectorNr;\/\/ aktuell geladener Sektor (in sector) \/\/beschleunigt wenn z.b 2* 512 byte puffer vorhanden, oder bei fat operationen im gleichen sektor$/;" m struct:Fat
|
||||||
|
dataDirSec fat.h /^ unsigned long int dataDirSec; \/\/ Sektor nr data area $/;" m struct:Fat
|
||||||
|
data_buffer main.c /^uint8_t data_buffer[4];$/;" v
|
||||||
|
debug debug.c /^void debug(int level, char* format, ...) {$/;" f
|
||||||
|
debug debug.h 34;" d
|
||||||
|
debug_level main.c /^uint8_t debug_level = (DEBUG | DEBUG_USB | DEBUG_CRC);$/;" v
|
||||||
|
dir fat.h /^ unsigned long int dir; \/\/ Direktory zeiger rootDir=='0' sonst(1.Cluster des dir; start auf root)$/;" m struct:Fat
|
||||||
|
do_crc crc.c /^uint16_t do_crc(uint8_t * data, uint16_t size)$/;" f
|
||||||
|
do_crc_update crc.c /^uint16_t do_crc_update(uint16_t crc, uint8_t * data, uint16_t size)$/;" f
|
||||||
|
dump_memory dump.c /^void dump_memory(uint32_t bottom_addr, uint32_t top_addr)$/;" f
|
||||||
|
dump_packet dump.c /^void dump_packet(uint32_t addr, uint32_t len, uint8_t * packet)$/;" f
|
||||||
|
endSectors fat.h /^ unsigned long int endSectors; $/;" m struct:Fat
|
||||||
|
fat fat.c /^struct Fat fat; \/\/ wichtige daten\/variablen der fat$/;" v typeref:struct:Fat
|
||||||
|
fatSec fat.h /^ unsigned long int fatSec; \/\/ Sektor nr fat area$/;" m struct:Fat
|
||||||
|
fatType fat.h /^ unsigned char fatType; \/\/ fat16 oder fat32 (16 oder 32)$/;" m struct:Fat
|
||||||
|
fat_cd fat.c /^unsigned char fat_cd(char name[]){$/;" f
|
||||||
|
fat_clustToSec fat.c /^unsigned long int fat_clustToSec(unsigned long int clust){$/;" f
|
||||||
|
fat_delClusterChain fat.c /^void fat_delClusterChain(unsigned long int startCluster){$/;" f
|
||||||
|
fat_getFatChainClustersInRow fat.c /^void fat_getFatChainClustersInRow(unsigned long int offsetCluster){$/;" f
|
||||||
|
fat_getFreeClustersInRow fat.c /^void fat_getFreeClustersInRow(unsigned long int offsetCluster){$/;" f
|
||||||
|
fat_getFreeRowOfCluster fat.c /^unsigned char fat_getFreeRowOfCluster(unsigned long secStart){$/;" f
|
||||||
|
fat_getFreeRowOfDir fat.c /^void fat_getFreeRowOfDir(unsigned long int dir){$/;" f
|
||||||
|
fat_getNextCluster fat.c /^unsigned long int fat_getNextCluster(unsigned long int oneCluster){ $/;" f
|
||||||
|
fat_initfat fat.c /^unsigned char fat_initfat(void){ $/;" f
|
||||||
|
fat_loadFatData fat.c /^unsigned char fat_loadFatData(unsigned long int sec){$/;" f
|
||||||
|
fat_loadFileDataFromCluster fat.c /^unsigned char fat_loadFileDataFromCluster(unsigned long int sec , char name[]){$/;" f
|
||||||
|
fat_loadFileDataFromDir fat.c /^unsigned char fat_loadFileDataFromDir(char name[]){ $/;" f
|
||||||
|
fat_loadRowOfSector fat.c /^unsigned char fat_loadRowOfSector(unsigned int row){$/;" f
|
||||||
|
fat_loadSector fat.c /^unsigned char fat_loadSector(unsigned long int sec){$/;" f
|
||||||
|
fat_makeFileEntry fat.c /^void fat_makeFileEntry(char name[],unsigned char attrib,unsigned long int length){$/;" f
|
||||||
|
fat_makeRowDataEntry fat.c /^void fat_makeRowDataEntry(unsigned int row,char name[],unsigned char attrib,unsigned long int cluster,unsigned long int length){$/;" f
|
||||||
|
fat_secToClust fat.c /^unsigned long int fat_secToClust(unsigned long int sec){$/;" f
|
||||||
|
fat_setCluster fat.c /^void fat_setCluster(unsigned long int cluster, unsigned long int content){ $/;" f
|
||||||
|
fat_setClusterChain fat.c /^void fat_setClusterChain(unsigned long int startCluster,unsigned int endCluster){$/;" f
|
||||||
|
fat_str fat.c /^char * fat_str(char *str){$/;" f
|
||||||
|
fat_writeSector fat.c /^unsigned char fat_writeSector(unsigned long int sec){ $/;" f
|
||||||
|
ffcd file.c /^unsigned char ffcd(char name[]){ $/;" f
|
||||||
|
ffcdLower file.c /^unsigned char ffcdLower(void){$/;" f
|
||||||
|
ffclose file.c /^unsigned char ffclose(void){$/;" f
|
||||||
|
ffls file.c /^void ffls(void){$/;" f
|
||||||
|
ffmkdir file.c /^void ffmkdir(char name[]){$/;" f
|
||||||
|
ffopen file.c /^unsigned char ffopen(char name[]){ $/;" f
|
||||||
|
ffread file.c /^inline unsigned char ffread(void){ $/;" f
|
||||||
|
ffrm file.c /^unsigned char ffrm(char name[]){ $/;" f
|
||||||
|
ffseek file.c /^void ffseek(unsigned long int offset){ $/;" f
|
||||||
|
ffwrite file.c /^inline void ffwrite(unsigned char c){$/;" f
|
||||||
|
ffwrites file.c /^inline void ffwrites(const char *s ){$/;" f
|
||||||
|
fifo_get_nowait fifo.c /^int fifo_get_nowait(fifo_t * f)$/;" f
|
||||||
|
fifo_get_wait fifo.c /^uint8_t fifo_get_wait(fifo_t * f)$/;" f
|
||||||
|
fifo_init fifo.c /^void fifo_init(fifo_t * f, uint8_t * buffer, const uint8_t size)$/;" f
|
||||||
|
fifo_put fifo.c /^uint8_t fifo_put(fifo_t * f, const uint8_t data)$/;" f
|
||||||
|
fifo_t fifo.h /^} fifo_t;$/;" t typeref:struct:__anon1
|
||||||
|
file fat.c /^struct File file; \/\/ wichtige dateibezogene daten\/variablen$/;" v typeref:struct:File
|
||||||
|
fileUpdate file.c /^void fileUpdate(void){$/;" f
|
||||||
|
firstCluster fat.h /^ unsigned long int firstCluster; \/\/ 20,2 \/26,2 datei 1.cluster hi,low(möglicherweise der einzige) (4-byte)$/;" m struct:File
|
||||||
|
info info.c /^void info(char* format, ...) {$/;" f
|
||||||
|
info info.c 34;" d file:
|
||||||
|
info info.h 34;" d
|
||||||
|
intflags uart.c /^} intflags;$/;" v typeref:struct:__anon2
|
||||||
|
irq_addr_hi shared_memory.c /^uint8_t irq_addr_hi;$/;" v
|
||||||
|
irq_addr_lo shared_memory.c /^uint8_t irq_addr_lo;$/;" v
|
||||||
|
lastCluster fat.h /^ unsigned long int lastCluster; \/\/ -nicht direkt aus dem dateisystem- letzter cluster der ersten kette$/;" m struct:File
|
||||||
|
led_off sram.h 49;" d
|
||||||
|
led_on sram.h 47;" d
|
||||||
|
length fat.h /^ unsigned long int length; \/\/ 28,4 datei Länge (4-byte)$/;" m struct:File
|
||||||
|
lsRowsOfClust file.c /^void lsRowsOfClust (unsigned long int start_sec){$/;" f
|
||||||
|
main main.c /^int main(void)$/;" f
|
||||||
|
mmc_disable mmc.h 38;" d
|
||||||
|
mmc_enable mmc.h 40;" d
|
||||||
|
mmc_init mmc.c /^uint8_t mmc_init()$/;" f
|
||||||
|
mmc_read_block mmc.c /^void mmc_read_block(uint8_t * cmd, uint8_t * Buffer, uint16_t Bytes)$/;" f
|
||||||
|
mmc_read_byte mmc.c /^uint8_t mmc_read_byte(void)$/;" f
|
||||||
|
mmc_read_cid mmc.c /^uint8_t mmc_read_cid(uint8_t * Buffer)$/;" f
|
||||||
|
mmc_read_csd mmc.c /^uint8_t mmc_read_csd(uint8_t * Buffer)$/;" f
|
||||||
|
mmc_read_sector mmc.c /^uint8_t mmc_read_sector(uint32_t addr, uint8_t * Buffer)$/;" f
|
||||||
|
mmc_write_byte mmc.c /^void mmc_write_byte(uint8_t Byte)$/;" f
|
||||||
|
mmc_write_command mmc.c /^uint8_t mmc_write_command(uint8_t * cmd)$/;" f
|
||||||
|
mmc_write_sector mmc.c /^uint8_t mmc_write_sector(uint32_t addr, uint8_t * Buffer)$/;" f
|
||||||
|
name fat.h /^ unsigned char name[13]; \/\/ 0,10 datei Name.ext (8.3 = max 11)(MUSS unsigned char weil E5)$/;" m struct:File
|
||||||
|
nop mmc.h 42;" d
|
||||||
|
pread fifo.h /^ uint8_t *pread; \/\/ Lesezeiger$/;" m struct:__anon1
|
||||||
|
prescaler timer.c /^uint16_t prescaler;$/;" v
|
||||||
|
pwrite fifo.h /^ uint8_t *pwrite; \/\/ Schreibzeiger$/;" m struct:__anon1
|
||||||
|
read2end fifo.h /^ uint8_t read2end, write2end; \/\/ # Zeichen bis zum Überlauf Lese-\/Schreibzeiger$/;" m struct:__anon1
|
||||||
|
read_buffer main.c /^uint8_t read_buffer[TRANSFER_BUFFER_SIZE];$/;" v
|
||||||
|
req_addr main.c /^uint32_t req_addr = 0;$/;" v
|
||||||
|
req_addr_end main.c /^uint32_t req_addr_end = 0;$/;" v
|
||||||
|
req_bank main.c /^uint8_t req_bank;$/;" v
|
||||||
|
req_bank_cnt main.c /^uint16_t req_bank_cnt;$/;" v
|
||||||
|
req_bank_size main.c /^uint32_t req_bank_size;$/;" v
|
||||||
|
req_percent main.c /^uint8_t req_percent;$/;" v
|
||||||
|
req_percent_last main.c /^uint8_t req_percent_last;$/;" v
|
||||||
|
req_size main.c /^uint32_t req_size;$/;" v
|
||||||
|
req_state main.c /^uint8_t req_state = REQ_STATUS_IDLE;$/;" v
|
||||||
|
rle_decode rle.c /^uint8_t rle_decode(PGM_VOID_P in_addr, int32_t in_len, uint32_t out_addr)$/;" f
|
||||||
|
rootDir fat.h /^ unsigned long int rootDir; \/\/ Sektor(f16)\/Cluster(f32) nr root directory$/;" m struct:Fat
|
||||||
|
row fat.h /^ unsigned char row; \/\/ reihe im sektor in der die datei infos stehen (reihe 0-15)$/;" m struct:File
|
||||||
|
rx_int uart.c /^ uint8_t rx_int:1;$/;" m struct:__anon2 file:
|
||||||
|
rx_remaining main.c /^uint8_t rx_remaining = 0;$/;" v
|
||||||
|
rxbuff uart.c /^volatile char rxbuff;$/;" v
|
||||||
|
scratchpad_cmd shared_memory.c /^uint8_t scratchpad_cmd;$/;" v
|
||||||
|
scratchpad_payload shared_memory.c /^uint8_t scratchpad_payload;$/;" v
|
||||||
|
scratchpad_state shared_memory.c /^uint8_t scratchpad_state;$/;" v
|
||||||
|
secPerClust fat.h /^ unsigned char secPerClust; \/\/ anzahl der sektoren pro cluster$/;" m struct:Fat
|
||||||
|
second timer.c /^uint16_t volatile second; \/\/ count seconds$/;" v
|
||||||
|
sector fat.h /^ unsigned char sector[512]; \/\/ der puffer für sektoren !$/;" m struct:Fat
|
||||||
|
seek fat.h /^ unsigned long int seek; \/\/ schreib position in der datei$/;" m struct:File
|
||||||
|
send_irq command.c /^void send_irq()$/;" f
|
||||||
|
send_reset command.c /^void send_reset()$/;" f
|
||||||
|
set_rom_mode command.c /^void set_rom_mode()$/;" f
|
||||||
|
shared_memory_irq_hook shared_memory.c /^void shared_memory_irq_hook()$/;" f
|
||||||
|
shared_memory_irq_restore shared_memory.c /^void shared_memory_irq_restore()$/;" f
|
||||||
|
shared_memory_read shared_memory.c /^int shared_memory_read(uint8_t *cmd, uint8_t *len,uint8_t *buffer)$/;" f
|
||||||
|
shared_memory_scratchpad_tx_restore shared_memory.c /^void shared_memory_scratchpad_tx_restore()$/;" f
|
||||||
|
shared_memory_scratchpad_tx_save shared_memory.c /^void shared_memory_scratchpad_tx_save()$/;" f
|
||||||
|
shared_memory_write shared_memory.c /^void shared_memory_write(uint8_t cmd, uint8_t value)$/;" f
|
||||||
|
shared_memory_yield shared_memory.c /^void shared_memory_yield()$/;" f
|
||||||
|
size fifo.h /^ uint8_t size; \/\/ Puffer-Größe$/;" m struct:__anon1
|
||||||
|
snes_bus_active sram.h 162;" d
|
||||||
|
snes_hirom sram.h 169;" d
|
||||||
|
snes_irq_hi sram.h 83;" d
|
||||||
|
snes_irq_lo sram.h 86;" d
|
||||||
|
snes_irq_off sram.h 85;" d
|
||||||
|
snes_irq_on sram.h 82;" d
|
||||||
|
snes_lorom sram.h 170;" d
|
||||||
|
snes_reset_hi sram.h 94;" d
|
||||||
|
snes_reset_lo sram.h 97;" d
|
||||||
|
snes_reset_off sram.h 96;" d
|
||||||
|
snes_reset_on sram.h 93;" d
|
||||||
|
snes_wr_disable sram.h 176;" d
|
||||||
|
snes_wr_enable sram.h 178;" d
|
||||||
|
soft_reset watchdog.h 32;" d
|
||||||
|
sram_bulk_addr_restore sram.c /^inline void sram_bulk_addr_restore()$/;" f
|
||||||
|
sram_bulk_addr_save sram.c /^inline void sram_bulk_addr_save()$/;" f
|
||||||
|
sram_bulk_copy sram.c /^void sram_bulk_copy_from_buffer(uint32_t addr, uint8_t * src, uint32_t len)$/;" f
|
||||||
|
sram_bulk_read sram.c /^inline uint8_t sram_bulk_read(void)$/;" f
|
||||||
|
sram_bulk_copy_into_buffer sram.c /^void sram_bulk_copy_into_buffer(uint32_t addr, uint8_t * dst, uint32_t len)$/;" f
|
||||||
|
sram_bulk_read_end sram.c /^void sram_bulk_read_end(void)$/;" f
|
||||||
|
sram_bulk_read_next sram.c /^inline void sram_bulk_read_next(void)$/;" f
|
||||||
|
sram_bulk_read_start sram.c /^void sram_bulk_read_start(uint32_t addr)$/;" f
|
||||||
|
sram_bulk_set sram.c /^void sram_bulk_set(uint32_t addr, uint32_t len,uint8_t value){$/;" f
|
||||||
|
sram_bulk_write sram.c /^inline void sram_bulk_write( uint8_t data)$/;" f
|
||||||
|
sram_bulk_write_end sram.c /^void sram_bulk_write_end(void)$/;" f
|
||||||
|
sram_bulk_write_next sram.c /^inline void sram_bulk_write_next(void)$/;" f
|
||||||
|
sram_bulk_write_start sram.c /^void sram_bulk_write_start(uint32_t addr)$/;" f
|
||||||
|
sram_read sram.c /^uint8_t sram_read(uint32_t addr)$/;" f
|
||||||
|
sram_write sram.c /^void sram_write(uint32_t addr, uint8_t data)$/;" f
|
||||||
|
sreg_set sram.c /^void sreg_set(uint32_t addr)$/;" f
|
||||||
|
startSectors fat.h /^ unsigned long int startSectors; \/\/ der erste sektor in einer reihe (freie oder verkettete)$/;" m struct:Fat
|
||||||
|
sync_errors main.c /^uint16_t sync_errors = 0;$/;" v
|
||||||
|
system_init sram.c /^void system_init(void)$/;" f
|
||||||
|
test_bulk_read_write testing.c /^void test_bulk_read_write()$/;" f
|
||||||
|
test_crc testing.c /^void test_crc()$/;" f
|
||||||
|
test_non_zero_memory testing.c /^void test_non_zero_memory(uint32_t bottom_addr, uint32_t top_addr)$/;" f
|
||||||
|
test_read_write testing.c /^void test_read_write()$/;" f
|
||||||
|
test_sdcard testing.c /^void test_sdcard(void){$/;" f
|
||||||
|
timer_start timer.c /^void timer_start( void )$/;" f
|
||||||
|
timer_stop_int timer.c /^uint16_t timer_stop_int(void)$/;" f
|
||||||
|
tmr_int uart.c /^ uint8_t tmr_int:1;$/;" m struct:__anon2 file:
|
||||||
|
tx_buffer main.c /^uint8_t tx_buffer[32];$/;" v
|
||||||
|
tx_remaining main.c /^uint8_t tx_remaining = 0;$/;" v
|
||||||
|
uart_init uart.c /^void uart_init(void)$/;" f
|
||||||
|
uart_putc uart.c /^void uart_putc(uint8_t c)$/;" f
|
||||||
|
uart_puts uart.c /^void uart_puts(const char *s)$/;" f
|
||||||
|
uart_puts_P uart.c /^void uart_puts_P(PGM_P s)$/;" f
|
||||||
|
uart_stdout uart.c /^FILE uart_stdout = FDEV_SETUP_STREAM(uart_stream, NULL, _FDEV_SETUP_WRITE);$/;" v
|
||||||
|
uart_stream uart.c /^static int uart_stream(char c, FILE * stream)$/;" f file:
|
||||||
|
uint timer.c 47;" d file:
|
||||||
|
uint8_t timer.c 46;" d file:
|
||||||
|
usbFunctionRead usb_bulk.c /^uint8_t usbFunctionRead(uint8_t * data, uint8_t len)$/;" f
|
||||||
|
usbFunctionSetup main.c /^usbMsgLen_t usbFunctionSetup(uchar data[8])$/;" f
|
||||||
|
usbFunctionWrite usb_bulk.c /^uint8_t usbFunctionWrite(uint8_t * data, uint8_t len)$/;" f
|
||||||
|
usb_connect main.c /^void usb_connect()$/;" f
|
||||||
|
wdt_init watchdog.c /^void wdt_init(void)$/;" f
|
||||||
|
write2end fifo.h /^ uint8_t read2end, write2end; \/\/ # Zeichen bis zum Überlauf Lese-\/Schreibzeiger$/;" m struct:__anon1
|
||||||
106
avr/usbload/testing.c
Normal file
106
avr/usbload/testing.c
Normal file
@@ -0,0 +1,106 @@
|
|||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* =====================================================================================
|
||||||
|
*
|
||||||
|
* ________ .__ __ ________ ____ ________
|
||||||
|
* \_____ \ __ __|__| ____ | | __\______ \ _______ _/_ |/ _____/
|
||||||
|
* / / \ \| | \ |/ ___\| |/ / | | \_/ __ \ \/ /| / __ \
|
||||||
|
* / \_/. \ | / \ \___| < | ` \ ___/\ / | \ |__\ \
|
||||||
|
* \_____\ \_/____/|__|\___ >__|_ \/_______ /\___ >\_/ |___|\_____ /
|
||||||
|
* \__> \/ \/ \/ \/ \/
|
||||||
|
*
|
||||||
|
* 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"
|
||||||
|
|
||||||
|
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_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
|
||||||
94
avr/usbload/timer.c
Normal file
94
avr/usbload/timer.c
Normal file
@@ -0,0 +1,94 @@
|
|||||||
|
/*
|
||||||
|
* =====================================================================================
|
||||||
|
*
|
||||||
|
* ________ .__ __ ________ ____ ________
|
||||||
|
* \_____ \ __ __|__| ____ | | __\______ \ _______ _/_ |/ _____/
|
||||||
|
* / / \ \| | \ |/ ___\| |/ / | | \_/ __ \ \/ /| / __ \
|
||||||
|
* / \_/. \ | / \ \___| < | ` \ ___/\ / | \ |__\ \
|
||||||
|
* \_____\ \_/____/|__|\___ >__|_ \/_______ /\___ >\_/ |___|\_____ /
|
||||||
|
* \__> \/ \/ \/ \/ \/
|
||||||
|
*
|
||||||
|
* 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/io.h>
|
||||||
|
#include <avr/interrupt.h> /* for sei() */
|
||||||
|
|
||||||
|
#include "debug.h"
|
||||||
|
#include "info.h"
|
||||||
|
#include "sram.h"
|
||||||
|
|
||||||
|
|
||||||
|
extern uint8_t snes_reset_line;
|
||||||
|
|
||||||
|
#ifndef OCR1A
|
||||||
|
#define OCR1A OCR1 // 2313 support
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef WGM12
|
||||||
|
#define WGM12 CTC1 // 2313 support
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//#define XTAL 11059201L // nominal value
|
||||||
|
#define XTAL 20000000UL
|
||||||
|
|
||||||
|
#define DEBOUNCE 500L // debounce clock (256Hz = 4msec)
|
||||||
|
|
||||||
|
#define uint8_t unsigned char
|
||||||
|
#define uint unsigned int
|
||||||
|
|
||||||
|
uint16_t prescaler;
|
||||||
|
uint16_t volatile second; // count seconds
|
||||||
|
|
||||||
|
|
||||||
|
ISR (SIG_OUTPUT_COMPARE1A)
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
#if XTAL % DEBOUNCE // bei rest
|
||||||
|
OCR1A = 20000000UL / DEBOUNCE - 1; // compare DEBOUNCE - 1 times
|
||||||
|
#endif
|
||||||
|
if( --prescaler == 0 ){
|
||||||
|
prescaler = (uint16_t)DEBOUNCE;
|
||||||
|
second++; // exact one second over
|
||||||
|
#if XTAL % DEBOUNCE // handle remainder
|
||||||
|
OCR1A = XTAL / DEBOUNCE + XTAL % DEBOUNCE - 1; // compare once per second
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void timer_start( void )
|
||||||
|
{
|
||||||
|
TCCR1B = (1<<WGM12) | (1<<CS10); // divide by 1
|
||||||
|
// clear on compare
|
||||||
|
OCR1A = XTAL / DEBOUNCE - 1UL; // Output Compare Register
|
||||||
|
TCNT1 = 0; // Timmer startet mit 0
|
||||||
|
second = 0;
|
||||||
|
prescaler = (uint16_t)DEBOUNCE; //software teiler
|
||||||
|
TIMSK1 = 1<<OCIE1A; // beim Vergleichswertes Compare Match
|
||||||
|
// Interrupt (SIG_OUTPUT_COMPARE1A)
|
||||||
|
sei();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t timer_stop_int(void)
|
||||||
|
{
|
||||||
|
uint16_t t = ((DEBOUNCE - prescaler) / DEBOUNCE ) + second;
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
29
avr/usbload/timer.h
Normal file
29
avr/usbload/timer.h
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
/*
|
||||||
|
* =====================================================================================
|
||||||
|
*
|
||||||
|
* ________ .__ __ ________ ____ ________
|
||||||
|
* \_____ \ __ __|__| ____ | | __\______ \ _______ _/_ |/ _____/
|
||||||
|
* / / \ \| | \ |/ ___\| |/ / | | \_/ __ \ \/ /| / __ \
|
||||||
|
* / \_/. \ | / \ \___| < | ` \ ___/\ / | \ |__\ \
|
||||||
|
* \_____\ \_/____/|__|\___ >__|_ \/_______ /\___ >\_/ |___|\_____ /
|
||||||
|
* \__> \/ \/ \/ \/ \/
|
||||||
|
*
|
||||||
|
* www.optixx.org
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Version: 1.0
|
||||||
|
* Created: 07/21/2009 03:32:16 PM
|
||||||
|
* Author: david@optixx.org
|
||||||
|
*
|
||||||
|
* =====================================================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __TIMER_H__
|
||||||
|
#define __TIMER_H__
|
||||||
|
|
||||||
|
|
||||||
|
int16_t timer_start( void );
|
||||||
|
double timer_stop( void );
|
||||||
|
int16_t timer_stop_int( void );
|
||||||
|
|
||||||
|
#endif
|
||||||
95
avr/usbload/uart.c
Normal file
95
avr/usbload/uart.c
Normal file
@@ -0,0 +1,95 @@
|
|||||||
|
/*
|
||||||
|
* =====================================================================================
|
||||||
|
*
|
||||||
|
* ________ .__ __ ________ ____ ________
|
||||||
|
* \_____ \ __ __|__| ____ | | __\______ \ _______ _/_ |/ _____/
|
||||||
|
* / / \ \| | \ |/ ___\| |/ / | | \_/ __ \ \/ /| / __ \
|
||||||
|
* / \_/. \ | / \ \___| < | ` \ ___/\ / | \ |__\ \
|
||||||
|
* \_____\ \_/____/|__|\___ >__|_ \/_______ /\___ >\_/ |___|\_____ /
|
||||||
|
* \__> \/ \/ \/ \/ \/
|
||||||
|
*
|
||||||
|
* 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 <avr/pgmspace.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "uart.h"
|
||||||
|
#include "fifo.h"
|
||||||
|
|
||||||
|
volatile struct {
|
||||||
|
uint8_t tmr_int:1;
|
||||||
|
uint8_t adc_int:1;
|
||||||
|
uint8_t rx_int:1;
|
||||||
|
} intflags;
|
||||||
|
|
||||||
|
|
||||||
|
volatile char rxbuff;
|
||||||
|
|
||||||
|
|
||||||
|
FILE uart_stdout = FDEV_SETUP_STREAM(uart_stream, NULL, _FDEV_SETUP_WRITE);
|
||||||
|
|
||||||
|
void uart_init(void)
|
||||||
|
{
|
||||||
|
UCSR0A = _BV(U2X0); /* improves baud rate error @ F_CPU = 1 MHz */
|
||||||
|
UCSR0B = _BV(TXEN0) | _BV(RXEN0) | _BV(RXCIE0); /* tx/rx enable, rx complete
|
||||||
|
* intr */
|
||||||
|
UBRR0L = (F_CPU / (8 * 115200UL)) - 1;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ISR(USART0_RX_vect)
|
||||||
|
{
|
||||||
|
uint8_t c;
|
||||||
|
c = UDR0;
|
||||||
|
if (bit_is_clear(UCSR0A, FE0)) {
|
||||||
|
rxbuff = c;
|
||||||
|
intflags.rx_int = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void uart_putc(uint8_t c)
|
||||||
|
{
|
||||||
|
loop_until_bit_is_set(UCSR0A, UDRE0);
|
||||||
|
UDR0 = c;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void uart_puts(const char *s)
|
||||||
|
{
|
||||||
|
do {
|
||||||
|
uart_putc(*s);
|
||||||
|
}
|
||||||
|
while (*s++);
|
||||||
|
}
|
||||||
|
|
||||||
|
void uart_puts_P(PGM_P s)
|
||||||
|
{
|
||||||
|
while (1) {
|
||||||
|
unsigned char c = pgm_read_byte(s);
|
||||||
|
s++;
|
||||||
|
if ('\0' == c)
|
||||||
|
break;
|
||||||
|
uart_putc(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int uart_stream(char c, FILE * stream)
|
||||||
|
{
|
||||||
|
if (c == '\n')
|
||||||
|
uart_putc('\r');
|
||||||
|
loop_until_bit_is_set(UCSR0A, UDRE0);
|
||||||
|
UDR0 = c;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
40
avr/usbload/uart.h
Normal file
40
avr/usbload/uart.h
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
/*
|
||||||
|
* =====================================================================================
|
||||||
|
*
|
||||||
|
* ________ .__ __ ________ ____ ________
|
||||||
|
* \_____ \ __ __|__| ____ | | __\______ \ _______ _/_ |/ _____/
|
||||||
|
* / / \ \| | \ |/ ___\| |/ / | | \_/ __ \ \/ /| / __ \
|
||||||
|
* / \_/. \ | / \ \___| < | ` \ ___/\ / | \ |__\ \
|
||||||
|
* \_____\ \_/____/|__|\___ >__|_ \/_______ /\___ >\_/ |___|\_____ /
|
||||||
|
* \__> \/ \/ \/ \/ \/
|
||||||
|
*
|
||||||
|
* www.optixx.org
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Version: 1.0
|
||||||
|
* Created: 07/21/2009 03:32:16 PM
|
||||||
|
* Author: david@optixx.org
|
||||||
|
*
|
||||||
|
* =====================================================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef __UART_H__
|
||||||
|
#define __UART_H__
|
||||||
|
|
||||||
|
#define CR "\r\n"
|
||||||
|
|
||||||
|
#include <avr/io.h>
|
||||||
|
#include <avr/pgmspace.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
91
avr/usbload/usb_bulk.c
Normal file
91
avr/usbload/usb_bulk.c
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
/*
|
||||||
|
* =====================================================================================
|
||||||
|
*
|
||||||
|
* ________ .__ __ ________ ____ ________
|
||||||
|
* \_____ \ __ __|__| ____ | | __\______ \ _______ _/_ |/ _____/
|
||||||
|
* / / \ \| | \ |/ ___\| |/ / | | \_/ __ \ \/ /| / __ \
|
||||||
|
* / \_/. \ | / \ \___| < | ` \ ___/\ / | \ |__\ \
|
||||||
|
* \_____\ \_/____/|__|\___ >__|_ \/_______ /\___ >\_/ |___|\_____ /
|
||||||
|
* \__> \/ \/ \/ \/ \/
|
||||||
|
*
|
||||||
|
* www.optixx.org
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Version: 1.0
|
||||||
|
* Created: 07/21/2009 03:32:16 PM
|
||||||
|
* Author: david@optixx.org
|
||||||
|
*
|
||||||
|
* =====================================================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <avr/io.h>
|
||||||
|
#include <avr/pgmspace.h> /* required by usbdrv.h */
|
||||||
|
#include <avr/interrupt.h> /* for sei() */
|
||||||
|
#include <util/delay.h> /* for _delay_ms() */
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "usbdrv.h"
|
||||||
|
#include "oddebug.h" /* This is also an example for using debug
|
||||||
|
* macros */
|
||||||
|
#include "config.h"
|
||||||
|
#include "requests.h" /* The custom request numbers we use */
|
||||||
|
#include "uart.h"
|
||||||
|
#include "sram.h"
|
||||||
|
#include "debug.h"
|
||||||
|
#include "info.h"
|
||||||
|
|
||||||
|
#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;
|
||||||
|
|
||||||
|
uint8_t usbFunctionWrite(uint8_t * data, uint8_t len)
|
||||||
|
{
|
||||||
|
uint8_t *ptr;
|
||||||
|
uint8_t i;
|
||||||
|
|
||||||
|
if (len > rx_remaining) {
|
||||||
|
info_P(PSTR("ERROR:usbFunctionWrite more data than expected remain: %i len: %i\n"),
|
||||||
|
rx_remaining, len);
|
||||||
|
len = rx_remaining;
|
||||||
|
}
|
||||||
|
if (req_state == REQ_STATUS_BULK_UPLOAD) {
|
||||||
|
|
||||||
|
rx_remaining -= len;
|
||||||
|
debug_P(DEBUG_USB_TRANS, PSTR("usbFunctionWrite REQ_STATUS_BULK_UPLOAD addr: 0x%08lx len: %i rx_remaining=%i\n"),
|
||||||
|
req_addr, len, rx_remaining);
|
||||||
|
ptr = data;
|
||||||
|
i = len;
|
||||||
|
while(i--){
|
||||||
|
sram_bulk_write(*ptr++);
|
||||||
|
sram_bulk_write_next();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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_P(DEBUG_USB_TRANS, PSTR("usbFunctionRead len=%i tx_remaining=%i \n"), len, tx_remaining);
|
||||||
|
|
||||||
|
for (i = 0; i < len; i++) {
|
||||||
|
*data = tx_buffer[len];
|
||||||
|
data++;
|
||||||
|
}
|
||||||
|
return len;
|
||||||
|
}
|
||||||
29
avr/usbload/usb_bulk.h
Normal file
29
avr/usbload/usb_bulk.h
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
/*
|
||||||
|
* =====================================================================================
|
||||||
|
*
|
||||||
|
* ________ .__ __ ________ ____ ________
|
||||||
|
* \_____ \ __ __|__| ____ | | __\______ \ _______ _/_ |/ _____/
|
||||||
|
* / / \ \| | \ |/ ___\| |/ / | | \_/ __ \ \/ /| / __ \
|
||||||
|
* / \_/. \ | / \ \___| < | ` \ ___/\ / | \ |__\ \
|
||||||
|
* \_____\ \_/____/|__|\___ >__|_ \/_______ /\___ >\_/ |___|\_____ /
|
||||||
|
* \__> \/ \/ \/ \/ \/
|
||||||
|
*
|
||||||
|
* www.optixx.org
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Version: 1.0
|
||||||
|
* Created: 07/21/2009 03:32:16 PM
|
||||||
|
* Author: david@optixx.org
|
||||||
|
*
|
||||||
|
* =====================================================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef __USB_BULK_H__
|
||||||
|
#define __USB_BULK_H__
|
||||||
|
|
||||||
|
|
||||||
|
uint8_t usbFunctionWrite(uint8_t * data, uint8_t len);
|
||||||
|
uint8_t usbFunctionRead(uint8_t * data, uint8_t len);
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -1,11 +1,33 @@
|
|||||||
|
/*
|
||||||
|
* =====================================================================================
|
||||||
|
*
|
||||||
|
* ________ .__ __ ________ ____ ________
|
||||||
|
* \_____ \ __ __|__| ____ | | __\______ \ _______ _/_ |/ _____/
|
||||||
|
* / / \ \| | \ |/ ___\| |/ / | | \_/ __ \ \/ /| / __ \
|
||||||
|
* / \_/. \ | / \ \___| < | ` \ ___/\ / | \ |__\ \
|
||||||
|
* \_____\ \_/____/|__|\___ >__|_ \/_______ /\___ >\_/ |___|\_____ /
|
||||||
|
* \__> \/ \/ \/ \/ \/
|
||||||
|
*
|
||||||
|
* www.optixx.org
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Version: 1.0
|
||||||
|
* Created: 07/21/2009 03:32:16 PM
|
||||||
|
* Author: david@optixx.org
|
||||||
|
*
|
||||||
|
* =====================================================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Name: usbconfig.h
|
/* Name: usbconfig.h
|
||||||
* Project: AVR USB driver
|
* Project: V-USB, virtual USB port for Atmel's(r) AVR(r) microcontrollers
|
||||||
* Author: Christian Starkjohann
|
* Author: Christian Starkjohann
|
||||||
* Creation Date: 2005-04-01
|
* Creation Date: 2005-04-01
|
||||||
* Tabsize: 4
|
* Tabsize: 4
|
||||||
* Copyright: (c) 2005 by OBJECTIVE DEVELOPMENT Software GmbH
|
* Copyright: (c) 2005 by OBJECTIVE DEVELOPMENT Software GmbH
|
||||||
* License: GNU GPL v2 (see License.txt) or proprietary (CommercialLicense.txt)
|
* License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
|
||||||
* This Revision: $Id: usbconfig-prototype.h 396 2007-09-19 16:39:54Z cs $
|
* This Revision: $Id: usbconfig-prototype.h 740 2009-04-13 18:23:31Z cs $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __usbconfig_h_included__
|
#ifndef __usbconfig_h_included__
|
||||||
@@ -14,12 +36,11 @@
|
|||||||
/*
|
/*
|
||||||
General Description:
|
General Description:
|
||||||
This file is an example configuration (with inline documentation) for the USB
|
This file is an example configuration (with inline documentation) for the USB
|
||||||
driver. It configures AVR-USB for an ATMega8 with USB D+ connected to Port D
|
driver. It configures V-USB for USB D+ connected to Port D bit 2 (which is
|
||||||
bit 2 (which is also hardware interrupt 0) and USB D- to Port D bit 0. You may
|
also hardware interrupt 0 on many devices) and USB D- to Port D bit 4. You may
|
||||||
wire the lines to any other port, as long as D+ is also wired to INT0.
|
wire the lines to any other port, as long as D+ is also wired to INT0 (or any
|
||||||
To create your own usbconfig.h file, copy this file to the directory
|
other hardware interrupt, as long as it is the highest level interrupt, see
|
||||||
containing "usbdrv" (that is your project firmware source directory) and
|
section at the end of this file).
|
||||||
rename it to "usbconfig.h". Then edit it accordingly.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* ---------------------------- Hardware Config ---------------------------- */
|
/* ---------------------------- Hardware Config ---------------------------- */
|
||||||
@@ -28,32 +49,42 @@ rename it to "usbconfig.h". Then edit it accordingly.
|
|||||||
/* This is the port where the USB bus is connected. When you configure it to
|
/* This is the port where the USB bus is connected. When you configure it to
|
||||||
* "B", the registers PORTB, PINB and DDRB will be used.
|
* "B", the registers PORTB, PINB and DDRB will be used.
|
||||||
*/
|
*/
|
||||||
#define USB_CFG_DMINUS_BIT 0
|
#define USB_CFG_DMINUS_BIT 4
|
||||||
/* This is the bit number in USB_CFG_IOPORT where the USB D- line is connected.
|
/* This is the bit number in USB_CFG_IOPORT where the USB D- line is connected.
|
||||||
* This may be any bit in the port.
|
* This may be any bit in the port.
|
||||||
*/
|
*/
|
||||||
#define USB_CFG_DPLUS_BIT 2
|
#define USB_CFG_DPLUS_BIT 2
|
||||||
/* This is the bit number in USB_CFG_IOPORT where the USB D+ line is connected.
|
/* This is the bit number in USB_CFG_IOPORT where the USB D+ line is connected.
|
||||||
* This may be any bit in the port. Please note that D+ must also be connected
|
* This may be any bit in the port. Please note that D+ must also be connected
|
||||||
* to interrupt pin INT0!
|
* to interrupt pin INT0! [You can also use other interrupts, see section
|
||||||
|
* "Optional MCU Description" below, or you can connect D- to the interrupt, as
|
||||||
|
* it is required if you use the USB_COUNT_SOF feature. If you use D- for the
|
||||||
|
* interrupt, the USB interrupt will also be triggered at Start-Of-Frame
|
||||||
|
* markers every millisecond.]
|
||||||
*/
|
*/
|
||||||
/* #define USB_CFG_CLOCK_KHZ (F_CPU/1000) */
|
#define USB_CFG_CLOCK_KHZ (F_CPU/1000)
|
||||||
/* Clock rate of the AVR in MHz. Legal values are 12000, 15000, 16000 or 16500.
|
/* Clock rate of the AVR in kHz. Legal values are 12000, 12800, 15000, 16000,
|
||||||
* The 16.5 MHz version of the code requires no crystal, it tolerates +/- 1%
|
* 16500 and 20000. The 12.8 MHz and 16.5 MHz versions of the code require no
|
||||||
* deviation from the nominal frequency. All other rates require a precision
|
* crystal, they tolerate +/- 1% deviation from the nominal frequency. All
|
||||||
* of 2000 ppm and thus a crystal!
|
* other rates require a precision of 2000 ppm and thus a crystal!
|
||||||
* Default if not specified: 12 MHz
|
* Default if not specified: 12 MHz
|
||||||
*/
|
*/
|
||||||
|
#define USB_CFG_CHECK_CRC 0
|
||||||
|
/* Define this to 1 if you want that the driver checks integrity of incoming
|
||||||
|
* data packets (CRC checks). CRC checks cost quite a bit of code size and are
|
||||||
|
* currently only available for 18 MHz crystal clock. You must choose
|
||||||
|
* USB_CFG_CLOCK_KHZ = 18000 if you enable this option.
|
||||||
|
*/
|
||||||
|
|
||||||
/* ----------------------- Optional Hardware Config ------------------------ */
|
/* ----------------------- Optional Hardware Config ------------------------ */
|
||||||
|
|
||||||
/* #define USB_CFG_PULLUP_IOPORTNAME D */
|
//#define USB_CFG_PULLUP_IOPORTNAME D
|
||||||
/* If you connect the 1.5k pullup resistor from D- to a port pin instead of
|
/* If you connect the 1.5k pullup resistor from D- to a port pin instead of
|
||||||
* V+, you can connect and disconnect the device from firmware by calling
|
* V+, you can connect and disconnect the device from firmware by calling
|
||||||
* the macros usbDeviceConnect() and usbDeviceDisconnect() (see usbdrv.h).
|
* the macros usbDeviceConnect() and usbDeviceDisconnect() (see usbdrv.h).
|
||||||
* This constant defines the port on which the pullup resistor is connected.
|
* This constant defines the port on which the pullup resistor is connected.
|
||||||
*/
|
*/
|
||||||
/* #define USB_CFG_PULLUP_BIT 4 */
|
//#define USB_CFG_PULLUP_BIT 6
|
||||||
/* This constant defines the bit number in USB_CFG_PULLUP_IOPORT (defined
|
/* This constant defines the bit number in USB_CFG_PULLUP_IOPORT (defined
|
||||||
* above) where the 1.5k pullup resistor is connected. See description
|
* above) where the 1.5k pullup resistor is connected. See description
|
||||||
* above for details.
|
* above for details.
|
||||||
@@ -61,18 +92,26 @@ rename it to "usbconfig.h". Then edit it accordingly.
|
|||||||
|
|
||||||
/* --------------------------- Functional Range ---------------------------- */
|
/* --------------------------- Functional Range ---------------------------- */
|
||||||
|
|
||||||
#define USB_CFG_HAVE_INTRIN_ENDPOINT 1
|
#define USB_CFG_HAVE_INTRIN_ENDPOINT 0
|
||||||
/* Define this to 1 if you want to compile a version with two endpoints: The
|
/* Define this to 1 if you want to compile a version with two endpoints: The
|
||||||
* default control endpoint 0 and an interrupt-in endpoint 1.
|
* default control endpoint 0 and an interrupt-in endpoint (any other endpoint
|
||||||
|
* number).
|
||||||
*/
|
*/
|
||||||
#define USB_CFG_HAVE_INTRIN_ENDPOINT3 0
|
#define USB_CFG_HAVE_INTRIN_ENDPOINT3 0
|
||||||
/* Define this to 1 if you want to compile a version with three endpoints: The
|
/* Define this to 1 if you want to compile a version with three endpoints: The
|
||||||
* default control endpoint 0, an interrupt-in endpoint 1 and an interrupt-in
|
* default control endpoint 0, an interrupt-in endpoint 3 (or the number
|
||||||
* endpoint 3. You must also enable endpoint 1 above.
|
* configured below) and a catch-all default interrupt-in endpoint as above.
|
||||||
|
* You must also define USB_CFG_HAVE_INTRIN_ENDPOINT to 1 for this feature.
|
||||||
*/
|
*/
|
||||||
/* #define USB_INITIAL_DATATOKEN USBPID_DATA0 */
|
#define USB_CFG_EP3_NUMBER 3
|
||||||
|
/* If the so-called endpoint 3 is used, it can now be configured to any other
|
||||||
|
* endpoint number (except 0) with this macro. Default if undefined is 3.
|
||||||
|
*/
|
||||||
|
/* #define USB_INITIAL_DATATOKEN USBPID_DATA1 */
|
||||||
/* The above macro defines the startup condition for data toggling on the
|
/* The above macro defines the startup condition for data toggling on the
|
||||||
* interrupt/bulk endpoints 1 and 3. Defaults to USBPID_DATA0.
|
* interrupt/bulk endpoints 1 and 3. Defaults to USBPID_DATA1.
|
||||||
|
* Since the token is toggled BEFORE sending any data, the first packet is
|
||||||
|
* sent with the oposite value of this configuration!
|
||||||
*/
|
*/
|
||||||
#define USB_CFG_IMPLEMENT_HALT 0
|
#define USB_CFG_IMPLEMENT_HALT 0
|
||||||
/* Define this to 1 if you also want to implement the ENDPOINT_HALT feature
|
/* Define this to 1 if you also want to implement the ENDPOINT_HALT feature
|
||||||
@@ -80,7 +119,15 @@ rename it to "usbconfig.h". Then edit it accordingly.
|
|||||||
* it is required by the standard. We have made it a config option because it
|
* it is required by the standard. We have made it a config option because it
|
||||||
* bloats the code considerably.
|
* bloats the code considerably.
|
||||||
*/
|
*/
|
||||||
#define USB_CFG_INTR_POLL_INTERVAL 20
|
#define USB_CFG_SUPPRESS_INTR_CODE 1
|
||||||
|
/* Define this to 1 if you want to declare interrupt-in endpoints, but don't
|
||||||
|
* want to send any data over them. If this macro is defined to 1, functions
|
||||||
|
* usbSetInterrupt() and usbSetInterrupt3() are omitted. This is useful if
|
||||||
|
* you need the interrupt-in endpoints in order to comply to an interface
|
||||||
|
* (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
|
||||||
/* If you compile a version with endpoint 1 (interrupt-in), this is the poll
|
/* 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
|
* interval. The value is in milliseconds and must not be less than 10 ms for
|
||||||
* low speed devices.
|
* low speed devices.
|
||||||
@@ -89,12 +136,12 @@ rename it to "usbconfig.h". Then edit it accordingly.
|
|||||||
/* Define this to 1 if the device has its own power supply. Set it to 0 if the
|
/* Define this to 1 if the device has its own power supply. Set it to 0 if the
|
||||||
* device is powered from the USB bus.
|
* device is powered from the USB bus.
|
||||||
*/
|
*/
|
||||||
#define USB_CFG_MAX_BUS_POWER 100
|
#define USB_CFG_MAX_BUS_POWER 300
|
||||||
/* Set this variable to the maximum USB bus power consumption of your device.
|
/* Set this variable to the maximum USB bus power consumption of your device.
|
||||||
* The value is in milliamperes. [It will be divided by two since USB
|
* The value is in milliamperes. [It will be divided by two since USB
|
||||||
* communicates power requirements in units of 2 mA.]
|
* communicates power requirements in units of 2 mA.]
|
||||||
*/
|
*/
|
||||||
#define USB_CFG_IMPLEMENT_FN_WRITE 0
|
#define USB_CFG_IMPLEMENT_FN_WRITE 1
|
||||||
/* Set this to 1 if you want usbFunctionWrite() to be called for control-out
|
/* Set this to 1 if you want usbFunctionWrite() to be called for control-out
|
||||||
* transfers. Set it to 0 if you don't need it and want to save a couple of
|
* transfers. Set it to 0 if you don't need it and want to save a couple of
|
||||||
* bytes.
|
* bytes.
|
||||||
@@ -106,15 +153,21 @@ rename it to "usbconfig.h". Then edit it accordingly.
|
|||||||
* usbFunctionSetup(). This saves a couple of bytes.
|
* usbFunctionSetup(). This saves a couple of bytes.
|
||||||
*/
|
*/
|
||||||
#define USB_CFG_IMPLEMENT_FN_WRITEOUT 0
|
#define USB_CFG_IMPLEMENT_FN_WRITEOUT 0
|
||||||
/* Define this to 1 if you want to use interrupt-out (or bulk out) endpoint 1.
|
/* Define this to 1 if you want to use interrupt-out (or bulk out) endpoints.
|
||||||
* You must implement the function usbFunctionWriteOut() which receives all
|
* You must implement the function usbFunctionWriteOut() which receives all
|
||||||
* interrupt/bulk data sent to endpoint 1.
|
* interrupt/bulk data sent to any endpoint other than 0. The endpoint number
|
||||||
|
* can be found in 'usbRxToken'.
|
||||||
*/
|
*/
|
||||||
#define USB_CFG_HAVE_FLOWCONTROL 0
|
#define USB_CFG_HAVE_FLOWCONTROL 0
|
||||||
/* Define this to 1 if you want flowcontrol over USB data. See the definition
|
/* Define this to 1 if you want flowcontrol over USB data. See the definition
|
||||||
* of the macros usbDisableAllRequests() and usbEnableAllRequests() in
|
* of the macros usbDisableAllRequests() and usbEnableAllRequests() in
|
||||||
* usbdrv.h.
|
* usbdrv.h.
|
||||||
*/
|
*/
|
||||||
|
#define USB_CFG_LONG_TRANSFERS 0
|
||||||
|
/* Define this to 1 if you want to send/receive blocks of more than 254 bytes
|
||||||
|
* in a single control-in or control-out transfer. Note that the capability
|
||||||
|
* for long transfers increases the driver size.
|
||||||
|
*/
|
||||||
/* #define USB_RX_USER_HOOK(data, len) if(usbRxToken == (uchar)USBPID_SETUP) blinkLED(); */
|
/* #define USB_RX_USER_HOOK(data, len) if(usbRxToken == (uchar)USBPID_SETUP) blinkLED(); */
|
||||||
/* This macro is a hook if you want to do unconventional things. If it is
|
/* This macro is a hook if you want to do unconventional things. If it is
|
||||||
* defined, it's inserted at the beginning of received message processing.
|
* defined, it's inserted at the beginning of received message processing.
|
||||||
@@ -122,34 +175,71 @@ rename it to "usbconfig.h". Then edit it accordingly.
|
|||||||
* proceed, do a return after doing your things. One possible application
|
* proceed, do a return after doing your things. One possible application
|
||||||
* (besides debugging) is to flash a status LED on each packet.
|
* (besides debugging) is to flash a status LED on each packet.
|
||||||
*/
|
*/
|
||||||
|
/* #define USB_RESET_HOOK(resetStarts) if(!resetStarts){hadUsbReset();} */
|
||||||
|
/* This macro is a hook if you need to know when an USB RESET occurs. It has
|
||||||
|
* one parameter which distinguishes between the start of RESET state and its
|
||||||
|
* end.
|
||||||
|
*/
|
||||||
|
/* #define USB_SET_ADDRESS_HOOK() hadAddressAssigned(); */
|
||||||
|
/* This macro (if defined) is executed when a USB SET_ADDRESS request was
|
||||||
|
* received.
|
||||||
|
*/
|
||||||
#define USB_COUNT_SOF 0
|
#define USB_COUNT_SOF 0
|
||||||
/* define this macro to 1 if you need the global variable "usbSofCount" which
|
/* define this macro to 1 if you need the global variable "usbSofCount" which
|
||||||
* counts SOF packets.
|
* counts SOF packets. This feature requires that the hardware interrupt is
|
||||||
|
* connected to D- instead of D+.
|
||||||
|
*/
|
||||||
|
/* #ifdef __ASSEMBLER__
|
||||||
|
* macro myAssemblerMacro
|
||||||
|
* in YL, TCNT0
|
||||||
|
* sts timer0Snapshot, YL
|
||||||
|
* endm
|
||||||
|
* #endif
|
||||||
|
* #define USB_SOF_HOOK myAssemblerMacro
|
||||||
|
* This macro (if defined) is executed in the assembler module when a
|
||||||
|
* Start Of Frame condition is detected. It is recommended to define it to
|
||||||
|
* the name of an assembler macro which is defined here as well so that more
|
||||||
|
* than one assembler instruction can be used. The macro may use the register
|
||||||
|
* YL and modify SREG. If it lasts longer than a couple of cycles, USB messages
|
||||||
|
* immediately after an SOF pulse may be lost and must be retried by the host.
|
||||||
|
* What can you do with this hook? Since the SOF signal occurs exactly every
|
||||||
|
* 1 ms (unless the host is in sleep mode), you can use it to tune OSCCAL in
|
||||||
|
* designs running on the internal RC oscillator.
|
||||||
|
* Please note that Start Of Frame detection works only if D- is wired to the
|
||||||
|
* interrupt, not D+. THIS IS DIFFERENT THAN MOST EXAMPLES!
|
||||||
|
*/
|
||||||
|
#define USB_CFG_CHECK_DATA_TOGGLING 0
|
||||||
|
/* define this macro to 1 if you want to filter out duplicate data packets
|
||||||
|
* sent by the host. Duplicates occur only as a consequence of communication
|
||||||
|
* errors, when the host does not receive an ACK. Please note that you need to
|
||||||
|
* implement the filtering yourself in usbFunctionWriteOut() and
|
||||||
|
* usbFunctionWrite(). Use the global usbCurrentDataToken and a static variable
|
||||||
|
* for each control- and out-endpoint to check for duplicate packets.
|
||||||
|
*/
|
||||||
|
#define USB_CFG_HAVE_MEASURE_FRAME_LENGTH 0
|
||||||
|
/* define this macro to 1 if you want the function usbMeasureFrameLength()
|
||||||
|
* compiled in. This function can be used to calibrate the AVR's RC oscillator.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* -------------------------- Device Description --------------------------- */
|
/* -------------------------- Device Description --------------------------- */
|
||||||
|
|
||||||
#define USB_CFG_VENDOR_ID 0xc0, 0x16
|
#define USB_CFG_VENDOR_ID 0xc0, 0x16
|
||||||
/* USB vendor ID for the device, low byte first. If you have registered your
|
/* USB vendor ID for the device, low byte first. If you have registered your
|
||||||
* own Vendor ID, define it here. Otherwise you use obdev's free shared
|
* own Vendor ID, define it here. Otherwise you use one of obdev's free shared
|
||||||
* VID/PID pair. Be sure to read USBID-License.txt for rules!
|
* VID/PID pairs. Be sure to read USBID-License.txt for rules!
|
||||||
* This template uses obdev's shared VID/PID pair for HIDs: 0x16c0/0x5df.
|
|
||||||
* Use this VID/PID pair ONLY if you understand the implications!
|
|
||||||
*/
|
*/
|
||||||
#define USB_CFG_DEVICE_ID 0xdf, 0x05
|
#define USB_CFG_DEVICE_ID 0xdd, 0x05
|
||||||
/* This is the ID of the product, low byte first. It is interpreted in the
|
/* This is the ID of the product, low byte first. It is interpreted in the
|
||||||
* scope of the vendor ID. If you have registered your own VID with usb.org
|
* scope of the vendor ID. If you have registered your own VID with usb.org
|
||||||
* or if you have licensed a PID from somebody else, define it here. Otherwise
|
* or if you have licensed a PID from somebody else, define it here. Otherwise
|
||||||
* you use obdev's free shared VID/PID pair. Be sure to read the rules in
|
* you use obdev's free shared VID/PID pair. Be sure to read the rules in
|
||||||
* USBID-License.txt!
|
* USBID-License.txt!
|
||||||
* This template uses obdev's shared VID/PID pair for HIDs: 0x16c0/0x5df.
|
|
||||||
* Use this VID/PID pair ONLY if you understand the implications!
|
|
||||||
*/
|
*/
|
||||||
#define USB_CFG_DEVICE_VERSION 0x00, 0x01
|
#define USB_CFG_DEVICE_VERSION 0x00, 0x01
|
||||||
/* Version number of the device: Minor number first, then major number.
|
/* Version number of the device: Minor number first, then major number.
|
||||||
*/
|
*/
|
||||||
#define USB_CFG_VENDOR_NAME 'w', 'w', 'w', '.', 'o', 'b', 'd', 'e', 'v', '.', 'a', 't'
|
#define USB_CFG_VENDOR_NAME 'o', 'p', 't', 'i', 'x', 'x', '.', 'o', 'r', 'g'
|
||||||
#define USB_CFG_VENDOR_NAME_LEN 12
|
#define USB_CFG_VENDOR_NAME_LEN 10
|
||||||
/* These two values define the vendor name returned by the USB device. The name
|
/* These two values define the vendor name returned by the USB device. The name
|
||||||
* must be given as a list of characters under single quotes. The characters
|
* must be given as a list of characters under single quotes. The characters
|
||||||
* are interpreted as Unicode (UTF-16) entities.
|
* are interpreted as Unicode (UTF-16) entities.
|
||||||
@@ -158,8 +248,8 @@ rename it to "usbconfig.h". Then edit it accordingly.
|
|||||||
* obdev's free shared VID/PID pair. See the file USBID-License.txt for
|
* obdev's free shared VID/PID pair. See the file USBID-License.txt for
|
||||||
* details.
|
* details.
|
||||||
*/
|
*/
|
||||||
#define USB_CFG_DEVICE_NAME 'T', 'e', 'm', 'p', 'l', 'a', 't', 'e'
|
#define USB_CFG_DEVICE_NAME 'Q', 'U', 'I', 'C', 'K', 'D', 'E', 'V', '1', '6'
|
||||||
#define USB_CFG_DEVICE_NAME_LEN 8
|
#define USB_CFG_DEVICE_NAME_LEN 10
|
||||||
/* Same as above for the device name. If you don't want a device name, undefine
|
/* Same as above for the device name. If you don't want a device name, undefine
|
||||||
* the macros. See the file USBID-License.txt before you assign a name if you
|
* the macros. See the file USBID-License.txt before you assign a name if you
|
||||||
* use a shared VID/PID.
|
* use a shared VID/PID.
|
||||||
@@ -173,23 +263,24 @@ rename it to "usbconfig.h". Then edit it accordingly.
|
|||||||
* to fine tune control over USB descriptors such as the string descriptor
|
* to fine tune control over USB descriptors such as the string descriptor
|
||||||
* for the serial number.
|
* for the serial number.
|
||||||
*/
|
*/
|
||||||
#define USB_CFG_DEVICE_CLASS 0
|
#define USB_CFG_DEVICE_CLASS 0xff /* set to 0 if deferred to interface */
|
||||||
#define USB_CFG_DEVICE_SUBCLASS 0
|
#define USB_CFG_DEVICE_SUBCLASS 0
|
||||||
/* See USB specification if you want to conform to an existing device class.
|
/* See USB specification if you want to conform to an existing device class.
|
||||||
|
* Class 0xff is "vendor specific".
|
||||||
*/
|
*/
|
||||||
#define USB_CFG_INTERFACE_CLASS 3 /* HID */
|
#define USB_CFG_INTERFACE_CLASS 0 /* define class here if not at device level */
|
||||||
#define USB_CFG_INTERFACE_SUBCLASS 0
|
#define USB_CFG_INTERFACE_SUBCLASS 0
|
||||||
#define USB_CFG_INTERFACE_PROTOCOL 0
|
#define USB_CFG_INTERFACE_PROTOCOL 0
|
||||||
/* See USB specification if you want to conform to an existing device class or
|
/* See USB specification if you want to conform to an existing device class or
|
||||||
* protocol.
|
* protocol. The following classes must be set at interface level:
|
||||||
* This template defines a HID class device. If you implement a vendor class
|
* HID class is 3, no subclass and protocol required (but may be useful!)
|
||||||
* device, set USB_CFG_INTERFACE_CLASS to 0 and USB_CFG_DEVICE_CLASS to 0xff.
|
* CDC class is 2, use subclass 2 and protocol 1 for ACM
|
||||||
*/
|
*/
|
||||||
#define USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH 42 /* total length of report descriptor */
|
#define USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH 0
|
||||||
|
|
||||||
/* Define this to the length of the HID report descriptor, if you implement
|
/* Define this to the length of the HID report descriptor, if you implement
|
||||||
* an HID device. Otherwise don't define it or define it to 0.
|
* an HID device. Otherwise don't define it or define it to 0.
|
||||||
* Since this template defines a HID device, it must also specify a HID
|
* If you use this define, you must add a PROGMEM character array named
|
||||||
* report descriptor length. You must add a PROGMEM character array named
|
|
||||||
* "usbHidReportDescriptor" to your code which contains the report descriptor.
|
* "usbHidReportDescriptor" to your code which contains the report descriptor.
|
||||||
* Don't forget to keep the array and this define in sync!
|
* Don't forget to keep the array and this define in sync!
|
||||||
*/
|
*/
|
||||||
@@ -209,7 +300,9 @@ rename it to "usbconfig.h". Then edit it accordingly.
|
|||||||
* no properties are defined or if they are 0, the default descriptor is used.
|
* no properties are defined or if they are 0, the default descriptor is used.
|
||||||
* Possible properties are:
|
* Possible properties are:
|
||||||
* + USB_PROP_IS_DYNAMIC: The data for the descriptor should be fetched
|
* + USB_PROP_IS_DYNAMIC: The data for the descriptor should be fetched
|
||||||
* at runtime via usbFunctionDescriptor().
|
* at runtime via usbFunctionDescriptor(). If the usbMsgPtr mechanism is
|
||||||
|
* used, the data is in FLASH by default. Add property USB_PROP_IS_RAM if
|
||||||
|
* you want RAM pointers.
|
||||||
* + USB_PROP_IS_RAM: The data returned by usbFunctionDescriptor() or found
|
* + USB_PROP_IS_RAM: The data returned by usbFunctionDescriptor() or found
|
||||||
* in static memory is in RAM, not in flash memory.
|
* in static memory is in RAM, not in flash memory.
|
||||||
* + USB_PROP_LENGTH(len): If the data is in static memory (RAM or flash),
|
* + USB_PROP_LENGTH(len): If the data is in static memory (RAM or flash),
|
||||||
@@ -241,6 +334,12 @@ rename it to "usbconfig.h". Then edit it accordingly.
|
|||||||
* USB_CFG_DESCR_PROPS_HID_REPORT
|
* USB_CFG_DESCR_PROPS_HID_REPORT
|
||||||
* USB_CFG_DESCR_PROPS_UNKNOWN (for all descriptors not handled by the driver)
|
* USB_CFG_DESCR_PROPS_UNKNOWN (for all descriptors not handled by the driver)
|
||||||
*
|
*
|
||||||
|
* Note about string descriptors: String descriptors are not just strings, they
|
||||||
|
* are Unicode strings prefixed with a 2 byte header. Example:
|
||||||
|
* int serialNumberDescriptor[] = {
|
||||||
|
* USB_STRING_DESCRIPTOR_HEADER(6),
|
||||||
|
* 'S', 'e', 'r', 'i', 'a', 'l'
|
||||||
|
* };
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define USB_CFG_DESCR_PROPS_DEVICE 0
|
#define USB_CFG_DESCR_PROPS_DEVICE 0
|
||||||
752
avr/usbload/usbdrv/usbdrvasm128.inc
Normal file
752
avr/usbload/usbdrv/usbdrvasm128.inc
Normal file
@@ -0,0 +1,752 @@
|
|||||||
|
/* Name: usbdrvasm128.inc
|
||||||
|
* Project: V-USB, virtual USB port for Atmel's(r) AVR(r) microcontrollers
|
||||||
|
* Author: Christian Starkjohann
|
||||||
|
* Creation Date: 2008-10-11
|
||||||
|
* Tabsize: 4
|
||||||
|
* Copyright: (c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH
|
||||||
|
* License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
|
||||||
|
* This Revision: $Id: usbdrvasm128.inc 740 2009-04-13 18:23:31Z cs $
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Do not link this file! Link usbdrvasm.S instead, which includes the
|
||||||
|
* appropriate implementation!
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
General Description:
|
||||||
|
This file is the 12.8 MHz version of the USB driver. It is intended for use
|
||||||
|
with the internal RC oscillator. Although 12.8 MHz is outside the guaranteed
|
||||||
|
calibration range of the oscillator, almost all AVRs can reach this frequency.
|
||||||
|
This version contains a phase locked loop in the receiver routine to cope with
|
||||||
|
slight clock rate deviations of up to +/- 1%.
|
||||||
|
|
||||||
|
See usbdrv.h for a description of the entire driver.
|
||||||
|
|
||||||
|
LIMITATIONS
|
||||||
|
===========
|
||||||
|
Although it may seem very handy to save the crystal and use the internal
|
||||||
|
RC oscillator of the CPU, this method (and this module) has some serious
|
||||||
|
limitations:
|
||||||
|
(1) The guaranteed calibration range of the oscillator is only 8.1 MHz.
|
||||||
|
They typical range is 14.5 MHz and most AVRs can actually reach this rate.
|
||||||
|
(2) Writing EEPROM and Flash may be unreliable (short data lifetime) since
|
||||||
|
the write procedure is timed from the RC oscillator.
|
||||||
|
(3) End Of Packet detection is between bit 0 and bit 1 where the EOP condition
|
||||||
|
may not be reliable when a hub is used. It should be in bit 1.
|
||||||
|
(4) Code size is much larger than that of the other modules.
|
||||||
|
|
||||||
|
Since almost all of this code is timing critical, don't change unless you
|
||||||
|
really know what you are doing! Many parts require not only a maximum number
|
||||||
|
of CPU cycles, but even an exact number of cycles!
|
||||||
|
|
||||||
|
Implementation notes:
|
||||||
|
======================
|
||||||
|
min frequency: 67 cycles for 8 bit -> 12.5625 MHz
|
||||||
|
max frequency: 69.286 cycles for 8 bit -> 12.99 MHz
|
||||||
|
nominal frequency: 12.77 MHz ( = sqrt(min * max))
|
||||||
|
|
||||||
|
sampling positions: (next even number in range [+/- 0.5])
|
||||||
|
cycle index range: 0 ... 66
|
||||||
|
bits:
|
||||||
|
.5, 8.875, 17.25, 25.625, 34, 42.375, 50.75, 59.125
|
||||||
|
[0/1], [9], [17], [25/+26], [34], [+42/43], [51], [59]
|
||||||
|
|
||||||
|
bit number: 0 1 2 3 4 5 6 7
|
||||||
|
spare cycles 1 2 1 2 1 1 1 0
|
||||||
|
|
||||||
|
operations to perform: duration cycle
|
||||||
|
----------------
|
||||||
|
eor fix, shift 1 -> 00
|
||||||
|
andi phase, USBMASK 1 -> 08
|
||||||
|
breq se0 1 -> 16 (moved to 11)
|
||||||
|
st y+, data 2 -> 24, 25
|
||||||
|
mov data, fix 1 -> 33
|
||||||
|
ser data 1 -> 41
|
||||||
|
subi cnt, 1 1 -> 49
|
||||||
|
brcs overflow 1 -> 50
|
||||||
|
|
||||||
|
layout of samples and operations:
|
||||||
|
[##] = sample bit
|
||||||
|
<##> = sample phase
|
||||||
|
*##* = operation
|
||||||
|
|
||||||
|
0: *00* [01] 02 03 04 <05> 06 07
|
||||||
|
1: *08* [09] 10 11 12 <13> 14 15 *16*
|
||||||
|
2: [17] 18 19 20 <21> 22 23
|
||||||
|
3: *24* *25* [26] 27 28 29 <30> 31 32
|
||||||
|
4: *33* [34] 35 36 37 <38> 39 40
|
||||||
|
5: *41* [42] 43 44 45 <46> 47 48
|
||||||
|
6: *49* *50* [51] 52 53 54 <55> 56 57 58
|
||||||
|
7: [59] 60 61 62 <63> 64 65 66
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/* we prefer positive expressions (do if condition) instead of negative
|
||||||
|
* (skip if condition), therefore use defines for skip instructions:
|
||||||
|
*/
|
||||||
|
#define ifioclr sbis
|
||||||
|
#define ifioset sbic
|
||||||
|
#define ifrclr sbrs
|
||||||
|
#define ifrset sbrc
|
||||||
|
|
||||||
|
/* The registers "fix" and "data" swap their meaning during the loop. Use
|
||||||
|
* defines to keep their name constant.
|
||||||
|
*/
|
||||||
|
#define fix x2
|
||||||
|
#define data x1
|
||||||
|
#undef phase /* phase has a default definition to x4 */
|
||||||
|
#define phase x3
|
||||||
|
|
||||||
|
|
||||||
|
USB_INTR_VECTOR:
|
||||||
|
;order of registers pushed: YL, SREG [sofError], YH, shift, x1, x2, x3, cnt, r0
|
||||||
|
push YL ;2 push only what is necessary to sync with edge ASAP
|
||||||
|
in YL, SREG ;1
|
||||||
|
push YL ;2
|
||||||
|
;----------------------------------------------------------------------------
|
||||||
|
; Synchronize with sync pattern:
|
||||||
|
;----------------------------------------------------------------------------
|
||||||
|
;sync byte (D-) pattern LSb to MSb: 01010100 [1 = idle = J, 0 = K]
|
||||||
|
;sync up with J to K edge during sync pattern -- use fastest possible loops
|
||||||
|
;The first part waits at most 1 bit long since we must be in sync pattern.
|
||||||
|
;YL is guarenteed to be < 0x80 because I flag is clear. When we jump to
|
||||||
|
;waitForJ, ensure that this prerequisite is met.
|
||||||
|
waitForJ:
|
||||||
|
inc YL
|
||||||
|
sbis USBIN, USBMINUS
|
||||||
|
brne waitForJ ; just make sure we have ANY timeout
|
||||||
|
waitForK:
|
||||||
|
;The following code results in a sampling window of 1/4 bit which meets the spec.
|
||||||
|
sbis USBIN, USBMINUS
|
||||||
|
rjmp foundK
|
||||||
|
sbis USBIN, USBMINUS
|
||||||
|
rjmp foundK
|
||||||
|
sbis USBIN, USBMINUS
|
||||||
|
rjmp foundK
|
||||||
|
sbis USBIN, USBMINUS
|
||||||
|
rjmp foundK
|
||||||
|
sbis USBIN, USBMINUS ;[0]
|
||||||
|
rjmp foundK ;[1]
|
||||||
|
#if USB_COUNT_SOF
|
||||||
|
lds YL, usbSofCount
|
||||||
|
inc YL
|
||||||
|
sts usbSofCount, YL
|
||||||
|
#endif /* USB_COUNT_SOF */
|
||||||
|
#ifdef USB_SOF_HOOK
|
||||||
|
USB_SOF_HOOK
|
||||||
|
#endif
|
||||||
|
rjmp sofError
|
||||||
|
|
||||||
|
foundK:
|
||||||
|
;{3, 5} after falling D- edge, average delay: 4 cycles [we want 4 for center sampling]
|
||||||
|
;we have 1 bit time for setup purposes, then sample again. Numbers in brackets
|
||||||
|
;are cycles from center of first sync (double K) bit after the instruction
|
||||||
|
push YH ;[2]
|
||||||
|
lds YL, usbInputBufOffset;[4]
|
||||||
|
clr YH ;[6]
|
||||||
|
subi YL, lo8(-(usbRxBuf));[7]
|
||||||
|
sbci YH, hi8(-(usbRxBuf));[8]
|
||||||
|
|
||||||
|
sbis USBIN, USBMINUS ;[9] we want two bits K [we want to sample at 8 + 4 - 1.5 = 10.5]
|
||||||
|
rjmp haveTwoBitsK ;[10]
|
||||||
|
pop YH ;[11] undo the push from before
|
||||||
|
rjmp waitForK ;[13] this was not the end of sync, retry
|
||||||
|
haveTwoBitsK:
|
||||||
|
;----------------------------------------------------------------------------
|
||||||
|
; push more registers and initialize values while we sample the first bits:
|
||||||
|
;----------------------------------------------------------------------------
|
||||||
|
#define fix x2
|
||||||
|
#define data x1
|
||||||
|
|
||||||
|
push shift ;[12]
|
||||||
|
push x1 ;[14]
|
||||||
|
push x2 ;[16]
|
||||||
|
ldi shift, 0x80 ;[18] prevent bit-unstuffing but init low bits to 0
|
||||||
|
ifioset USBIN, USBMINUS ;[19] [01] <--- bit 0 [10.5 + 8 = 18.5]
|
||||||
|
ori shift, 1<<0 ;[02]
|
||||||
|
push x3 ;[03]
|
||||||
|
push cnt ;[05]
|
||||||
|
push r0 ;[07]
|
||||||
|
ifioset USBIN, USBMINUS ;[09] <--- bit 1
|
||||||
|
ori shift, 1<<1 ;[10]
|
||||||
|
ser fix ;[11]
|
||||||
|
ldi cnt, USB_BUFSIZE ;[12]
|
||||||
|
mov data, shift ;[13]
|
||||||
|
lsl shift ;[14]
|
||||||
|
nop2 ;[15]
|
||||||
|
ifioset USBIN, USBMINUS ;[17] <--- bit 2
|
||||||
|
ori data, 3<<2 ;[18] store in bit 2 AND bit 3
|
||||||
|
eor shift, data ;[19] do nrzi decoding
|
||||||
|
andi data, 1<<3 ;[20]
|
||||||
|
in phase, USBIN ;[21] <- phase
|
||||||
|
brne jumpToEntryAfterSet ;[22] if USBMINS at bit 3 was 1
|
||||||
|
nop ;[23]
|
||||||
|
rjmp entryAfterClr ;[24]
|
||||||
|
jumpToEntryAfterSet:
|
||||||
|
rjmp entryAfterSet ;[24]
|
||||||
|
|
||||||
|
;----------------------------------------------------------------------------
|
||||||
|
; Receiver loop (numbers in brackets are cycles within byte after instr)
|
||||||
|
;----------------------------------------------------------------------------
|
||||||
|
#undef fix
|
||||||
|
#define fix x1
|
||||||
|
#undef data
|
||||||
|
#define data x2
|
||||||
|
|
||||||
|
bit7IsSet:
|
||||||
|
ifrclr phase, USBMINUS ;[62] check phase only if D- changed
|
||||||
|
lpm ;[63]
|
||||||
|
in phase, USBIN ;[64] <- phase (one cycle too late)
|
||||||
|
ori shift, 1 << 7 ;[65]
|
||||||
|
nop ;[66]
|
||||||
|
;;;;rjmp bit0AfterSet ; -> [00] == [67] moved block up to save jump
|
||||||
|
bit0AfterSet:
|
||||||
|
eor fix, shift ;[00]
|
||||||
|
#undef fix
|
||||||
|
#define fix x2
|
||||||
|
#undef data
|
||||||
|
#define data x1 /* we now have result in data, fix is reset to 0xff */
|
||||||
|
ifioclr USBIN, USBMINUS ;[01] <--- sample 0
|
||||||
|
rjmp bit0IsClr ;[02]
|
||||||
|
andi shift, ~(7 << 0) ;[03]
|
||||||
|
breq unstuff0s ;[04]
|
||||||
|
in phase, USBIN ;[05] <- phase
|
||||||
|
rjmp bit1AfterSet ;[06]
|
||||||
|
unstuff0s:
|
||||||
|
in phase, USBIN ;[06] <- phase (one cycle too late)
|
||||||
|
andi fix, ~(1 << 0) ;[07]
|
||||||
|
ifioclr USBIN, USBMINUS ;[00]
|
||||||
|
ifioset USBIN, USBPLUS ;[01]
|
||||||
|
rjmp bit0IsClr ;[02] executed if first expr false or second true
|
||||||
|
jumpToSe0AndStore:
|
||||||
|
rjmp se0AndStore ;[03] executed only if both bits 0
|
||||||
|
bit0IsClr:
|
||||||
|
ifrset phase, USBMINUS ;[04] check phase only if D- changed
|
||||||
|
lpm ;[05]
|
||||||
|
in phase, USBIN ;[06] <- phase (one cycle too late)
|
||||||
|
ori shift, 1 << 0 ;[07]
|
||||||
|
bit1AfterClr:
|
||||||
|
andi phase, USBMASK ;[08]
|
||||||
|
ifioset USBIN, USBMINUS ;[09] <--- sample 1
|
||||||
|
rjmp bit1IsSet ;[10]
|
||||||
|
breq jumpToSe0AndStore ;[11]
|
||||||
|
andi shift, ~(7 << 1) ;[12]
|
||||||
|
in phase, USBIN ;[13] <- phase
|
||||||
|
breq unstuff1c ;[14]
|
||||||
|
rjmp bit2AfterClr ;[15]
|
||||||
|
unstuff1c:
|
||||||
|
andi fix, ~(1 << 1) ;[16]
|
||||||
|
nop2 ;[08]
|
||||||
|
nop2 ;[10]
|
||||||
|
bit1IsSet:
|
||||||
|
ifrclr phase, USBMINUS ;[12] check phase only if D- changed
|
||||||
|
lpm ;[13]
|
||||||
|
in phase, USBIN ;[14] <- phase (one cycle too late)
|
||||||
|
ori shift, 1 << 1 ;[15]
|
||||||
|
nop ;[16]
|
||||||
|
bit2AfterSet:
|
||||||
|
ifioclr USBIN, USBMINUS ;[17] <--- sample 2
|
||||||
|
rjmp bit2IsClr ;[18]
|
||||||
|
andi shift, ~(7 << 2) ;[19]
|
||||||
|
breq unstuff2s ;[20]
|
||||||
|
in phase, USBIN ;[21] <- phase
|
||||||
|
rjmp bit3AfterSet ;[22]
|
||||||
|
unstuff2s:
|
||||||
|
in phase, USBIN ;[22] <- phase (one cycle too late)
|
||||||
|
andi fix, ~(1 << 2) ;[23]
|
||||||
|
nop2 ;[16]
|
||||||
|
nop2 ;[18]
|
||||||
|
bit2IsClr:
|
||||||
|
ifrset phase, USBMINUS ;[20] check phase only if D- changed
|
||||||
|
lpm ;[21]
|
||||||
|
in phase, USBIN ;[22] <- phase (one cycle too late)
|
||||||
|
ori shift, 1 << 2 ;[23]
|
||||||
|
bit3AfterClr:
|
||||||
|
st y+, data ;[24]
|
||||||
|
entryAfterClr:
|
||||||
|
ifioset USBIN, USBMINUS ;[26] <--- sample 3
|
||||||
|
rjmp bit3IsSet ;[27]
|
||||||
|
andi shift, ~(7 << 3) ;[28]
|
||||||
|
breq unstuff3c ;[29]
|
||||||
|
in phase, USBIN ;[30] <- phase
|
||||||
|
rjmp bit4AfterClr ;[31]
|
||||||
|
unstuff3c:
|
||||||
|
in phase, USBIN ;[31] <- phase (one cycle too late)
|
||||||
|
andi fix, ~(1 << 3) ;[32]
|
||||||
|
nop2 ;[25]
|
||||||
|
nop2 ;[27]
|
||||||
|
bit3IsSet:
|
||||||
|
ifrclr phase, USBMINUS ;[29] check phase only if D- changed
|
||||||
|
lpm ;[30]
|
||||||
|
in phase, USBIN ;[31] <- phase (one cycle too late)
|
||||||
|
ori shift, 1 << 3 ;[32]
|
||||||
|
bit4AfterSet:
|
||||||
|
mov data, fix ;[33] undo this move by swapping defines
|
||||||
|
#undef fix
|
||||||
|
#define fix x1
|
||||||
|
#undef data
|
||||||
|
#define data x2
|
||||||
|
ifioclr USBIN, USBMINUS ;[34] <--- sample 4
|
||||||
|
rjmp bit4IsClr ;[35]
|
||||||
|
andi shift, ~(7 << 4) ;[36]
|
||||||
|
breq unstuff4s ;[37]
|
||||||
|
in phase, USBIN ;[38] <- phase
|
||||||
|
rjmp bit5AfterSet ;[39]
|
||||||
|
unstuff4s:
|
||||||
|
in phase, USBIN ;[39] <- phase (one cycle too late)
|
||||||
|
andi fix, ~(1 << 4) ;[40]
|
||||||
|
nop2 ;[33]
|
||||||
|
nop2 ;[35]
|
||||||
|
bit4IsClr:
|
||||||
|
ifrset phase, USBMINUS ;[37] check phase only if D- changed
|
||||||
|
lpm ;[38]
|
||||||
|
in phase, USBIN ;[39] <- phase (one cycle too late)
|
||||||
|
ori shift, 1 << 4 ;[40]
|
||||||
|
bit5AfterClr:
|
||||||
|
ser data ;[41]
|
||||||
|
ifioset USBIN, USBMINUS ;[42] <--- sample 5
|
||||||
|
rjmp bit5IsSet ;[43]
|
||||||
|
andi shift, ~(7 << 5) ;[44]
|
||||||
|
breq unstuff5c ;[45]
|
||||||
|
in phase, USBIN ;[46] <- phase
|
||||||
|
rjmp bit6AfterClr ;[47]
|
||||||
|
unstuff5c:
|
||||||
|
in phase, USBIN ;[47] <- phase (one cycle too late)
|
||||||
|
andi fix, ~(1 << 5) ;[48]
|
||||||
|
nop2 ;[41]
|
||||||
|
nop2 ;[43]
|
||||||
|
bit5IsSet:
|
||||||
|
ifrclr phase, USBMINUS ;[45] check phase only if D- changed
|
||||||
|
lpm ;[46]
|
||||||
|
in phase, USBIN ;[47] <- phase (one cycle too late)
|
||||||
|
ori shift, 1 << 5 ;[48]
|
||||||
|
bit6AfterSet:
|
||||||
|
subi cnt, 1 ;[49]
|
||||||
|
brcs jumpToOverflow ;[50]
|
||||||
|
ifioclr USBIN, USBMINUS ;[51] <--- sample 6
|
||||||
|
rjmp bit6IsClr ;[52]
|
||||||
|
andi shift, ~(3 << 6) ;[53]
|
||||||
|
cpi shift, 2 ;[54]
|
||||||
|
in phase, USBIN ;[55] <- phase
|
||||||
|
brlt unstuff6s ;[56]
|
||||||
|
rjmp bit7AfterSet ;[57]
|
||||||
|
|
||||||
|
jumpToOverflow:
|
||||||
|
rjmp overflow
|
||||||
|
|
||||||
|
unstuff6s:
|
||||||
|
andi fix, ~(1 << 6) ;[50]
|
||||||
|
lpm ;[51]
|
||||||
|
bit6IsClr:
|
||||||
|
ifrset phase, USBMINUS ;[54] check phase only if D- changed
|
||||||
|
lpm ;[55]
|
||||||
|
in phase, USBIN ;[56] <- phase (one cycle too late)
|
||||||
|
ori shift, 1 << 6 ;[57]
|
||||||
|
nop ;[58]
|
||||||
|
bit7AfterClr:
|
||||||
|
ifioset USBIN, USBMINUS ;[59] <--- sample 7
|
||||||
|
rjmp bit7IsSet ;[60]
|
||||||
|
andi shift, ~(1 << 7) ;[61]
|
||||||
|
cpi shift, 4 ;[62]
|
||||||
|
in phase, USBIN ;[63] <- phase
|
||||||
|
brlt unstuff7c ;[64]
|
||||||
|
rjmp bit0AfterClr ;[65] -> [00] == [67]
|
||||||
|
unstuff7c:
|
||||||
|
andi fix, ~(1 << 7) ;[58]
|
||||||
|
nop ;[59]
|
||||||
|
rjmp bit7IsSet ;[60]
|
||||||
|
|
||||||
|
se0AndStore:
|
||||||
|
st y+, x1 ;[15/17] cycles after start of byte
|
||||||
|
rjmp se0 ;[17/19]
|
||||||
|
|
||||||
|
bit7IsClr:
|
||||||
|
ifrset phase, USBMINUS ;[62] check phase only if D- changed
|
||||||
|
lpm ;[63]
|
||||||
|
in phase, USBIN ;[64] <- phase (one cycle too late)
|
||||||
|
ori shift, 1 << 7 ;[65]
|
||||||
|
nop ;[66]
|
||||||
|
;;;;rjmp bit0AfterClr ; -> [00] == [67] moved block up to save jump
|
||||||
|
bit0AfterClr:
|
||||||
|
eor fix, shift ;[00]
|
||||||
|
#undef fix
|
||||||
|
#define fix x2
|
||||||
|
#undef data
|
||||||
|
#define data x1 /* we now have result in data, fix is reset to 0xff */
|
||||||
|
ifioset USBIN, USBMINUS ;[01] <--- sample 0
|
||||||
|
rjmp bit0IsSet ;[02]
|
||||||
|
andi shift, ~(7 << 0) ;[03]
|
||||||
|
breq unstuff0c ;[04]
|
||||||
|
in phase, USBIN ;[05] <- phase
|
||||||
|
rjmp bit1AfterClr ;[06]
|
||||||
|
unstuff0c:
|
||||||
|
in phase, USBIN ;[06] <- phase (one cycle too late)
|
||||||
|
andi fix, ~(1 << 0) ;[07]
|
||||||
|
ifioclr USBIN, USBMINUS ;[00]
|
||||||
|
ifioset USBIN, USBPLUS ;[01]
|
||||||
|
rjmp bit0IsSet ;[02] executed if first expr false or second true
|
||||||
|
rjmp se0AndStore ;[03] executed only if both bits 0
|
||||||
|
bit0IsSet:
|
||||||
|
ifrclr phase, USBMINUS ;[04] check phase only if D- changed
|
||||||
|
lpm ;[05]
|
||||||
|
in phase, USBIN ;[06] <- phase (one cycle too late)
|
||||||
|
ori shift, 1 << 0 ;[07]
|
||||||
|
bit1AfterSet:
|
||||||
|
andi phase, USBMASK ;[08]
|
||||||
|
ifioclr USBIN, USBMINUS ;[09] <--- sample 1
|
||||||
|
rjmp bit1IsClr ;[10]
|
||||||
|
andi shift, ~(7 << 1) ;[11]
|
||||||
|
breq unstuff1s ;[12]
|
||||||
|
in phase, USBIN ;[13] <- phase
|
||||||
|
nop ;[14]
|
||||||
|
rjmp bit2AfterSet ;[15]
|
||||||
|
unstuff1s:
|
||||||
|
in phase, USBIN ;[14] <- phase (one cycle too late)
|
||||||
|
andi fix, ~(1 << 1) ;[15]
|
||||||
|
nop2 ;[08]
|
||||||
|
nop2 ;[10]
|
||||||
|
bit1IsClr:
|
||||||
|
ifrset phase, USBMINUS ;[12] check phase only if D- changed
|
||||||
|
lpm ;[13]
|
||||||
|
in phase, USBIN ;[14] <- phase (one cycle too late)
|
||||||
|
breq se0AndStore ;[15] if we come from unstuff1s, Z bit is never set
|
||||||
|
ori shift, 1 << 1 ;[16]
|
||||||
|
bit2AfterClr:
|
||||||
|
ifioset USBIN, USBMINUS ;[17] <--- sample 2
|
||||||
|
rjmp bit2IsSet ;[18]
|
||||||
|
andi shift, ~(7 << 2) ;[19]
|
||||||
|
breq unstuff2c ;[20]
|
||||||
|
in phase, USBIN ;[21] <- phase
|
||||||
|
rjmp bit3AfterClr ;[22]
|
||||||
|
unstuff2c:
|
||||||
|
in phase, USBIN ;[22] <- phase (one cycle too late)
|
||||||
|
andi fix, ~(1 << 2) ;[23]
|
||||||
|
nop2 ;[16]
|
||||||
|
nop2 ;[18]
|
||||||
|
bit2IsSet:
|
||||||
|
ifrclr phase, USBMINUS ;[20] check phase only if D- changed
|
||||||
|
lpm ;[21]
|
||||||
|
in phase, USBIN ;[22] <- phase (one cycle too late)
|
||||||
|
ori shift, 1 << 2 ;[23]
|
||||||
|
bit3AfterSet:
|
||||||
|
st y+, data ;[24]
|
||||||
|
entryAfterSet:
|
||||||
|
ifioclr USBIN, USBMINUS ;[26] <--- sample 3
|
||||||
|
rjmp bit3IsClr ;[27]
|
||||||
|
andi shift, ~(7 << 3) ;[28]
|
||||||
|
breq unstuff3s ;[29]
|
||||||
|
in phase, USBIN ;[30] <- phase
|
||||||
|
rjmp bit4AfterSet ;[31]
|
||||||
|
unstuff3s:
|
||||||
|
in phase, USBIN ;[31] <- phase (one cycle too late)
|
||||||
|
andi fix, ~(1 << 3) ;[32]
|
||||||
|
nop2 ;[25]
|
||||||
|
nop2 ;[27]
|
||||||
|
bit3IsClr:
|
||||||
|
ifrset phase, USBMINUS ;[29] check phase only if D- changed
|
||||||
|
lpm ;[30]
|
||||||
|
in phase, USBIN ;[31] <- phase (one cycle too late)
|
||||||
|
ori shift, 1 << 3 ;[32]
|
||||||
|
bit4AfterClr:
|
||||||
|
mov data, fix ;[33] undo this move by swapping defines
|
||||||
|
#undef fix
|
||||||
|
#define fix x1
|
||||||
|
#undef data
|
||||||
|
#define data x2
|
||||||
|
ifioset USBIN, USBMINUS ;[34] <--- sample 4
|
||||||
|
rjmp bit4IsSet ;[35]
|
||||||
|
andi shift, ~(7 << 4) ;[36]
|
||||||
|
breq unstuff4c ;[37]
|
||||||
|
in phase, USBIN ;[38] <- phase
|
||||||
|
rjmp bit5AfterClr ;[39]
|
||||||
|
unstuff4c:
|
||||||
|
in phase, USBIN ;[39] <- phase (one cycle too late)
|
||||||
|
andi fix, ~(1 << 4) ;[40]
|
||||||
|
nop2 ;[33]
|
||||||
|
nop2 ;[35]
|
||||||
|
bit4IsSet:
|
||||||
|
ifrclr phase, USBMINUS ;[37] check phase only if D- changed
|
||||||
|
lpm ;[38]
|
||||||
|
in phase, USBIN ;[39] <- phase (one cycle too late)
|
||||||
|
ori shift, 1 << 4 ;[40]
|
||||||
|
bit5AfterSet:
|
||||||
|
ser data ;[41]
|
||||||
|
ifioclr USBIN, USBMINUS ;[42] <--- sample 5
|
||||||
|
rjmp bit5IsClr ;[43]
|
||||||
|
andi shift, ~(7 << 5) ;[44]
|
||||||
|
breq unstuff5s ;[45]
|
||||||
|
in phase, USBIN ;[46] <- phase
|
||||||
|
rjmp bit6AfterSet ;[47]
|
||||||
|
unstuff5s:
|
||||||
|
in phase, USBIN ;[47] <- phase (one cycle too late)
|
||||||
|
andi fix, ~(1 << 5) ;[48]
|
||||||
|
nop2 ;[41]
|
||||||
|
nop2 ;[43]
|
||||||
|
bit5IsClr:
|
||||||
|
ifrset phase, USBMINUS ;[45] check phase only if D- changed
|
||||||
|
lpm ;[46]
|
||||||
|
in phase, USBIN ;[47] <- phase (one cycle too late)
|
||||||
|
ori shift, 1 << 5 ;[48]
|
||||||
|
bit6AfterClr:
|
||||||
|
subi cnt, 1 ;[49]
|
||||||
|
brcs overflow ;[50]
|
||||||
|
ifioset USBIN, USBMINUS ;[51] <--- sample 6
|
||||||
|
rjmp bit6IsSet ;[52]
|
||||||
|
andi shift, ~(3 << 6) ;[53]
|
||||||
|
cpi shift, 2 ;[54]
|
||||||
|
in phase, USBIN ;[55] <- phase
|
||||||
|
brlt unstuff6c ;[56]
|
||||||
|
rjmp bit7AfterClr ;[57]
|
||||||
|
unstuff6c:
|
||||||
|
andi fix, ~(1 << 6) ;[50]
|
||||||
|
lpm ;[51]
|
||||||
|
bit6IsSet:
|
||||||
|
ifrclr phase, USBMINUS ;[54] check phase only if D- changed
|
||||||
|
lpm ;[55]
|
||||||
|
in phase, USBIN ;[56] <- phase (one cycle too late)
|
||||||
|
ori shift, 1 << 6 ;[57]
|
||||||
|
bit7AfterSet:
|
||||||
|
ifioclr USBIN, USBMINUS ;[59] <--- sample 7
|
||||||
|
rjmp bit7IsClr ;[60]
|
||||||
|
andi shift, ~(1 << 7) ;[61]
|
||||||
|
cpi shift, 4 ;[62]
|
||||||
|
in phase, USBIN ;[63] <- phase
|
||||||
|
brlt unstuff7s ;[64]
|
||||||
|
rjmp bit0AfterSet ;[65] -> [00] == [67]
|
||||||
|
unstuff7s:
|
||||||
|
andi fix, ~(1 << 7) ;[58]
|
||||||
|
nop ;[59]
|
||||||
|
rjmp bit7IsClr ;[60]
|
||||||
|
|
||||||
|
macro POP_STANDARD ; 14 cycles
|
||||||
|
pop r0
|
||||||
|
pop cnt
|
||||||
|
pop x3
|
||||||
|
pop x2
|
||||||
|
pop x1
|
||||||
|
pop shift
|
||||||
|
pop YH
|
||||||
|
endm
|
||||||
|
macro POP_RETI ; 5 cycles
|
||||||
|
pop YL
|
||||||
|
out SREG, YL
|
||||||
|
pop YL
|
||||||
|
endm
|
||||||
|
|
||||||
|
#include "asmcommon.inc"
|
||||||
|
|
||||||
|
;----------------------------------------------------------------------------
|
||||||
|
; Transmitting data
|
||||||
|
;----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
txByteLoop:
|
||||||
|
txBitloop:
|
||||||
|
stuffN1Delay: ; [03]
|
||||||
|
ror shift ;[-5] [11] [63]
|
||||||
|
brcc doExorN1 ;[-4] [64]
|
||||||
|
subi x3, 1 ;[-3]
|
||||||
|
brne commonN1 ;[-2]
|
||||||
|
lsl shift ;[-1] compensate ror after rjmp stuffDelay
|
||||||
|
nop ;[00] stuffing consists of just waiting 8 cycles
|
||||||
|
rjmp stuffN1Delay ;[01] after ror, C bit is reliably clear
|
||||||
|
|
||||||
|
sendNakAndReti:
|
||||||
|
ldi cnt, USBPID_NAK ;[-19]
|
||||||
|
rjmp sendCntAndReti ;[-18]
|
||||||
|
sendAckAndReti:
|
||||||
|
ldi cnt, USBPID_ACK ;[-17]
|
||||||
|
sendCntAndReti:
|
||||||
|
mov r0, cnt ;[-16]
|
||||||
|
ldi YL, 0 ;[-15] R0 address is 0
|
||||||
|
ldi YH, 0 ;[-14]
|
||||||
|
ldi cnt, 2 ;[-13]
|
||||||
|
; rjmp usbSendAndReti fallthrough
|
||||||
|
|
||||||
|
; USB spec says:
|
||||||
|
; idle = J
|
||||||
|
; J = (D+ = 0), (D- = 1) or USBOUT = 0x01
|
||||||
|
; K = (D+ = 1), (D- = 0) or USBOUT = 0x02
|
||||||
|
; Spec allows 7.5 bit times from EOP to SOP for replies (= 60 cycles)
|
||||||
|
|
||||||
|
;usbSend:
|
||||||
|
;pointer to data in 'Y'
|
||||||
|
;number of bytes in 'cnt' -- including sync byte
|
||||||
|
;uses: x1...x3, shift, cnt, Y [x1 = mirror USBOUT, x2 = USBMASK, x3 = bitstuff cnt]
|
||||||
|
;Numbers in brackets are time since first bit of sync pattern is sent (start of instruction)
|
||||||
|
usbSendAndReti:
|
||||||
|
in x2, USBDDR ;[-10] 10 cycles until SOP
|
||||||
|
ori x2, USBMASK ;[-9]
|
||||||
|
sbi USBOUT, USBMINUS ;[-8] prepare idle state; D+ and D- must have been 0 (no pullups)
|
||||||
|
out USBDDR, x2 ;[-6] <--- acquire bus
|
||||||
|
in x1, USBOUT ;[-5] port mirror for tx loop
|
||||||
|
ldi shift, 0x40 ;[-4] sync byte is first byte sent (we enter loop after ror)
|
||||||
|
ldi x2, USBMASK ;[-3]
|
||||||
|
doExorN1:
|
||||||
|
eor x1, x2 ;[-2] [06] [62]
|
||||||
|
ldi x3, 6 ;[-1] [07] [63]
|
||||||
|
commonN1:
|
||||||
|
stuffN2Delay:
|
||||||
|
out USBOUT, x1 ;[00] [08] [64] <--- set bit
|
||||||
|
ror shift ;[01]
|
||||||
|
brcc doExorN2 ;[02]
|
||||||
|
subi x3, 1 ;[03]
|
||||||
|
brne commonN2 ;[04]
|
||||||
|
lsl shift ;[05] compensate ror after rjmp stuffDelay
|
||||||
|
rjmp stuffN2Delay ;[06] after ror, C bit is reliably clear
|
||||||
|
doExorN2:
|
||||||
|
eor x1, x2 ;[04] [12]
|
||||||
|
ldi x3, 6 ;[05] [13]
|
||||||
|
commonN2:
|
||||||
|
nop2 ;[06] [14]
|
||||||
|
subi cnt, 171 ;[08] [16] trick: (3 * 171) & 0xff = 1
|
||||||
|
out USBOUT, x1 ;[09] [17] <--- set bit
|
||||||
|
brcs txBitloop ;[10] [27] [44]
|
||||||
|
|
||||||
|
stuff6Delay:
|
||||||
|
ror shift ;[45] [53]
|
||||||
|
brcc doExor6 ;[46]
|
||||||
|
subi x3, 1 ;[47]
|
||||||
|
brne common6 ;[48]
|
||||||
|
lsl shift ;[49] compensate ror after rjmp stuffDelay
|
||||||
|
nop ;[50] stuffing consists of just waiting 8 cycles
|
||||||
|
rjmp stuff6Delay ;[51] after ror, C bit is reliably clear
|
||||||
|
doExor6:
|
||||||
|
eor x1, x2 ;[48] [56]
|
||||||
|
ldi x3, 6 ;[49]
|
||||||
|
common6:
|
||||||
|
stuff7Delay:
|
||||||
|
ror shift ;[50] [58]
|
||||||
|
out USBOUT, x1 ;[51] <--- set bit
|
||||||
|
brcc doExor7 ;[52]
|
||||||
|
subi x3, 1 ;[53]
|
||||||
|
brne common7 ;[54]
|
||||||
|
lsl shift ;[55] compensate ror after rjmp stuffDelay
|
||||||
|
rjmp stuff7Delay ;[56] after ror, C bit is reliably clear
|
||||||
|
doExor7:
|
||||||
|
eor x1, x2 ;[54] [62]
|
||||||
|
ldi x3, 6 ;[55]
|
||||||
|
common7:
|
||||||
|
ld shift, y+ ;[56]
|
||||||
|
nop ;[58]
|
||||||
|
tst cnt ;[59]
|
||||||
|
out USBOUT, x1 ;[60] [00]<--- set bit
|
||||||
|
brne txByteLoop ;[61] [01]
|
||||||
|
;make SE0:
|
||||||
|
cbr x1, USBMASK ;[02] prepare SE0 [spec says EOP may be 15 to 18 cycles]
|
||||||
|
lds x2, usbNewDeviceAddr;[03]
|
||||||
|
lsl x2 ;[05] we compare with left shifted address
|
||||||
|
subi YL, 2 + 0 ;[06] Only assign address on data packets, not ACK/NAK in r0
|
||||||
|
sbci YH, 0 ;[07]
|
||||||
|
out USBOUT, x1 ;[00] <-- out SE0 -- from now 2 bits = 16 cycles until bus idle
|
||||||
|
;2006-03-06: moved transfer of new address to usbDeviceAddr from C-Code to asm:
|
||||||
|
;set address only after data packet was sent, not after handshake
|
||||||
|
breq skipAddrAssign ;[01]
|
||||||
|
sts usbDeviceAddr, x2 ; if not skipped: SE0 is one cycle longer
|
||||||
|
skipAddrAssign:
|
||||||
|
;end of usbDeviceAddress transfer
|
||||||
|
ldi x2, 1<<USB_INTR_PENDING_BIT;[03] int0 occurred during TX -- clear pending flag
|
||||||
|
USB_STORE_PENDING(x2) ;[04]
|
||||||
|
ori x1, USBIDLE ;[05]
|
||||||
|
in x2, USBDDR ;[06]
|
||||||
|
cbr x2, USBMASK ;[07] set both pins to input
|
||||||
|
mov x3, x1 ;[08]
|
||||||
|
cbr x3, USBMASK ;[09] configure no pullup on both pins
|
||||||
|
lpm ;[10]
|
||||||
|
lpm ;[13]
|
||||||
|
out USBOUT, x1 ;[16] <-- out J (idle) -- end of SE0 (EOP signal)
|
||||||
|
out USBDDR, x2 ;[17] <-- release bus now
|
||||||
|
out USBOUT, x3 ;[18] <-- ensure no pull-up resistors are active
|
||||||
|
rjmp doReturn
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
The following PHP script generates a code skeleton for the receiver routine:
|
||||||
|
|
||||||
|
<?php
|
||||||
|
|
||||||
|
function printCmdBuffer($thisBit)
|
||||||
|
{
|
||||||
|
global $cycle;
|
||||||
|
|
||||||
|
$nextBit = ($thisBit + 1) % 8;
|
||||||
|
$s = ob_get_contents();
|
||||||
|
ob_end_clean();
|
||||||
|
$s = str_replace("#", $thisBit, $s);
|
||||||
|
$s = str_replace("@", $nextBit, $s);
|
||||||
|
$lines = explode("\n", $s);
|
||||||
|
for($i = 0; $i < count($lines); $i++){
|
||||||
|
$s = $lines[$i];
|
||||||
|
if(ereg("\\[([0-9-][0-9])\\]", $s, $regs)){
|
||||||
|
$c = $cycle + (int)$regs[1];
|
||||||
|
$s = ereg_replace("\\[[0-9-][0-9]\\]", sprintf("[%02d]", $c), $s);
|
||||||
|
}
|
||||||
|
if(strlen($s) > 0)
|
||||||
|
echo "$s\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function printBit($isAfterSet, $bitNum)
|
||||||
|
{
|
||||||
|
ob_start();
|
||||||
|
if($isAfterSet){
|
||||||
|
?>
|
||||||
|
ifioclr USBIN, USBMINUS ;[00] <--- sample
|
||||||
|
rjmp bit#IsClr ;[01]
|
||||||
|
andi shift, ~(7 << #) ;[02]
|
||||||
|
breq unstuff#s ;[03]
|
||||||
|
in phase, USBIN ;[04] <- phase
|
||||||
|
rjmp bit@AfterSet ;[05]
|
||||||
|
unstuff#s:
|
||||||
|
in phase, USBIN ;[05] <- phase (one cycle too late)
|
||||||
|
andi fix, ~(1 << #) ;[06]
|
||||||
|
nop2 ;[-1]
|
||||||
|
nop2 ;[01]
|
||||||
|
bit#IsClr:
|
||||||
|
ifrset phase, USBMINUS ;[03] check phase only if D- changed
|
||||||
|
lpm ;[04]
|
||||||
|
in phase, USBIN ;[05] <- phase (one cycle too late)
|
||||||
|
ori shift, 1 << # ;[06]
|
||||||
|
<?php
|
||||||
|
}else{
|
||||||
|
?>
|
||||||
|
ifioset USBIN, USBMINUS ;[00] <--- sample
|
||||||
|
rjmp bit#IsSet ;[01]
|
||||||
|
andi shift, ~(7 << #) ;[02]
|
||||||
|
breq unstuff#c ;[03]
|
||||||
|
in phase, USBIN ;[04] <- phase
|
||||||
|
rjmp bit@AfterClr ;[05]
|
||||||
|
unstuff#c:
|
||||||
|
in phase, USBIN ;[05] <- phase (one cycle too late)
|
||||||
|
andi fix, ~(1 << #) ;[06]
|
||||||
|
nop2 ;[-1]
|
||||||
|
nop2 ;[01]
|
||||||
|
bit#IsSet:
|
||||||
|
ifrclr phase, USBMINUS ;[03] check phase only if D- changed
|
||||||
|
lpm ;[04]
|
||||||
|
in phase, USBIN ;[05] <- phase (one cycle too late)
|
||||||
|
ori shift, 1 << # ;[06]
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
printCmdBuffer($bitNum);
|
||||||
|
}
|
||||||
|
|
||||||
|
$bitStartCycles = array(1, 9, 17, 26, 34, 42, 51, 59);
|
||||||
|
for($i = 0; $i < 16; $i++){
|
||||||
|
$bit = $i % 8;
|
||||||
|
$emitClrCode = ($i + (int)($i / 8)) % 2;
|
||||||
|
$cycle = $bitStartCycles[$bit];
|
||||||
|
if($emitClrCode){
|
||||||
|
printf("bit%dAfterClr:\n", $bit);
|
||||||
|
}else{
|
||||||
|
printf("bit%dAfterSet:\n", $bit);
|
||||||
|
}
|
||||||
|
ob_start();
|
||||||
|
echo " ***** ;[-1]\n";
|
||||||
|
printCmdBuffer($bit);
|
||||||
|
printBit(!$emitClrCode, $bit);
|
||||||
|
if($i == 7)
|
||||||
|
echo "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
||||||
|
*****************************************************************************/
|
||||||
707
avr/usbload/usbdrv/usbdrvasm18-crc.inc
Normal file
707
avr/usbload/usbdrv/usbdrvasm18-crc.inc
Normal file
@@ -0,0 +1,707 @@
|
|||||||
|
/* Name: usbdrvasm18.inc
|
||||||
|
* Project: V-USB, virtual USB port for Atmel's(r) AVR(r) microcontrollers
|
||||||
|
* Author: Lukas Schrittwieser (based on 20 MHz usbdrvasm20.inc by Jeroen Benschop)
|
||||||
|
* Creation Date: 2009-01-20
|
||||||
|
* Tabsize: 4
|
||||||
|
* Copyright: (c) 2008 by Lukas Schrittwieser and OBJECTIVE DEVELOPMENT Software GmbH
|
||||||
|
* License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
|
||||||
|
* Revision: $Id: usbdrvasm18-crc.inc 740 2009-04-13 18:23:31Z cs $
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Do not link this file! Link usbdrvasm.S instead, which includes the
|
||||||
|
* appropriate implementation!
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
General Description:
|
||||||
|
This file is the 18 MHz version of the asssembler part of the USB driver. It
|
||||||
|
requires a 18 MHz crystal (not a ceramic resonator and not a calibrated RC
|
||||||
|
oscillator).
|
||||||
|
|
||||||
|
See usbdrv.h for a description of the entire driver.
|
||||||
|
|
||||||
|
Since almost all of this code is timing critical, don't change unless you
|
||||||
|
really know what you are doing! Many parts require not only a maximum number
|
||||||
|
of CPU cycles, but even an exact number of cycles!
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
;max stack usage: [ret(2), YL, SREG, YH, [sofError], bitcnt(x5), shift, x1, x2, x3, x4, cnt, ZL, ZH] = 14 bytes
|
||||||
|
;nominal frequency: 18 MHz -> 12 cycles per bit
|
||||||
|
; Numbers in brackets are clocks counted from center of last sync bit
|
||||||
|
; when instruction starts
|
||||||
|
;register use in receive loop to receive the data bytes:
|
||||||
|
; shift assembles the byte currently being received
|
||||||
|
; x1 holds the D+ and D- line state
|
||||||
|
; x2 holds the previous line state
|
||||||
|
; cnt holds the number of bytes left in the receive buffer
|
||||||
|
; x3 holds the higher crc byte (see algorithm below)
|
||||||
|
; x4 is used as temporary register for the crc algorithm
|
||||||
|
; x5 is used for unstuffing: when unstuffing the last received bit is inverted in shift (to prevent further
|
||||||
|
; unstuffing calls. In the same time the corresponding bit in x5 is cleared to mark the bit as beening iverted
|
||||||
|
; zl lower crc value and crc table index
|
||||||
|
; zh used for crc table accesses
|
||||||
|
|
||||||
|
;--------------------------------------------------------------------------------------------------------------
|
||||||
|
; CRC mods:
|
||||||
|
; table driven crc checker, Z points to table in prog space
|
||||||
|
; ZL is the lower crc byte, x3 is the higher crc byte
|
||||||
|
; x4 is used as temp register to store different results
|
||||||
|
; the initialization of the crc register is not 0xFFFF but 0xFE54. This is because during the receipt of the
|
||||||
|
; first data byte an virtual zero data byte is added to the crc register, this results in the correct initial
|
||||||
|
; value of 0xFFFF at beginning of the second data byte before the first data byte is added to the crc.
|
||||||
|
; The magic number 0xFE54 results form the crc table: At tabH[0x54] = 0xFF = crcH (required) and
|
||||||
|
; tabL[0x54] = 0x01 -> crcL = 0x01 xor 0xFE = 0xFF
|
||||||
|
; bitcnt is renamed to x5 and is used for unstuffing purposes, the unstuffing works like in the 12MHz version
|
||||||
|
;--------------------------------------------------------------------------------------------------------------
|
||||||
|
; CRC algorithm:
|
||||||
|
; The crc register is formed by x3 (higher byte) and ZL (lower byte). The algorithm uses a 'reversed' form
|
||||||
|
; i.e. that it takes the least significant bit first and shifts to the right. So in fact the highest order
|
||||||
|
; bit seen from the polynomial devision point of view is the lsb of ZL. (If this sounds strange to you i
|
||||||
|
; propose a research on CRC :-) )
|
||||||
|
; Each data byte received is xored to ZL, the lower crc byte. This byte now builds the crc
|
||||||
|
; table index. Next the new high byte is loaded from the table and stored in x4 until we have space in x3
|
||||||
|
; (its destination).
|
||||||
|
; Afterwards the lower table is loaded from the table and stored in ZL (the old index is overwritten as
|
||||||
|
; we don't need it anymore. In fact this is a right shift by 8 bits.) Now the old crc high value is xored
|
||||||
|
; to ZL, this is the second shift of the old crc value. Now x4 (the temp reg) is moved to x3 and the crc
|
||||||
|
; calculation is done.
|
||||||
|
; Prior to the first byte the two CRC register have to be initialized to 0xFFFF (as defined in usb spec)
|
||||||
|
; however the crc engine also runs during the receipt of the first byte, therefore x3 and zl are initialized
|
||||||
|
; to a magic number which results in a crc value of 0xFFFF after the first complete byte.
|
||||||
|
;
|
||||||
|
; This algorithm is split into the extra cycles of the different bits:
|
||||||
|
; bit7: XOR the received byte to ZL
|
||||||
|
; bit5: load the new high byte to x4
|
||||||
|
; bit6: load the lower xor byte from the table, xor zl and x3, store result in zl (=the new crc low value)
|
||||||
|
; move x4 (the new high byte) to x3, the crc value is ready
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
|
macro POP_STANDARD ; 18 cycles
|
||||||
|
pop ZH
|
||||||
|
pop ZL
|
||||||
|
pop cnt
|
||||||
|
pop x5
|
||||||
|
pop x3
|
||||||
|
pop x2
|
||||||
|
pop x1
|
||||||
|
pop shift
|
||||||
|
pop x4
|
||||||
|
endm
|
||||||
|
macro POP_RETI ; 7 cycles
|
||||||
|
pop YH
|
||||||
|
pop YL
|
||||||
|
out SREG, YL
|
||||||
|
pop YL
|
||||||
|
endm
|
||||||
|
|
||||||
|
macro CRC_CLEANUP_AND_CHECK
|
||||||
|
; the last byte has already been xored with the lower crc byte, we have to do the table lookup and xor
|
||||||
|
; x3 is the higher crc byte, zl the lower one
|
||||||
|
ldi ZH, hi8(usbCrcTableHigh);[+1] get the new high byte from the table
|
||||||
|
lpm x2, Z ;[+2][+3][+4]
|
||||||
|
ldi ZH, hi8(usbCrcTableLow);[+5] get the new low xor byte from the table
|
||||||
|
lpm ZL, Z ;[+6][+7][+8]
|
||||||
|
eor ZL, x3 ;[+7] xor the old high byte with the value from the table, x2:ZL now holds the crc value
|
||||||
|
cpi ZL, 0x01 ;[+8] if the crc is ok we have a fixed remainder value of 0xb001 in x2:ZL (see usb spec)
|
||||||
|
brne ignorePacket ;[+9] detected a crc fault -> paket is ignored and retransmitted by the host
|
||||||
|
cpi x2, 0xb0 ;[+10]
|
||||||
|
brne ignorePacket ;[+11] detected a crc fault -> paket is ignored and retransmitted by the host
|
||||||
|
endm
|
||||||
|
|
||||||
|
|
||||||
|
USB_INTR_VECTOR:
|
||||||
|
;order of registers pushed: YL, SREG, YH, [sofError], x4, shift, x1, x2, x3, x5, cnt, ZL, ZH
|
||||||
|
push YL ;[-28] push only what is necessary to sync with edge ASAP
|
||||||
|
in YL, SREG ;[-26]
|
||||||
|
push YL ;[-25]
|
||||||
|
push YH ;[-23]
|
||||||
|
;----------------------------------------------------------------------------
|
||||||
|
; Synchronize with sync pattern:
|
||||||
|
;----------------------------------------------------------------------------
|
||||||
|
;sync byte (D-) pattern LSb to MSb: 01010100 [1 = idle = J, 0 = K]
|
||||||
|
;sync up with J to K edge during sync pattern -- use fastest possible loops
|
||||||
|
;The first part waits at most 1 bit long since we must be in sync pattern.
|
||||||
|
;YL is guarenteed to be < 0x80 because I flag is clear. When we jump to
|
||||||
|
;waitForJ, ensure that this prerequisite is met.
|
||||||
|
waitForJ:
|
||||||
|
inc YL
|
||||||
|
sbis USBIN, USBMINUS
|
||||||
|
brne waitForJ ; just make sure we have ANY timeout
|
||||||
|
waitForK:
|
||||||
|
;The following code results in a sampling window of < 1/4 bit which meets the spec.
|
||||||
|
sbis USBIN, USBMINUS ;[-17]
|
||||||
|
rjmp foundK ;[-16]
|
||||||
|
sbis USBIN, USBMINUS
|
||||||
|
rjmp foundK
|
||||||
|
sbis USBIN, USBMINUS
|
||||||
|
rjmp foundK
|
||||||
|
sbis USBIN, USBMINUS
|
||||||
|
rjmp foundK
|
||||||
|
sbis USBIN, USBMINUS
|
||||||
|
rjmp foundK
|
||||||
|
sbis USBIN, USBMINUS
|
||||||
|
rjmp foundK
|
||||||
|
sbis USBIN, USBMINUS
|
||||||
|
rjmp foundK
|
||||||
|
sbis USBIN, USBMINUS
|
||||||
|
rjmp foundK
|
||||||
|
sbis USBIN, USBMINUS
|
||||||
|
rjmp foundK
|
||||||
|
#if USB_COUNT_SOF
|
||||||
|
lds YL, usbSofCount
|
||||||
|
inc YL
|
||||||
|
sts usbSofCount, YL
|
||||||
|
#endif /* USB_COUNT_SOF */
|
||||||
|
#ifdef USB_SOF_HOOK
|
||||||
|
USB_SOF_HOOK
|
||||||
|
#endif
|
||||||
|
rjmp sofError
|
||||||
|
foundK: ;[-15]
|
||||||
|
;{3, 5} after falling D- edge, average delay: 4 cycles
|
||||||
|
;bit0 should be at 30 (2.5 bits) for center sampling. Currently at 4 so 26 cylces till bit 0 sample
|
||||||
|
;use 1 bit time for setup purposes, then sample again. Numbers in brackets
|
||||||
|
;are cycles from center of first sync (double K) bit after the instruction
|
||||||
|
push x4 ;[-14]
|
||||||
|
; [---] ;[-13]
|
||||||
|
lds YL, usbInputBufOffset;[-12] used to toggle the two usb receive buffers
|
||||||
|
; [---] ;[-11]
|
||||||
|
clr YH ;[-10]
|
||||||
|
subi YL, lo8(-(usbRxBuf));[-9] [rx loop init]
|
||||||
|
sbci YH, hi8(-(usbRxBuf));[-8] [rx loop init]
|
||||||
|
push shift ;[-7]
|
||||||
|
; [---] ;[-6]
|
||||||
|
ldi shift, 0x80 ;[-5] the last bit is the end of byte marker for the pid receiver loop
|
||||||
|
clc ;[-4] the carry has to be clear for receipt of pid bit 0
|
||||||
|
sbis USBIN, USBMINUS ;[-3] we want two bits K (sample 3 cycles too early)
|
||||||
|
rjmp haveTwoBitsK ;[-2]
|
||||||
|
pop shift ;[-1] undo the push from before
|
||||||
|
pop x4 ;[1]
|
||||||
|
rjmp waitForK ;[3] this was not the end of sync, retry
|
||||||
|
; The entire loop from waitForK until rjmp waitForK above must not exceed two
|
||||||
|
; bit times (= 24 cycles).
|
||||||
|
|
||||||
|
;----------------------------------------------------------------------------
|
||||||
|
; push more registers and initialize values while we sample the first bits:
|
||||||
|
;----------------------------------------------------------------------------
|
||||||
|
haveTwoBitsK:
|
||||||
|
push x1 ;[0]
|
||||||
|
push x2 ;[2]
|
||||||
|
push x3 ;[4] crc high byte
|
||||||
|
ldi x2, 1<<USBPLUS ;[6] [rx loop init] current line state is K state. D+=="1", D-=="0"
|
||||||
|
push x5 ;[7]
|
||||||
|
push cnt ;[9]
|
||||||
|
ldi cnt, USB_BUFSIZE ;[11]
|
||||||
|
|
||||||
|
|
||||||
|
;--------------------------------------------------------------------------------------------------------------
|
||||||
|
; receives the pid byte
|
||||||
|
; there is no real unstuffing algorithm implemented here as a stuffing bit is impossible in the pid byte.
|
||||||
|
; That's because the last four bits of the byte are the inverted of the first four bits. If we detect a
|
||||||
|
; unstuffing condition something went wrong and abort
|
||||||
|
; shift has to be initialized to 0x80
|
||||||
|
;--------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
; pid bit 0 - used for even more register saving (we need the z pointer)
|
||||||
|
in x1, USBIN ;[0] sample line state
|
||||||
|
andi x1, USBMASK ;[1] filter only D+ and D- bits
|
||||||
|
eor x2, x1 ;[2] generate inverted of actual bit
|
||||||
|
sbrc x2, USBMINUS ;[3] if the bit is set we received a zero
|
||||||
|
sec ;[4]
|
||||||
|
ror shift ;[5] we perform no unstuffing check here as this is the first bit
|
||||||
|
mov x2, x1 ;[6]
|
||||||
|
push ZL ;[7]
|
||||||
|
;[8]
|
||||||
|
push ZH ;[9]
|
||||||
|
;[10]
|
||||||
|
ldi x3, 0xFE ;[11] x3 is the high order crc value
|
||||||
|
|
||||||
|
|
||||||
|
bitloopPid:
|
||||||
|
in x1, USBIN ;[0] sample line state
|
||||||
|
andi x1, USBMASK ;[1] filter only D+ and D- bits
|
||||||
|
breq nse0 ;[2] both lines are low so handle se0
|
||||||
|
eor x2, x1 ;[3] generate inverted of actual bit
|
||||||
|
sbrc x2, USBMINUS ;[4] set the carry if we received a zero
|
||||||
|
sec ;[5]
|
||||||
|
ror shift ;[6]
|
||||||
|
ldi ZL, 0x54 ;[7] ZL is the low order crc value
|
||||||
|
ser x4 ;[8] the is no bit stuffing check here as the pid bit can't be stuffed. if so
|
||||||
|
; some error occured. In this case the paket is discarded later on anyway.
|
||||||
|
mov x2, x1 ;[9] prepare for the next cycle
|
||||||
|
brcc bitloopPid ;[10] while 0s drop out of shift we get the next bit
|
||||||
|
eor x4, shift ;[11] invert all bits in shift and store result in x4
|
||||||
|
|
||||||
|
;--------------------------------------------------------------------------------------------------------------
|
||||||
|
; receives data bytes and calculates the crc
|
||||||
|
; the last USBIN state has to be in x2
|
||||||
|
; this is only the first half, due to branch distanc limitations the second half of the loop is near the end
|
||||||
|
; of this asm file
|
||||||
|
;--------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
rxDataStart:
|
||||||
|
in x1, USBIN ;[0] sample line state (note: a se0 check is not useful due to bit dribbling)
|
||||||
|
ser x5 ;[1] prepare the unstuff marker register
|
||||||
|
eor x2, x1 ;[2] generates the inverted of the actual bit
|
||||||
|
bst x2, USBMINUS ;[3] copy the bit from x2
|
||||||
|
bld shift, 0 ;[4] and store it in shift
|
||||||
|
mov x2, shift ;[5] make a copy of shift for unstuffing check
|
||||||
|
andi x2, 0xF9 ;[6] mask the last six bits, if we got six zeros (which are six ones in fact)
|
||||||
|
breq unstuff0 ;[7] then Z is set now and we branch to the unstuffing handler
|
||||||
|
didunstuff0:
|
||||||
|
subi cnt, 1 ;[8] cannot use dec because it doesn't affect the carry flag
|
||||||
|
brcs nOverflow ;[9] Too many bytes received. Ignore packet
|
||||||
|
st Y+, x4 ;[10] store the last received byte
|
||||||
|
;[11] st needs two cycles
|
||||||
|
|
||||||
|
; bit1
|
||||||
|
in x2, USBIN ;[0] sample line state
|
||||||
|
andi x1, USBMASK ;[1] check for se0 during bit 0
|
||||||
|
breq nse0 ;[2]
|
||||||
|
andi x2, USBMASK ;[3] check se0 during bit 1
|
||||||
|
breq nse0 ;[4]
|
||||||
|
eor x1, x2 ;[5]
|
||||||
|
bst x1, USBMINUS ;[6]
|
||||||
|
bld shift, 1 ;[7]
|
||||||
|
mov x1, shift ;[8]
|
||||||
|
andi x1, 0xF3 ;[9]
|
||||||
|
breq unstuff1 ;[10]
|
||||||
|
didunstuff1:
|
||||||
|
nop ;[11]
|
||||||
|
|
||||||
|
; bit2
|
||||||
|
in x1, USBIN ;[0] sample line state
|
||||||
|
andi x1, USBMASK ;[1] check for se0 (as there is nothing else to do here
|
||||||
|
breq nOverflow ;[2]
|
||||||
|
eor x2, x1 ;[3] generates the inverted of the actual bit
|
||||||
|
bst x2, USBMINUS ;[4]
|
||||||
|
bld shift, 2 ;[5] store the bit
|
||||||
|
mov x2, shift ;[6]
|
||||||
|
andi x2, 0xE7 ;[7] if we have six zeros here (which means six 1 in the stream)
|
||||||
|
breq unstuff2 ;[8] the next bit is a stuffing bit
|
||||||
|
didunstuff2:
|
||||||
|
nop2 ;[9]
|
||||||
|
;[10]
|
||||||
|
nop ;[11]
|
||||||
|
|
||||||
|
; bit3
|
||||||
|
in x2, USBIN ;[0] sample line state
|
||||||
|
andi x2, USBMASK ;[1] check for se0
|
||||||
|
breq nOverflow ;[2]
|
||||||
|
eor x1, x2 ;[3]
|
||||||
|
bst x1, USBMINUS ;[4]
|
||||||
|
bld shift, 3 ;[5]
|
||||||
|
mov x1, shift ;[6]
|
||||||
|
andi x1, 0xCF ;[7]
|
||||||
|
breq unstuff3 ;[8]
|
||||||
|
didunstuff3:
|
||||||
|
nop ;[9]
|
||||||
|
rjmp rxDataBit4 ;[10]
|
||||||
|
;[11]
|
||||||
|
|
||||||
|
; the avr branch instructions allow an offset of +63 insturction only, so we need this
|
||||||
|
; 'local copy' of se0
|
||||||
|
nse0:
|
||||||
|
rjmp se0 ;[4]
|
||||||
|
;[5]
|
||||||
|
; the same same as for se0 is needed for overflow and StuffErr
|
||||||
|
nOverflow:
|
||||||
|
stuffErr:
|
||||||
|
rjmp overflow
|
||||||
|
|
||||||
|
|
||||||
|
unstuff0: ;[8] this is the branch delay of breq unstuffX
|
||||||
|
andi x1, USBMASK ;[9] do an se0 check here (if the last crc byte ends with 5 one's we might end up here
|
||||||
|
breq didunstuff0 ;[10] event tough the message is complete -> jump back and store the byte
|
||||||
|
ori shift, 0x01 ;[11] invert the last received bit to prevent furhter unstuffing
|
||||||
|
in x2, USBIN ;[0] we have some free cycles so we could check for bit stuffing errors
|
||||||
|
andi x5, 0xFE ;[1] mark this bit as inverted (will be corrected before storing shift)
|
||||||
|
eor x1, x2 ;[2] x1 and x2 have to be different because the stuff bit is always a zero
|
||||||
|
andi x1, USBMASK ;[3] mask the interesting bits
|
||||||
|
breq stuffErr ;[4] if the stuff bit is a 1-bit something went wrong
|
||||||
|
mov x1, x2 ;[5] the next bit expects the last state to be in x1
|
||||||
|
rjmp didunstuff0 ;[6]
|
||||||
|
;[7] jump delay of rjmp didunstuffX
|
||||||
|
|
||||||
|
unstuff1: ;[11] this is the jump delay of breq unstuffX
|
||||||
|
in x1, USBIN ;[0] we have some free cycles so we could check for bit stuffing errors
|
||||||
|
ori shift, 0x02 ;[1] invert the last received bit to prevent furhter unstuffing
|
||||||
|
andi x5, 0xFD ;[2] mark this bit as inverted (will be corrected before storing shift)
|
||||||
|
eor x2, x1 ;[3] x1 and x2 have to be different because the stuff bit is always a zero
|
||||||
|
andi x2, USBMASK ;[4] mask the interesting bits
|
||||||
|
breq stuffErr ;[5] if the stuff bit is a 1-bit something went wrong
|
||||||
|
mov x2, x1 ;[6] the next bit expects the last state to be in x2
|
||||||
|
nop2 ;[7]
|
||||||
|
;[8]
|
||||||
|
rjmp didunstuff1 ;[9]
|
||||||
|
;[10] jump delay of rjmp didunstuffX
|
||||||
|
|
||||||
|
unstuff2: ;[9] this is the jump delay of breq unstuffX
|
||||||
|
ori shift, 0x04 ;[10] invert the last received bit to prevent furhter unstuffing
|
||||||
|
andi x5, 0xFB ;[11] mark this bit as inverted (will be corrected before storing shift)
|
||||||
|
in x2, USBIN ;[0] we have some free cycles so we could check for bit stuffing errors
|
||||||
|
eor x1, x2 ;[1] x1 and x2 have to be different because the stuff bit is always a zero
|
||||||
|
andi x1, USBMASK ;[2] mask the interesting bits
|
||||||
|
breq stuffErr ;[3] if the stuff bit is a 1-bit something went wrong
|
||||||
|
mov x1, x2 ;[4] the next bit expects the last state to be in x1
|
||||||
|
nop2 ;[5]
|
||||||
|
;[6]
|
||||||
|
rjmp didunstuff2 ;[7]
|
||||||
|
;[8] jump delay of rjmp didunstuffX
|
||||||
|
|
||||||
|
unstuff3: ;[9] this is the jump delay of breq unstuffX
|
||||||
|
ori shift, 0x08 ;[10] invert the last received bit to prevent furhter unstuffing
|
||||||
|
andi x5, 0xF7 ;[11] mark this bit as inverted (will be corrected before storing shift)
|
||||||
|
in x1, USBIN ;[0] we have some free cycles so we could check for bit stuffing errors
|
||||||
|
eor x2, x1 ;[1] x1 and x2 have to be different because the stuff bit is always a zero
|
||||||
|
andi x2, USBMASK ;[2] mask the interesting bits
|
||||||
|
breq stuffErr ;[3] if the stuff bit is a 1-bit something went wrong
|
||||||
|
mov x2, x1 ;[4] the next bit expects the last state to be in x2
|
||||||
|
nop2 ;[5]
|
||||||
|
;[6]
|
||||||
|
rjmp didunstuff3 ;[7]
|
||||||
|
;[8] jump delay of rjmp didunstuffX
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
; the include has to be here due to branch distance restirctions
|
||||||
|
#define __USE_CRC__
|
||||||
|
#include "asmcommon.inc"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
; USB spec says:
|
||||||
|
; idle = J
|
||||||
|
; J = (D+ = 0), (D- = 1)
|
||||||
|
; K = (D+ = 1), (D- = 0)
|
||||||
|
; Spec allows 7.5 bit times from EOP to SOP for replies
|
||||||
|
; 7.5 bit times is 90 cycles. ...there is plenty of time
|
||||||
|
|
||||||
|
|
||||||
|
sendNakAndReti:
|
||||||
|
ldi x3, USBPID_NAK ;[-18]
|
||||||
|
rjmp sendX3AndReti ;[-17]
|
||||||
|
sendAckAndReti:
|
||||||
|
ldi cnt, USBPID_ACK ;[-17]
|
||||||
|
sendCntAndReti:
|
||||||
|
mov x3, cnt ;[-16]
|
||||||
|
sendX3AndReti:
|
||||||
|
ldi YL, 20 ;[-15] x3==r20 address is 20
|
||||||
|
ldi YH, 0 ;[-14]
|
||||||
|
ldi cnt, 2 ;[-13]
|
||||||
|
; rjmp usbSendAndReti fallthrough
|
||||||
|
|
||||||
|
;usbSend:
|
||||||
|
;pointer to data in 'Y'
|
||||||
|
;number of bytes in 'cnt' -- including sync byte [range 2 ... 12]
|
||||||
|
;uses: x1...x4, btcnt, shift, cnt, Y
|
||||||
|
;Numbers in brackets are time since first bit of sync pattern is sent
|
||||||
|
|
||||||
|
usbSendAndReti: ; 12 cycles until SOP
|
||||||
|
in x2, USBDDR ;[-12]
|
||||||
|
ori x2, USBMASK ;[-11]
|
||||||
|
sbi USBOUT, USBMINUS;[-10] prepare idle state; D+ and D- must have been 0 (no pullups)
|
||||||
|
in x1, USBOUT ;[-8] port mirror for tx loop
|
||||||
|
out USBDDR, x2 ;[-6] <- acquire bus
|
||||||
|
ldi x2, 0 ;[-6] init x2 (bitstuff history) because sync starts with 0
|
||||||
|
ldi x4, USBMASK ;[-5] exor mask
|
||||||
|
ldi shift, 0x80 ;[-4] sync byte is first byte sent
|
||||||
|
txByteLoop:
|
||||||
|
ldi bitcnt, 0x40 ;[-3]=[9] binary 01000000
|
||||||
|
txBitLoop: ; the loop sends the first 7 bits of the byte
|
||||||
|
sbrs shift, 0 ;[-2]=[10] if we have to send a 1 don't change the line state
|
||||||
|
eor x1, x4 ;[-1]=[11]
|
||||||
|
out USBOUT, x1 ;[0]
|
||||||
|
ror shift ;[1]
|
||||||
|
ror x2 ;[2] transfers the last sent bit to the stuffing history
|
||||||
|
didStuffN:
|
||||||
|
nop ;[3]
|
||||||
|
nop ;[4]
|
||||||
|
cpi x2, 0xfc ;[5] if we sent six consecutive ones
|
||||||
|
brcc bitstuffN ;[6]
|
||||||
|
lsr bitcnt ;[7]
|
||||||
|
brne txBitLoop ;[8] restart the loop while the 1 is still in the bitcount
|
||||||
|
|
||||||
|
; transmit bit 7
|
||||||
|
sbrs shift, 0 ;[9]
|
||||||
|
eor x1, x4 ;[10]
|
||||||
|
didStuff7:
|
||||||
|
ror shift ;[11]
|
||||||
|
out USBOUT, x1 ;[0] transfer bit 7 to the pins
|
||||||
|
ror x2 ;[1] move the bit into the stuffing history
|
||||||
|
cpi x2, 0xfc ;[2]
|
||||||
|
brcc bitstuff7 ;[3]
|
||||||
|
ld shift, y+ ;[4] get next byte to transmit
|
||||||
|
dec cnt ;[5] decrement byte counter
|
||||||
|
brne txByteLoop ;[7] if we have more bytes start next one
|
||||||
|
;[8] branch delay
|
||||||
|
|
||||||
|
;make SE0:
|
||||||
|
cbr x1, USBMASK ;[8] prepare SE0 [spec says EOP may be 25 to 30 cycles]
|
||||||
|
lds x2, usbNewDeviceAddr;[9]
|
||||||
|
lsl x2 ;[11] we compare with left shifted address
|
||||||
|
out USBOUT, x1 ;[0] <-- out SE0 -- from now 2 bits = 24 cycles until bus idle
|
||||||
|
subi YL, 20 + 2 ;[1] Only assign address on data packets, not ACK/NAK in x3
|
||||||
|
sbci YH, 0 ;[2]
|
||||||
|
;2006-03-06: moved transfer of new address to usbDeviceAddr from C-Code to asm:
|
||||||
|
;set address only after data packet was sent, not after handshake
|
||||||
|
breq skipAddrAssign ;[3]
|
||||||
|
sts usbDeviceAddr, x2 ; if not skipped: SE0 is one cycle longer
|
||||||
|
skipAddrAssign:
|
||||||
|
;end of usbDeviceAddress transfer
|
||||||
|
ldi x2, 1<<USB_INTR_PENDING_BIT;[5] int0 occurred during TX -- clear pending flag
|
||||||
|
USB_STORE_PENDING(x2) ;[6]
|
||||||
|
ori x1, USBIDLE ;[7]
|
||||||
|
in x2, USBDDR ;[8]
|
||||||
|
cbr x2, USBMASK ;[9] set both pins to input
|
||||||
|
mov x3, x1 ;[10]
|
||||||
|
cbr x3, USBMASK ;[11] configure no pullup on both pins
|
||||||
|
ldi x4, 4 ;[12]
|
||||||
|
se0Delay:
|
||||||
|
dec x4 ;[13] [16] [19] [22]
|
||||||
|
brne se0Delay ;[14] [17] [20] [23]
|
||||||
|
out USBOUT, x1 ;[24] <-- out J (idle) -- end of SE0 (EOP signal)
|
||||||
|
out USBDDR, x2 ;[25] <-- release bus now
|
||||||
|
out USBOUT, x3 ;[26] <-- ensure no pull-up resistors are active
|
||||||
|
rjmp doReturn
|
||||||
|
|
||||||
|
bitstuffN:
|
||||||
|
eor x1, x4 ;[8] generate a zero
|
||||||
|
ldi x2, 0 ;[9] reset the bit stuffing history
|
||||||
|
nop2 ;[10]
|
||||||
|
out USBOUT, x1 ;[0] <-- send the stuffing bit
|
||||||
|
rjmp didStuffN ;[1]
|
||||||
|
|
||||||
|
bitstuff7:
|
||||||
|
eor x1, x4 ;[5]
|
||||||
|
ldi x2, 0 ;[6] reset bit stuffing history
|
||||||
|
clc ;[7] fill a zero into the shift register
|
||||||
|
rol shift ;[8] compensate for ror shift at branch destination
|
||||||
|
rjmp didStuff7 ;[9]
|
||||||
|
;[10] jump delay
|
||||||
|
|
||||||
|
;--------------------------------------------------------------------------------------------------------------
|
||||||
|
; receives data bytes and calculates the crc
|
||||||
|
; second half of the data byte receiver loop
|
||||||
|
; most parts of the crc algorithm are here
|
||||||
|
;--------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
nOverflow2:
|
||||||
|
rjmp overflow
|
||||||
|
|
||||||
|
rxDataBit4:
|
||||||
|
in x1, USBIN ;[0] sample line state
|
||||||
|
andi x1, USBMASK ;[1] check for se0
|
||||||
|
breq nOverflow2 ;[2]
|
||||||
|
eor x2, x1 ;[3]
|
||||||
|
bst x2, USBMINUS ;[4]
|
||||||
|
bld shift, 4 ;[5]
|
||||||
|
mov x2, shift ;[6]
|
||||||
|
andi x2, 0x9F ;[7]
|
||||||
|
breq unstuff4 ;[8]
|
||||||
|
didunstuff4:
|
||||||
|
nop2 ;[9][10]
|
||||||
|
nop ;[11]
|
||||||
|
|
||||||
|
; bit5
|
||||||
|
in x2, USBIN ;[0] sample line state
|
||||||
|
ldi ZH, hi8(usbCrcTableHigh);[1] use the table for the higher byte
|
||||||
|
eor x1, x2 ;[2]
|
||||||
|
bst x1, USBMINUS ;[3]
|
||||||
|
bld shift, 5 ;[4]
|
||||||
|
mov x1, shift ;[5]
|
||||||
|
andi x1, 0x3F ;[6]
|
||||||
|
breq unstuff5 ;[7]
|
||||||
|
didunstuff5:
|
||||||
|
lpm x4, Z ;[8] load the higher crc xor-byte and store it for later use
|
||||||
|
;[9] lpm needs 3 cycles
|
||||||
|
;[10]
|
||||||
|
ldi ZH, hi8(usbCrcTableLow);[11] load the lower crc xor byte adress
|
||||||
|
|
||||||
|
; bit6
|
||||||
|
in x1, USBIN ;[0] sample line state
|
||||||
|
eor x2, x1 ;[1]
|
||||||
|
bst x2, USBMINUS ;[2]
|
||||||
|
bld shift, 6 ;[3]
|
||||||
|
mov x2, shift ;[4]
|
||||||
|
andi x2, 0x7E ;[5]
|
||||||
|
breq unstuff6 ;[6]
|
||||||
|
didunstuff6:
|
||||||
|
lpm ZL, Z ;[7] load the lower xor crc byte
|
||||||
|
;[8] lpm needs 3 cycles
|
||||||
|
;[9]
|
||||||
|
eor ZL, x3 ;[10] xor the old high crc byte with the low xor-byte
|
||||||
|
mov x3, x4 ;[11] move the new high order crc value from temp to its destination
|
||||||
|
|
||||||
|
; bit7
|
||||||
|
in x2, USBIN ;[0] sample line state
|
||||||
|
eor x1, x2 ;[1]
|
||||||
|
bst x1, USBMINUS ;[2]
|
||||||
|
bld shift, 7 ;[3] now shift holds the complete but inverted data byte
|
||||||
|
mov x1, shift ;[4]
|
||||||
|
andi x1, 0xFC ;[5]
|
||||||
|
breq unstuff7 ;[6]
|
||||||
|
didunstuff7:
|
||||||
|
eor x5, shift ;[7] x5 marks all bits which have not been inverted by the unstuffing subs
|
||||||
|
mov x4, x5 ;[8] keep a copy of the data byte it will be stored during next bit0
|
||||||
|
eor ZL, x4 ;[9] feed the actual byte into the crc algorithm
|
||||||
|
rjmp rxDataStart ;[10] next byte
|
||||||
|
;[11] during the reception of the next byte this one will be fed int the crc algorithm
|
||||||
|
|
||||||
|
unstuff4: ;[9] this is the jump delay of rjmp unstuffX
|
||||||
|
ori shift, 0x10 ;[10] invert the last received bit to prevent furhter unstuffing
|
||||||
|
andi x5, 0xEF ;[11] mark this bit as inverted (will be corrected before storing shift)
|
||||||
|
in x2, USBIN ;[0] we have some free cycles so we could check for bit stuffing errors
|
||||||
|
eor x1, x2 ;[1] x1 and x2 have to be different because the stuff bit is always a zero
|
||||||
|
andi x1, USBMASK ;[2] mask the interesting bits
|
||||||
|
breq stuffErr2 ;[3] if the stuff bit is a 1-bit something went wrong
|
||||||
|
mov x1, x2 ;[4] the next bit expects the last state to be in x1
|
||||||
|
nop2 ;[5]
|
||||||
|
;[6]
|
||||||
|
rjmp didunstuff4 ;[7]
|
||||||
|
;[8] jump delay of rjmp didunstuffX
|
||||||
|
|
||||||
|
unstuff5: ;[8] this is the jump delay of rjmp unstuffX
|
||||||
|
nop ;[9]
|
||||||
|
ori shift, 0x20 ;[10] invert the last received bit to prevent furhter unstuffing
|
||||||
|
andi x5, 0xDF ;[11] mark this bit as inverted (will be corrected before storing shift)
|
||||||
|
in x1, USBIN ;[0] we have some free cycles so we could check for bit stuffing errors
|
||||||
|
eor x2, x1 ;[1] x1 and x2 have to be different because the stuff bit is always a zero
|
||||||
|
andi x2, USBMASK ;[2] mask the interesting bits
|
||||||
|
breq stuffErr2 ;[3] if the stuff bit is a 1-bit something went wrong
|
||||||
|
mov x2, x1 ;[4] the next bit expects the last state to be in x2
|
||||||
|
nop ;[5]
|
||||||
|
rjmp didunstuff5 ;[6]
|
||||||
|
;[7] jump delay of rjmp didunstuffX
|
||||||
|
|
||||||
|
unstuff6: ;[7] this is the jump delay of rjmp unstuffX
|
||||||
|
nop2 ;[8]
|
||||||
|
;[9]
|
||||||
|
ori shift, 0x40 ;[10] invert the last received bit to prevent furhter unstuffing
|
||||||
|
andi x5, 0xBF ;[11] mark this bit as inverted (will be corrected before storing shift)
|
||||||
|
in x2, USBIN ;[0] we have some free cycles so we could check for bit stuffing errors
|
||||||
|
eor x1, x2 ;[1] x1 and x2 have to be different because the stuff bit is always a zero
|
||||||
|
andi x1, USBMASK ;[2] mask the interesting bits
|
||||||
|
breq stuffErr2 ;[3] if the stuff bit is a 1-bit something went wrong
|
||||||
|
mov x1, x2 ;[4] the next bit expects the last state to be in x1
|
||||||
|
rjmp didunstuff6 ;[5]
|
||||||
|
;[6] jump delay of rjmp didunstuffX
|
||||||
|
|
||||||
|
unstuff7: ;[7] this is the jump delay of rjmp unstuffX
|
||||||
|
nop ;[8]
|
||||||
|
nop ;[9]
|
||||||
|
ori shift, 0x80 ;[10] invert the last received bit to prevent furhter unstuffing
|
||||||
|
andi x5, 0x7F ;[11] mark this bit as inverted (will be corrected before storing shift)
|
||||||
|
in x1, USBIN ;[0] we have some free cycles so we could check for bit stuffing errors
|
||||||
|
eor x2, x1 ;[1] x1 and x2 have to be different because the stuff bit is always a zero
|
||||||
|
andi x2, USBMASK ;[2] mask the interesting bits
|
||||||
|
breq stuffErr2 ;[3] if the stuff bit is a 1-bit something went wrong
|
||||||
|
mov x2, x1 ;[4] the next bit expects the last state to be in x2
|
||||||
|
rjmp didunstuff7 ;[5]
|
||||||
|
;[6] jump delay of rjmp didunstuff7
|
||||||
|
|
||||||
|
; local copy of the stuffErr desitnation for the second half of the receiver loop
|
||||||
|
stuffErr2:
|
||||||
|
rjmp stuffErr
|
||||||
|
|
||||||
|
;--------------------------------------------------------------------------------------------------------------
|
||||||
|
; The crc table follows. It has to be aligned to enable a fast loading of the needed bytes.
|
||||||
|
; There are two tables of 256 entries each, the low and the high byte table.
|
||||||
|
; Table values were generated with the following C code:
|
||||||
|
/*
|
||||||
|
#include <stdio.h>
|
||||||
|
int main (int argc, char **argv)
|
||||||
|
{
|
||||||
|
int i, j;
|
||||||
|
for (i=0; i<512; i++){
|
||||||
|
unsigned short crc = i & 0xff;
|
||||||
|
for(j=0; j<8; j++) crc = (crc >> 1) ^ ((crc & 1) ? 0xa001 : 0);
|
||||||
|
if((i & 7) == 0) printf("\n.byte ");
|
||||||
|
printf("0x%02x, ", (i > 0xff ? (crc >> 8) : crc) & 0xff);
|
||||||
|
if(i == 255) printf("\n");
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use the following algorithm to compute CRC values:
|
||||||
|
ushort computeCrc(uchar *msg, uchar msgLen)
|
||||||
|
{
|
||||||
|
uchar i;
|
||||||
|
ushort crc = 0xffff;
|
||||||
|
for(i = 0; i < msgLen; i++)
|
||||||
|
crc = usbCrcTable16[lo8(crc) ^ msg[i]] ^ hi8(crc);
|
||||||
|
return crc;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
.balign 256
|
||||||
|
usbCrcTableLow:
|
||||||
|
.byte 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41
|
||||||
|
.byte 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40
|
||||||
|
.byte 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40
|
||||||
|
.byte 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41
|
||||||
|
.byte 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40
|
||||||
|
.byte 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41
|
||||||
|
.byte 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41
|
||||||
|
.byte 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40
|
||||||
|
.byte 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40
|
||||||
|
.byte 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41
|
||||||
|
.byte 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41
|
||||||
|
.byte 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40
|
||||||
|
.byte 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41
|
||||||
|
.byte 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40
|
||||||
|
.byte 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40
|
||||||
|
.byte 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41
|
||||||
|
.byte 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40
|
||||||
|
.byte 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41
|
||||||
|
.byte 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41
|
||||||
|
.byte 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40
|
||||||
|
.byte 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41
|
||||||
|
.byte 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40
|
||||||
|
.byte 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40
|
||||||
|
.byte 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41
|
||||||
|
.byte 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41
|
||||||
|
.byte 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40
|
||||||
|
.byte 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40
|
||||||
|
.byte 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41
|
||||||
|
.byte 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40
|
||||||
|
.byte 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41
|
||||||
|
.byte 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41
|
||||||
|
.byte 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40
|
||||||
|
|
||||||
|
; .balign 256
|
||||||
|
usbCrcTableHigh:
|
||||||
|
.byte 0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2
|
||||||
|
.byte 0xC6, 0x06, 0x07, 0xC7, 0x05, 0xC5, 0xC4, 0x04
|
||||||
|
.byte 0xCC, 0x0C, 0x0D, 0xCD, 0x0F, 0xCF, 0xCE, 0x0E
|
||||||
|
.byte 0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09, 0x08, 0xC8
|
||||||
|
.byte 0xD8, 0x18, 0x19, 0xD9, 0x1B, 0xDB, 0xDA, 0x1A
|
||||||
|
.byte 0x1E, 0xDE, 0xDF, 0x1F, 0xDD, 0x1D, 0x1C, 0xDC
|
||||||
|
.byte 0x14, 0xD4, 0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6
|
||||||
|
.byte 0xD2, 0x12, 0x13, 0xD3, 0x11, 0xD1, 0xD0, 0x10
|
||||||
|
.byte 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3, 0xF2, 0x32
|
||||||
|
.byte 0x36, 0xF6, 0xF7, 0x37, 0xF5, 0x35, 0x34, 0xF4
|
||||||
|
.byte 0x3C, 0xFC, 0xFD, 0x3D, 0xFF, 0x3F, 0x3E, 0xFE
|
||||||
|
.byte 0xFA, 0x3A, 0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38
|
||||||
|
.byte 0x28, 0xE8, 0xE9, 0x29, 0xEB, 0x2B, 0x2A, 0xEA
|
||||||
|
.byte 0xEE, 0x2E, 0x2F, 0xEF, 0x2D, 0xED, 0xEC, 0x2C
|
||||||
|
.byte 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26
|
||||||
|
.byte 0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0
|
||||||
|
.byte 0xA0, 0x60, 0x61, 0xA1, 0x63, 0xA3, 0xA2, 0x62
|
||||||
|
.byte 0x66, 0xA6, 0xA7, 0x67, 0xA5, 0x65, 0x64, 0xA4
|
||||||
|
.byte 0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F, 0x6E, 0xAE
|
||||||
|
.byte 0xAA, 0x6A, 0x6B, 0xAB, 0x69, 0xA9, 0xA8, 0x68
|
||||||
|
.byte 0x78, 0xB8, 0xB9, 0x79, 0xBB, 0x7B, 0x7A, 0xBA
|
||||||
|
.byte 0xBE, 0x7E, 0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C
|
||||||
|
.byte 0xB4, 0x74, 0x75, 0xB5, 0x77, 0xB7, 0xB6, 0x76
|
||||||
|
.byte 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71, 0x70, 0xB0
|
||||||
|
.byte 0x50, 0x90, 0x91, 0x51, 0x93, 0x53, 0x52, 0x92
|
||||||
|
.byte 0x96, 0x56, 0x57, 0x97, 0x55, 0x95, 0x94, 0x54
|
||||||
|
.byte 0x9C, 0x5C, 0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E
|
||||||
|
.byte 0x5A, 0x9A, 0x9B, 0x5B, 0x99, 0x59, 0x58, 0x98
|
||||||
|
.byte 0x88, 0x48, 0x49, 0x89, 0x4B, 0x8B, 0x8A, 0x4A
|
||||||
|
.byte 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C
|
||||||
|
.byte 0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86
|
||||||
|
.byte 0x82, 0x42, 0x43, 0x83, 0x41, 0x81, 0x80, 0x40
|
||||||
|
|
||||||
140
avr/usbload/usbdrv/usbportability.h
Normal file
140
avr/usbload/usbdrv/usbportability.h
Normal file
@@ -0,0 +1,140 @@
|
|||||||
|
/* Name: usbportability.h
|
||||||
|
* Project: V-USB, virtual USB port for Atmel's(r) AVR(r) microcontrollers
|
||||||
|
* Author: Christian Starkjohann
|
||||||
|
* Creation Date: 2008-06-17
|
||||||
|
* Tabsize: 4
|
||||||
|
* Copyright: (c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH
|
||||||
|
* License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
|
||||||
|
* This Revision: $Id: usbportability.h 740 2009-04-13 18:23:31Z cs $
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
General Description:
|
||||||
|
This header is intended to contain all (or at least most of) the compiler
|
||||||
|
and library dependent stuff. The C code is written for avr-gcc and avr-libc.
|
||||||
|
The API of other development environments is converted to gcc's and avr-libc's
|
||||||
|
API by means of defines.
|
||||||
|
|
||||||
|
This header also contains all system includes since they depend on the
|
||||||
|
development environment.
|
||||||
|
|
||||||
|
Thanks to Oleg Semyonov for his help with the IAR tools port!
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __usbportability_h_INCLUDED__
|
||||||
|
#define __usbportability_h_INCLUDED__
|
||||||
|
|
||||||
|
/* We check explicitly for IAR and CodeVision. Default is avr-gcc/avr-libc. */
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------- */
|
||||||
|
#if defined __IAR_SYSTEMS_ICC__ || defined __IAR_SYSTEMS_ASM__ /* check for IAR */
|
||||||
|
/* ------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
#ifndef ENABLE_BIT_DEFINITIONS
|
||||||
|
# define ENABLE_BIT_DEFINITIONS 1 /* Enable bit definitions */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Include IAR headers */
|
||||||
|
#include <ioavr.h>
|
||||||
|
#ifndef __IAR_SYSTEMS_ASM__
|
||||||
|
# include <inavr.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define __attribute__(arg) /* not supported on IAR */
|
||||||
|
|
||||||
|
#ifdef __IAR_SYSTEMS_ASM__
|
||||||
|
# define __ASSEMBLER__ /* IAR does not define standard macro for asm */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __HAS_ELPM__
|
||||||
|
# define PROGMEM __farflash
|
||||||
|
#else
|
||||||
|
# define PROGMEM __flash
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define USB_READ_FLASH(addr) (*(PROGMEM char *)(addr))
|
||||||
|
|
||||||
|
/* The following definitions are not needed by the driver, but may be of some
|
||||||
|
* help if you port a gcc based project to IAR.
|
||||||
|
*/
|
||||||
|
#define cli() __disable_interrupt()
|
||||||
|
#define sei() __enable_interrupt()
|
||||||
|
#define wdt_reset() __watchdog_reset()
|
||||||
|
#define _BV(x) (1 << (x))
|
||||||
|
|
||||||
|
/* assembler compatibility macros */
|
||||||
|
#define nop2 rjmp $+2 /* jump to next instruction */
|
||||||
|
#define XL r26
|
||||||
|
#define XH r27
|
||||||
|
#define YL r28
|
||||||
|
#define YH r29
|
||||||
|
#define ZL r30
|
||||||
|
#define ZH r31
|
||||||
|
#define lo8(x) LOW(x)
|
||||||
|
#define hi8(x) (((x)>>8) & 0xff) /* not HIGH to allow XLINK to make a proper range check */
|
||||||
|
|
||||||
|
/* Depending on the device you use, you may get problems with the way usbdrv.h
|
||||||
|
* handles the differences between devices. Since IAR does not use #defines
|
||||||
|
* for MCU registers, we can't check for the existence of a particular
|
||||||
|
* register with an #ifdef. If the autodetection mechanism fails, include
|
||||||
|
* definitions for the required USB_INTR_* macros in your usbconfig.h. See
|
||||||
|
* usbconfig-prototype.h and usbdrv.h for details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------- */
|
||||||
|
#elif __CODEVISIONAVR__ /* check for CodeVision AVR */
|
||||||
|
/* ------------------------------------------------------------------------- */
|
||||||
|
/* This port is not working (yet) */
|
||||||
|
|
||||||
|
/* #define F_CPU _MCU_CLOCK_FREQUENCY_ seems to be defined automatically */
|
||||||
|
|
||||||
|
#include <io.h>
|
||||||
|
#include <delay.h>
|
||||||
|
|
||||||
|
#define __attribute__(arg) /* not supported on IAR */
|
||||||
|
|
||||||
|
#define PROGMEM __flash
|
||||||
|
#define USB_READ_FLASH(addr) (*(PROGMEM char *)(addr))
|
||||||
|
|
||||||
|
#ifndef __ASSEMBLER__
|
||||||
|
static inline void cli(void)
|
||||||
|
{
|
||||||
|
#asm("cli");
|
||||||
|
}
|
||||||
|
static inline void sei(void)
|
||||||
|
{
|
||||||
|
#asm("sei");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#define _delay_ms(t) delay_ms(t)
|
||||||
|
#define _BV(x) (1 << (x))
|
||||||
|
#define USB_CFG_USE_SWITCH_STATEMENT 1 /* macro for if() cascase fails for unknown reason */
|
||||||
|
|
||||||
|
#define macro .macro
|
||||||
|
#define endm .endmacro
|
||||||
|
#define nop2 rjmp .+0 /* jump to next instruction */
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------- */
|
||||||
|
#else /* default development environment is avr-gcc/avr-libc */
|
||||||
|
/* ------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
#include <avr/io.h>
|
||||||
|
#ifdef __ASSEMBLER__
|
||||||
|
# define _VECTOR(N) __vector_ ## N /* io.h does not define this for asm */
|
||||||
|
#else
|
||||||
|
# include <avr/pgmspace.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define USB_READ_FLASH(addr) pgm_read_byte(addr)
|
||||||
|
|
||||||
|
#define macro .macro
|
||||||
|
#define endm .endm
|
||||||
|
#define nop2 rjmp .+0 /* jump to next instruction */
|
||||||
|
|
||||||
|
#endif /* development environment */
|
||||||
|
|
||||||
|
/* for conveniecne, ensure that PRG_RDB exists */
|
||||||
|
#ifndef PRG_RDB
|
||||||
|
# define PRG_RDB(addr) USB_READ_FLASH(addr)
|
||||||
|
#endif
|
||||||
|
#endif /* __usbportability_h_INCLUDED__ */
|
||||||
31
avr/usbload/watchdog.c
Normal file
31
avr/usbload/watchdog.c
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
/*
|
||||||
|
* =====================================================================================
|
||||||
|
*
|
||||||
|
* ________ .__ __ ________ ____ ________
|
||||||
|
* \_____ \ __ __|__| ____ | | __\______ \ _______ _/_ |/ _____/
|
||||||
|
* / / \ \| | \ |/ ___\| |/ / | | \_/ __ \ \/ /| / __ \
|
||||||
|
* / \_/. \ | / \ \___| < | ` \ ___/\ / | \ |__\ \
|
||||||
|
* \_____\ \_/____/|__|\___ >__|_ \/_______ /\___ >\_/ |___|\_____ /
|
||||||
|
* \__> \/ \/ \/ \/ \/
|
||||||
|
*
|
||||||
|
* www.optixx.org
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Version: 1.0
|
||||||
|
* Created: 07/21/2009 03:32:16 PM
|
||||||
|
* Author: david@optixx.org
|
||||||
|
*
|
||||||
|
* =====================================================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "watchdog.h"
|
||||||
|
|
||||||
|
void wdt_init(void)
|
||||||
|
{
|
||||||
|
MCUSR = 0;
|
||||||
|
wdt_disable();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
42
avr/usbload/watchdog.h
Normal file
42
avr/usbload/watchdog.h
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
/*
|
||||||
|
* =====================================================================================
|
||||||
|
*
|
||||||
|
* ________ .__ __ ________ ____ ________
|
||||||
|
* \_____ \ __ __|__| ____ | | __\______ \ _______ _/_ |/ _____/
|
||||||
|
* / / \ \| | \ |/ ___\| |/ / | | \_/ __ \ \/ /| / __ \
|
||||||
|
* / \_/. \ | / \ \___| < | ` \ ___/\ / | \ |__\ \
|
||||||
|
* \_____\ \_/____/|__|\___ >__|_ \/_______ /\___ >\_/ |___|\_____ /
|
||||||
|
* \__> \/ \/ \/ \/ \/
|
||||||
|
*
|
||||||
|
* www.optixx.org
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Version: 1.0
|
||||||
|
* Created: 07/21/2009 03:32:16 PM
|
||||||
|
* Author: david@optixx.org
|
||||||
|
*
|
||||||
|
* =====================================================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#include <avr/wdt.h>
|
||||||
|
|
||||||
|
#ifndef __WATCHDOG_H__
|
||||||
|
#define __WATCHDOG_H__
|
||||||
|
|
||||||
|
|
||||||
|
void wdt_init(void) __attribute__((naked)) __attribute__((section(".init3")));
|
||||||
|
|
||||||
|
#define soft_reset() \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
wdt_enable(WDTO_500MS );\
|
||||||
|
for(;;) \
|
||||||
|
{ \
|
||||||
|
} \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
22
bugs/issue-032fab33a68ffbeb19f1e9fa4856101996759255.yaml
Normal file
22
bugs/issue-032fab33a68ffbeb19f1e9fa4856101996759255.yaml
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
--- !ditz.rubyforge.org,2008-03-06/issue
|
||||||
|
title: relocate code
|
||||||
|
desc: |-
|
||||||
|
move main code to upper page like 0xe4 and use 0x4f as shared mem window
|
||||||
|
or even combine this
|
||||||
|
code seems to reloacte and start, but ram doesn't seem accessable. broked
|
||||||
|
sprintfs
|
||||||
|
type: :bugfix
|
||||||
|
component: fatfs
|
||||||
|
release:
|
||||||
|
reporter: David <david@optixx.org>
|
||||||
|
status: :unstarted
|
||||||
|
disposition:
|
||||||
|
creation_time: 2009-06-10 14:22:10.400739 Z
|
||||||
|
references: []
|
||||||
|
|
||||||
|
id: 032fab33a68ffbeb19f1e9fa4856101996759255
|
||||||
|
log_events:
|
||||||
|
- - 2009-06-10 14:22:11.288638 Z
|
||||||
|
- David <david@optixx.org>
|
||||||
|
- created
|
||||||
|
- ""
|
||||||
21
bugs/issue-6498cae9de5e51829e5dbb6b8fcaa20c7a647aa6.yaml
Normal file
21
bugs/issue-6498cae9de5e51829e5dbb6b8fcaa20c7a647aa6.yaml
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
--- !ditz.rubyforge.org,2008-03-06/issue
|
||||||
|
title: "debug ram mapping "
|
||||||
|
desc: |-
|
||||||
|
global vars seem to be borked or miss used. seems all kind of buffers are overlapping
|
||||||
|
just reordering global var order renders the code unusable.
|
||||||
|
also the strange sprintf buffer conflicts seem to related to this issue
|
||||||
|
type: :bugfix
|
||||||
|
component: fatfs
|
||||||
|
release:
|
||||||
|
reporter: David <david@optixx.org>
|
||||||
|
status: :unstarted
|
||||||
|
disposition:
|
||||||
|
creation_time: 2009-06-10 14:23:44.121219 Z
|
||||||
|
references: []
|
||||||
|
|
||||||
|
id: 6498cae9de5e51829e5dbb6b8fcaa20c7a647aa6
|
||||||
|
log_events:
|
||||||
|
- - 2009-06-10 14:23:45.632999 Z
|
||||||
|
- David <david@optixx.org>
|
||||||
|
- created
|
||||||
|
- ""
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user