mirror of
https://gitea.osmocom.org/sim-card/simtrace2.git
synced 2026-03-17 21:58:33 +03:00
Compare commits
194 Commits
christina/
...
0.2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0de99cd069 | ||
|
|
ac4f66e5d1 | ||
|
|
91fc40240e | ||
|
|
b04f4f0ee8 | ||
|
|
e8eea29cf6 | ||
|
|
d1e963479e | ||
|
|
db17e83960 | ||
|
|
ec9b5fff3f | ||
|
|
0af4948211 | ||
|
|
adbe72a5ba | ||
|
|
e36970cac7 | ||
|
|
cab66419d6 | ||
|
|
479e97e338 | ||
|
|
203abf5f6e | ||
|
|
ee9ebb30da | ||
|
|
b2ad7f76a1 | ||
|
|
0395bd15b3 | ||
|
|
c430ac1f2a | ||
|
|
adba0ce80b | ||
|
|
65cca7cccc | ||
|
|
db30727514 | ||
|
|
32852bc1d9 | ||
|
|
edf9c9d322 | ||
|
|
37b6e41f84 | ||
|
|
964f509f59 | ||
|
|
96e62a4664 | ||
|
|
045ea3eb7b | ||
|
|
d09829dcc6 | ||
|
|
d52523185f | ||
|
|
d8a003dfd7 | ||
|
|
a1cd0f31c8 | ||
|
|
3f5e3ddffc | ||
|
|
7ed6f3bc37 | ||
|
|
aa3b867abb | ||
|
|
a05ccc9103 | ||
|
|
e9eaf90d35 | ||
|
|
1d91058eee | ||
|
|
4a9bce127f | ||
|
|
6732248f71 | ||
|
|
9c78cff10b | ||
|
|
987f59aa02 | ||
|
|
b41598b602 | ||
|
|
7e5c7d5b82 | ||
|
|
31f817c3ac | ||
|
|
83207e0cad | ||
|
|
2819e9c131 | ||
|
|
af6147997d | ||
|
|
fb3f308f2f | ||
|
|
84ad98585c | ||
|
|
7861132fad | ||
|
|
b871363be7 | ||
|
|
b30783c83e | ||
|
|
ae8a465f36 | ||
|
|
6dfcf70f63 | ||
|
|
f9a182d24d | ||
|
|
afbb747170 | ||
|
|
e07aed6543 | ||
|
|
396354cbdb | ||
|
|
006b16ddc2 | ||
|
|
e974fbb9e5 | ||
|
|
15e026ec34 | ||
|
|
4e3b9a5140 | ||
|
|
67415e3385 | ||
|
|
73d697d788 | ||
|
|
0aea9fff28 | ||
|
|
c6ae98c53a | ||
|
|
226b40aba4 | ||
|
|
a02b641650 | ||
|
|
fd9c041ec8 | ||
|
|
990f01051f | ||
|
|
e26c943fa1 | ||
|
|
622b6be774 | ||
|
|
3bafe43376 | ||
|
|
dde112e71c | ||
|
|
8ee15dbc2a | ||
|
|
28772ebcdc | ||
|
|
1871c25b6d | ||
|
|
cf1c19abe0 | ||
|
|
04e37a8481 | ||
|
|
5541e8a819 | ||
|
|
9daaa79222 | ||
|
|
53079bbbac | ||
|
|
c58bba0833 | ||
|
|
c8beefbf85 | ||
|
|
903d63a1e0 | ||
|
|
52d554657c | ||
|
|
ccb8a22037 | ||
|
|
a929f218d2 | ||
|
|
07872b6cdd | ||
|
|
6dcacf3efe | ||
|
|
419eb8acf2 | ||
|
|
ff16065047 | ||
|
|
02d5096b31 | ||
|
|
2315e6ba07 | ||
|
|
236caf68eb | ||
|
|
095ac6cbe2 | ||
|
|
b26d0038f6 | ||
|
|
d295b92192 | ||
|
|
b8f9450c18 | ||
|
|
9f240b6d34 | ||
|
|
da15ca01bf | ||
|
|
3d27c84635 | ||
|
|
250cd2c062 | ||
|
|
372f4cc7ba | ||
|
|
5820ea9327 | ||
|
|
0eaa992682 | ||
|
|
7abdb51f8f | ||
|
|
7dd3dfd992 | ||
|
|
1605564489 | ||
|
|
072daddf98 | ||
|
|
40901a0f14 | ||
|
|
57b3a250d4 | ||
|
|
13e8202c81 | ||
|
|
06b27f64a2 | ||
|
|
ebb80eda19 | ||
|
|
ad43440d93 | ||
|
|
5e00400a05 | ||
|
|
a0cf200695 | ||
|
|
acd48c51f2 | ||
|
|
fcdd660fb1 | ||
|
|
fde250a54b | ||
|
|
715bc05f55 | ||
|
|
12d4bdfbb1 | ||
|
|
dda7355306 | ||
|
|
f1697e2dd9 | ||
|
|
acae412b2a | ||
|
|
8a416b1812 | ||
|
|
45688d4c3b | ||
|
|
349c54bc3b | ||
|
|
22925ea707 | ||
|
|
4678388c3c | ||
|
|
ebbb645f4b | ||
|
|
54cb3d017f | ||
|
|
f672e9d63a | ||
|
|
b66ce249d0 | ||
|
|
22bf67fc9c | ||
|
|
708d85c085 | ||
|
|
c0bd7f0aaa | ||
|
|
47ee283d14 | ||
|
|
99f62a6def | ||
|
|
2ad0ca15a8 | ||
|
|
43f7949fe0 | ||
|
|
b086ab0242 | ||
|
|
9dbc46e799 | ||
|
|
ba0c688103 | ||
|
|
4dc3db7beb | ||
|
|
203ea19227 | ||
|
|
bd71768e5f | ||
|
|
2a6d3afd6c | ||
|
|
29f8f0e5d4 | ||
|
|
2fb5996d30 | ||
|
|
8c49636127 | ||
|
|
390760a006 | ||
|
|
54a7cec7bd | ||
|
|
17db2f1112 | ||
|
|
4ba66d0098 | ||
|
|
86d047b8f4 | ||
|
|
0ef96d5735 | ||
|
|
0ab6fcd173 | ||
|
|
c043e64ef1 | ||
|
|
eef6c2a46c | ||
|
|
f16b618755 | ||
|
|
22cdf2af59 | ||
|
|
6bf8c12b13 | ||
|
|
042f0d366b | ||
|
|
855ba9e168 | ||
|
|
849269f4cc | ||
|
|
2d3371ed65 | ||
|
|
61bb30e4ea | ||
|
|
84ec252ff4 | ||
|
|
4d8046743e | ||
|
|
b5288e8ac4 | ||
|
|
e7194abb9e | ||
|
|
52922ffa32 | ||
|
|
05b41c62f6 | ||
|
|
2935b3c479 | ||
|
|
b436286ed6 | ||
|
|
836990d244 | ||
|
|
d79dc4f6f2 | ||
|
|
4c473dad30 | ||
|
|
612d65ad62 | ||
|
|
16cf408a49 | ||
|
|
9d3e38242c | ||
|
|
f64f68871e | ||
|
|
30a53f823a | ||
|
|
6d44c1fdd3 | ||
|
|
8a5b580a72 | ||
|
|
ec4fe2358b | ||
|
|
844db577f2 | ||
|
|
beb729391b | ||
|
|
8d6a5d8f89 | ||
|
|
d4c1421c91 | ||
|
|
fefd571701 | ||
|
|
15d72cc631 |
14
.gitignore
vendored
14
.gitignore
vendored
@@ -7,7 +7,15 @@ cscope.out
|
|||||||
*/__pycache__
|
*/__pycache__
|
||||||
*.E
|
*.E
|
||||||
*.pyc
|
*.pyc
|
||||||
sam3s_example/mains/zwizwa_ccid.c
|
|
||||||
Baselibc
|
|
||||||
venv
|
|
||||||
tags
|
tags
|
||||||
|
*.hobj
|
||||||
|
*.o
|
||||||
|
*.a
|
||||||
|
*.lst
|
||||||
|
*.map
|
||||||
|
*.elf
|
||||||
|
*.size
|
||||||
|
*.bin
|
||||||
|
*.p
|
||||||
|
host/simtrace2-remsim
|
||||||
|
host/simtrace2-remsim-usb2udp
|
||||||
|
|||||||
@@ -34,49 +34,34 @@
|
|||||||
|
|
||||||
# Chip & board used for compilation
|
# Chip & board used for compilation
|
||||||
# (can be overriden by adding CHIP=chip and BOARD=board to the command-line)
|
# (can be overriden by adding CHIP=chip and BOARD=board to the command-line)
|
||||||
CHIP = sam3s2
|
CHIP ?= sam3s4
|
||||||
BOARD = simtrace
|
BOARD ?= qmod
|
||||||
|
|
||||||
# Defines which are the available memory targets for the SAM3S-EK board.
|
# Defines which are the available memory targets for the SAM3S-EK board.
|
||||||
MEMORIES = flash
|
MEMORIES ?= flash dfu
|
||||||
|
|
||||||
# Trace level used for compilation
|
|
||||||
# (can be overriden by adding TRACE_LEVEL=#number to the command-line)
|
|
||||||
# TRACE_LEVEL_DEBUG 5
|
|
||||||
# TRACE_LEVEL_INFO 4
|
|
||||||
# TRACE_LEVEL_WARNING 3
|
|
||||||
# TRACE_LEVEL_ERROR 2
|
|
||||||
# TRACE_LEVEL_FATAL 1
|
|
||||||
# TRACE_LEVEL_NO_TRACE 0
|
|
||||||
TRACE_LEVEL = 1
|
|
||||||
#FIXME: Remove this variable
|
|
||||||
NOAUTOCALLBACK=no
|
|
||||||
|
|
||||||
DEBUG_PHONE_SNIFF=0
|
|
||||||
|
|
||||||
#CFLAGS+=-DUSB_NO_DEBUG=1
|
|
||||||
|
|
||||||
# Optimization level, put in comment for debugging
|
|
||||||
OPTIMIZATION = -O0
|
|
||||||
|
|
||||||
# Output file basename
|
# Output file basename
|
||||||
OUTPUT = project
|
APP ?= dfu
|
||||||
|
|
||||||
# Output directories
|
# Output directories
|
||||||
|
OUTPUT = $(BOARD)-$(APP)
|
||||||
BIN = bin
|
BIN = bin
|
||||||
OBJ = obj
|
OBJ = obj/$(BOARD)
|
||||||
|
|
||||||
#-------------------------------------------------------------------------------
|
#-------------------------------------------------------------------------------
|
||||||
# Tools
|
# Tools
|
||||||
#-------------------------------------------------------------------------------
|
#-------------------------------------------------------------------------------
|
||||||
|
|
||||||
AT91LIB_USB_COMMON_CORE_PATH = atmel_softpack_libraries/usb/common/core
|
AT91LIB = ./atmel_softpack_libraries
|
||||||
AT91LIB_USB_CORE_PATH = atmel_softpack_libraries/usb/device/core
|
|
||||||
|
AT91LIB_USB_COMMON_CORE_PATH = $(AT91LIB)/usb/common/core
|
||||||
|
AT91LIB_USB_CORE_PATH = $(AT91LIB)/usb/device/core
|
||||||
|
AT91LIB_USB_DFU_PATH = $(AT91LIB)/usb/device/dfu
|
||||||
|
|
||||||
# Tool suffix when cross-compiling
|
# Tool suffix when cross-compiling
|
||||||
CROSS_COMPILE = arm-none-eabi-
|
CROSS_COMPILE = arm-none-eabi-
|
||||||
|
|
||||||
LIBS = -Wl,--start-group -lgcc -lc -Wl,--end-group
|
LIBS = -Wl,--start-group -lgcc -Wl,--end-group -nostdlib
|
||||||
|
|
||||||
# Compilation tools
|
# Compilation tools
|
||||||
CC = $(CROSS_COMPILE)gcc
|
CC = $(CROSS_COMPILE)gcc
|
||||||
@@ -87,12 +72,73 @@ OBJCOPY = $(CROSS_COMPILE)objcopy
|
|||||||
GDB = $(CROSS_COMPILE)gdb
|
GDB = $(CROSS_COMPILE)gdb
|
||||||
NM = $(CROSS_COMPILE)nm
|
NM = $(CROSS_COMPILE)nm
|
||||||
|
|
||||||
# Flags
|
TOP=..
|
||||||
INCLUDES_USB = -Iatmel_softpack_libraries/usb/include
|
GIT_VERSION=$(shell $(TOP)/git-version-gen $(TOP)/.tarvers)
|
||||||
|
|
||||||
INCLUDES = -Iinclude_board -Iinclude_sam3s -Iinclude -Isrc_simtrace
|
#-------------------------------------------------------------------------------
|
||||||
INCLUDES += -Icmsis
|
# Files
|
||||||
INCLUDES += $(INCLUDES_USB)
|
#-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# Directories where source files can be found
|
||||||
|
|
||||||
|
USB_PATHS = $(AT91LIB_USB_CORE_PATH) $(AT91LIB_USB_DFU_PATH) $(AT91LIB_USB_COMMON_CORE_PATH)
|
||||||
|
|
||||||
|
VPATH += $(USB_PATHS)
|
||||||
|
VPATH += $(AT91LIB)/libchip_sam3s/source/ $(AT91LIB)/libchip_sam3s/cmsis
|
||||||
|
VPATH += libboard/common/source libboard/$(BOARD)/source
|
||||||
|
VPATH += libcommon/source
|
||||||
|
VPATH += libosmocore/source
|
||||||
|
VPATH += apps/$(APP)
|
||||||
|
|
||||||
|
# Objects built from C source files
|
||||||
|
C_OSMOCORE = $(notdir $(wildcard libosmocore/source/*.c))
|
||||||
|
C_LIBCHIP = $(notdir $(wildcard $(AT91LIB)/libchip_sam3s/source/*.c) $(wildcard $(AT91LIB)/libchip_sam3s/cmsis/*.c))
|
||||||
|
|
||||||
|
C_LIBUSB = USBDescriptors.c USBRequests.c USBD.c USBDCallbacks.c USBDDriver.c USBDDriverCallbacks.c
|
||||||
|
C_LIBUSB_RT = dfu.c dfu_desc.c dfu_runtime.c
|
||||||
|
C_LIBUSB_DFU = dfu.c dfu_desc.c dfu_driver.c
|
||||||
|
C_LIBCOMMON = string.c stdio.c fputs.c req_ctx.c ringbuffer.c
|
||||||
|
|
||||||
|
C_BOARD = $(notdir $(wildcard libboard/common/source/*.c))
|
||||||
|
C_BOARD += $(notdir $(wildcard libboard/$(BOARD)/source/*.c))
|
||||||
|
|
||||||
|
C_APPLEVEL = $(notdir $(wildcard apps/$(APP)/*.c))
|
||||||
|
|
||||||
|
C_FILES = $(C_OSMOCORE) $(C_LIBCHIP) $(C_LIBUSB) $(C_LIBCOMMON) $(C_BOARD) $(C_APPLEVEL)
|
||||||
|
|
||||||
|
-include apps/$(APP)/Makefile
|
||||||
|
|
||||||
|
C_OBJECTS = $(C_FILES:%.c=%.o)
|
||||||
|
|
||||||
|
# Trace level used for compilation
|
||||||
|
# (can be overriden by adding TRACE_LEVEL=#number to the command-line)
|
||||||
|
# TRACE_LEVEL_DEBUG 5
|
||||||
|
# TRACE_LEVEL_INFO 4
|
||||||
|
# TRACE_LEVEL_WARNING 3
|
||||||
|
# TRACE_LEVEL_ERROR 2
|
||||||
|
# TRACE_LEVEL_FATAL 1
|
||||||
|
# TRACE_LEVEL_NO_TRACE 0
|
||||||
|
TRACE_LEVEL ?= 4
|
||||||
|
|
||||||
|
DEBUG_PHONE_SNIFF?=0
|
||||||
|
|
||||||
|
#CFLAGS+=-DUSB_NO_DEBUG=1
|
||||||
|
|
||||||
|
# Optimization level, put in comment for debugging
|
||||||
|
OPTIMIZATION ?= -Os
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Flags
|
||||||
|
INCLUDES_USB = -I$(AT91LIB)/usb/include -I$(AT91LIB)
|
||||||
|
|
||||||
|
INCLUDES = $(INCLUDES_USB)
|
||||||
|
INCLUDES += -I$(AT91LIB)/libchip_sam3s -I$(AT91LIB)/libchip_sam3s/include
|
||||||
|
INCLUDES += -I$(AT91LIB)/libchip_sam3s/cmsis
|
||||||
|
INCLUDES += -Ilibboard/common/include -Ilibboard/$(BOARD)/include
|
||||||
|
INCLUDES += -Ilibcommon/include
|
||||||
|
INCLUDES += -Ilibosmocore/include
|
||||||
|
INCLUDES += -Isrc_simtrace -Iinclude
|
||||||
|
|
||||||
CFLAGS += -Wall -Wchar-subscripts -Wcomment -Wimplicit-int #-Wformat=2
|
CFLAGS += -Wall -Wchar-subscripts -Wcomment -Wimplicit-int #-Wformat=2
|
||||||
CFLAGS += -Werror-implicit-function-declaration -Wmain -Wparentheses
|
CFLAGS += -Werror-implicit-function-declaration -Wmain -Wparentheses
|
||||||
@@ -105,42 +151,26 @@ CFLAGS += -Wmissing-format-attribute -Wno-deprecated-declarations
|
|||||||
CFLAGS += #-Wpacked
|
CFLAGS += #-Wpacked
|
||||||
CFLAGS += -Wredundant-decls -Wnested-externs -Winline #-Wlong-long
|
CFLAGS += -Wredundant-decls -Wnested-externs -Winline #-Wlong-long
|
||||||
CFLAGS += -Wunreachable-code
|
CFLAGS += -Wunreachable-code
|
||||||
CFLAGS += -Wcast-align
|
#CFLAGS += -Wcast-align
|
||||||
CFLAGS += -std=c11
|
#CFLAGS += -std=c11
|
||||||
CFLAGS += -Wmissing-noreturn
|
CFLAGS += -Wmissing-noreturn
|
||||||
#CFLAGS += -Wconversion
|
#CFLAGS += -Wconversion
|
||||||
CFLAGS += -Wno-unused-but-set-variable -Wno-unused-variable
|
CFLAGS += -Wno-unused-but-set-variable -Wno-unused-variable
|
||||||
CFLAGS += -Wno-suggest-attribute=noreturn
|
CFLAGS += -Wno-suggest-attribute=noreturn
|
||||||
|
|
||||||
# To reduce application size use only integer printf function.
|
|
||||||
CFLAGS += -Dprintf=iprintf
|
|
||||||
|
|
||||||
# -mlong-calls -Wall
|
# -mlong-calls -Wall
|
||||||
#CFLAGS += -save-temps -fverbose-asm
|
#CFLAGS += -save-temps -fverbose-asm
|
||||||
#CFLAGS += -Wa,-a,-ad
|
#CFLAGS += -Wa,-a,-ad
|
||||||
|
CFLAGS += -D__ARM
|
||||||
CFLAGS += --param max-inline-insns-single=500 -mcpu=cortex-m3 -mthumb # -mfix-cortex-m3-ldrd
|
CFLAGS += --param max-inline-insns-single=500 -mcpu=cortex-m3 -mthumb # -mfix-cortex-m3-ldrd
|
||||||
CFLAGS += -ffunction-sections -g $(OPTIMIZATION) $(INCLUDES) -D$(CHIP) -DTRACE_LEVEL=$(TRACE_LEVEL) -DDEBUG_PHONE_SNIFF=$(DEBUG_PHONE_SNIFF)
|
CFLAGS += -ffunction-sections -g $(OPTIMIZATION) $(INCLUDES) -D$(CHIP) -DTRACE_LEVEL=$(TRACE_LEVEL) -DDEBUG_PHONE_SNIFF=$(DEBUG_PHONE_SNIFF)
|
||||||
|
CFLAGS += -DGIT_VERSION=\"$(GIT_VERSION)\"
|
||||||
|
CFLAGS += -DBOARD=\"$(BOARD)\" -DBOARD_$(BOARD)
|
||||||
|
CFLAGS += -DAPPLICATION=\"$(APP)\" -DAPPLICATION_$(APP)
|
||||||
ASFLAGS = -mcpu=cortex-m3 -mthumb -Wall -g $(OPTIMIZATION) $(INCLUDES) -D$(CHIP) -D__ASSEMBLY__
|
ASFLAGS = -mcpu=cortex-m3 -mthumb -Wall -g $(OPTIMIZATION) $(INCLUDES) -D$(CHIP) -D__ASSEMBLY__
|
||||||
LDFLAGS = -mcpu=cortex-m3 -mthumb -Wl,--cref -Wl,--check-sections -Wl,--gc-sections -Wl,--entry=ResetException -Wl,--unresolved-symbols=report-all -Wl,--warn-common -Wl,--warn-section-align -Wl,--warn-unresolved-symbols $(LIB)
|
LDFLAGS = -mcpu=cortex-m3 -mthumb -Wl,--cref -Wl,--check-sections -Wl,--gc-sections -Wl,--entry=ResetException -Wl,--unresolved-symbols=report-all -Wl,--warn-common -Wl,--warn-section-align -Wl,--warn-unresolved-symbols $(LIB)
|
||||||
#LD_OPTIONAL=-Wl,--print-gc-sections -Wl,--stats
|
#LD_OPTIONAL=-Wl,--print-gc-sections -Wl,--stats
|
||||||
|
|
||||||
#-------------------------------------------------------------------------------
|
|
||||||
# Files
|
|
||||||
#-------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
# Directories where source files can be found
|
|
||||||
|
|
||||||
USB_PATHS = $(AT91LIB_USB_CORE_PATH) $(AT91LIB_USB_COMMON_CORE_PATH)
|
|
||||||
VPATH += src_board src_sam3s cmsis $(USB_PATHS) src_simtrace
|
|
||||||
|
|
||||||
# Objects built from C source files
|
|
||||||
C_CMSIS = core_cm3.o
|
|
||||||
C_LOWLEVEL = board_cstartup_gnu.o board_lowlevel.o syscalls.o exceptions.o
|
|
||||||
C_LIBLEVEL = spi.o pio.o pmc.o usart.o pio_it.o pio_capture.o uart_console.o iso7816_4.o wdt.o led.o tc.o
|
|
||||||
C_CCID = cciddriver.o USBD.o USBDDriver.o USBD_HAL.o USBRequests.o USBDCallbacks.o USBDescriptors.o USBDDriverCallbacks.o
|
|
||||||
C_SIMTRACE = simtrace_iso7816.o usb.o ccid.o sniffer.o phone.o mitm.o ringbuffer.o host_communication.o #iso7816_uart.o
|
|
||||||
C_APPLEVEL = main.o
|
|
||||||
C_OBJECTS = $(C_CMSIS) $(C_LOWLEVEL) $(C_LIBLEVEL) $(C_APPLEVEL) $(C_CCID) $(C_SIMTRACE)
|
|
||||||
|
|
||||||
# Append OBJ and BIN directories to output filename
|
# Append OBJ and BIN directories to output filename
|
||||||
OUTPUT := $(BIN)/$(OUTPUT)
|
OUTPUT := $(BIN)/$(OUTPUT)
|
||||||
@@ -159,18 +189,18 @@ C_OBJECTS_$(1) = $(addprefix $(OBJ)/$(1)_, $(C_OBJECTS))
|
|||||||
ASM_OBJECTS_$(1) = $(addprefix $(OBJ)/$(1)_, $(ASM_OBJECTS))
|
ASM_OBJECTS_$(1) = $(addprefix $(OBJ)/$(1)_, $(ASM_OBJECTS))
|
||||||
|
|
||||||
$(1): $$(ASM_OBJECTS_$(1)) $$(C_OBJECTS_$(1))
|
$(1): $$(ASM_OBJECTS_$(1)) $$(C_OBJECTS_$(1))
|
||||||
@$(CC) $(LDFLAGS) $(LD_OPTIONAL) -T"$$@.ld" -Wl,-Map,$(OUTPUT)-$$@.map -o $(OUTPUT)-$$@.elf $$^ $(LIBS)
|
@$(CC) $(LDFLAGS) $(LD_OPTIONAL) -T"libboard/common/resources/$(CHIP)/$$@.ld" -Wl,-Map,$(OUTPUT)-$$@.map -o $(OUTPUT)-$$@.elf $$^ $(LIBS)
|
||||||
@$(NM) $(OUTPUT)-$$@.elf >$(OUTPUT)-$$@.elf.txt
|
@$(NM) $(OUTPUT)-$$@.elf >$(OUTPUT)-$$@.elf.txt
|
||||||
@$(OBJCOPY) -O binary $(OUTPUT)-$$@.elf $(OUTPUT)-$$@.bin
|
@$(OBJCOPY) -O binary $(OUTPUT)-$$@.elf $(OUTPUT)-$$@.bin
|
||||||
@$(SIZE) $$^ $(OUTPUT)-$$@.elf
|
@$(SIZE) $$^ $(OUTPUT)-$$@.elf
|
||||||
|
|
||||||
$$(C_OBJECTS_$(1)): $(OBJ)/$(1)_%.o: %.c Makefile $(OBJ) $(BIN)
|
$$(C_OBJECTS_$(1)): $(OBJ)/$(1)_%.o: %.c Makefile $(OBJ) $(BIN)
|
||||||
@echo [COMPILING $$<]
|
@echo [COMPILING $$<]
|
||||||
@$(CC) $(CFLAGS) -D$(1) -Wa,-ahlms=$(BIN)/$$*.lst -c -o $$@ $$<
|
@$(CC) $(CFLAGS) -DENVIRONMENT_$(1) -DENVIRONMENT=\"$(1)\" -Wa,-ahlms=$(BIN)/$$*.lst -c -o $$@ $$<
|
||||||
|
|
||||||
$$(ASM_OBJECTS_$(1)): $(OBJ)/$(1)_%.o: %.S Makefile $(OBJ) $(BIN)
|
$$(ASM_OBJECTS_$(1)): $(OBJ)/$(1)_%.o: %.S Makefile $(OBJ) $(BIN)
|
||||||
@echo [ASSEMBLING $$@]
|
@echo [ASSEMBLING $$@]
|
||||||
@$(CC) $(ASFLAGS) -D$(1) -c -o $$@ $$<
|
@$(CC) $(ASFLAGS) -DENVIRONMENT_$(1) -DENVIRONMENT=\"$(1)\" -c -o $$@ $$<
|
||||||
|
|
||||||
debug_$(1): $(1)
|
debug_$(1): $(1)
|
||||||
$(GDB) -x "$(BOARD_LIB)/resources/gcc/$(BOARD)_$(1).gdb" -ex "reset" -readnow -se $(OUTPUT)-$(1).elf
|
$(GDB) -x "$(BOARD_LIB)/resources/gcc/$(BOARD)_$(1).gdb" -ex "reset" -readnow -se $(OUTPUT)-$(1).elf
|
||||||
@@ -188,6 +218,3 @@ log:
|
|||||||
|
|
||||||
clean:
|
clean:
|
||||||
-rm -fR $(OBJ)/*.o $(BIN)/*.bin $(BIN)/*.elf $(BIN)/*.elf.txt $(BIN)/*.map $(BIN)/*.lst
|
-rm -fR $(OBJ)/*.o $(BIN)/*.bin $(BIN)/*.elf $(BIN)/*.elf.txt $(BIN)/*.map $(BIN)/*.lst
|
||||||
|
|
||||||
rmbak:
|
|
||||||
-rm *~ $(BIN)/*~
|
|
||||||
|
|||||||
33
firmware/README.txt
Normal file
33
firmware/README.txt
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
|
||||||
|
== BOARDS
|
||||||
|
|
||||||
|
A board defines a given circuit board, i.e. SIMtrace, OWHW, QMOD
|
||||||
|
|
||||||
|
It defines the given hardware model for which the program is to be
|
||||||
|
compiled.
|
||||||
|
|
||||||
|
Current boards supported are:
|
||||||
|
* simtrace: The good old Osmocom SIMtrace PCB with SAM3 instead of
|
||||||
|
SAM7, open hardware.
|
||||||
|
* qmod: A sysmocom-proprietary quad mPCIe carrier board, publicly available
|
||||||
|
* owhw: An undisclosed sysmocom-internal board, not publicly available
|
||||||
|
|
||||||
|
== APPLICATIONS
|
||||||
|
|
||||||
|
An application is a specific piece of software with given
|
||||||
|
functionality.
|
||||||
|
|
||||||
|
== ENVIRONMENTS
|
||||||
|
|
||||||
|
An environment is a runtime environment, typically defined by a linker
|
||||||
|
script. The current runtime environments include
|
||||||
|
* flash: Run natively from start of flash memory
|
||||||
|
* dfu: Run after a DFU bootloader from an offset after the first 16k
|
||||||
|
of flash (the first 16k are reserved for the bootloader)
|
||||||
|
* ram: Run from within the RAM of the chip, downloaded via JTAG/SWD
|
||||||
|
|
||||||
|
|
||||||
|
== Building
|
||||||
|
|
||||||
|
A given software build is made for a specific combination of an APP
|
||||||
|
running in a certain ENVIRONMENT on a given BOARD.
|
||||||
3
firmware/apps/cardem/Makefile
Normal file
3
firmware/apps/cardem/Makefile
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
C_FILES += $(C_LIBUSB_RT)
|
||||||
|
|
||||||
|
C_FILES += card_emu.c ccid.c host_communication.c iso7816_4.c iso7816_fidi.c mitm.c mode_cardemu.c simtrace_iso7816.c sniffer.c tc_etu.c usb.c
|
||||||
207
firmware/apps/cardem/main.c
Normal file
207
firmware/apps/cardem/main.c
Normal file
@@ -0,0 +1,207 @@
|
|||||||
|
// FIXME: Copyright license here
|
||||||
|
/*------------------------------------------------------------------------------
|
||||||
|
* Headers
|
||||||
|
*------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "board.h"
|
||||||
|
#include "simtrace.h"
|
||||||
|
#include "utils.h"
|
||||||
|
#include "req_ctx.h"
|
||||||
|
#include "osmocom/core/timer.h"
|
||||||
|
|
||||||
|
unsigned int g_unique_id[4];
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------------
|
||||||
|
* Internal variables
|
||||||
|
*------------------------------------------------------------------------------*/
|
||||||
|
typedef struct {
|
||||||
|
/* static initialization, called whether or not the usb config is active */
|
||||||
|
void (*configure) (void);
|
||||||
|
/* initialization function after the config was selected */
|
||||||
|
void (*init) (void);
|
||||||
|
/* de-initialization before selecting new config */
|
||||||
|
void (*exit) (void);
|
||||||
|
/* main loop content for given configuration */
|
||||||
|
void (*run) (void);
|
||||||
|
/* Interrupt handler for USART1 */
|
||||||
|
void (*usart0_irq) (void);
|
||||||
|
/* Interrupt handler for USART1 */
|
||||||
|
void (*usart1_irq) (void);
|
||||||
|
} conf_func;
|
||||||
|
|
||||||
|
static const conf_func config_func_ptrs[] = {
|
||||||
|
/* array slot 0 is empty, usb configs start at 1 */
|
||||||
|
#ifdef HAVE_SNIFFER
|
||||||
|
[CFG_NUM_SNIFF] = {
|
||||||
|
.configure = Sniffer_configure,
|
||||||
|
.init = Sniffer_init,
|
||||||
|
.exit = Sniffer_exit,
|
||||||
|
.run = Sniffer_run,
|
||||||
|
},
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_CCID
|
||||||
|
[CFG_NUM_CCID] = {
|
||||||
|
.configure = CCID_configure,
|
||||||
|
.init = CCID_init,
|
||||||
|
.exit = CCID_exit,
|
||||||
|
.run = CCID_run,
|
||||||
|
},
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_CARDEM
|
||||||
|
[CFG_NUM_PHONE] = {
|
||||||
|
.configure = mode_cardemu_configure,
|
||||||
|
.init = mode_cardemu_init,
|
||||||
|
.exit = mode_cardemu_exit,
|
||||||
|
.run = mode_cardemu_run,
|
||||||
|
.usart0_irq = mode_cardemu_usart0_irq,
|
||||||
|
.usart1_irq = mode_cardemu_usart1_irq,
|
||||||
|
},
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_MITM
|
||||||
|
[CFG_NUM_MITM] = {
|
||||||
|
.configure = MITM_configure,
|
||||||
|
.init = MITM_init,
|
||||||
|
.exit = MITM_exit,
|
||||||
|
.run = MITM_run,
|
||||||
|
},
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------------
|
||||||
|
* Internal variables
|
||||||
|
*------------------------------------------------------------------------------*/
|
||||||
|
#if defined(HAVE_SNIFFER)
|
||||||
|
static volatile enum confNum simtrace_config = CFG_NUM_SNIFF;
|
||||||
|
#elif defined(HAVE_CARDEM)
|
||||||
|
static volatile enum confNum simtrace_config = CFG_NUM_PHONE;
|
||||||
|
#elif defined(HAVE_CCID)
|
||||||
|
static volatile enum confNum simtrace_config = CFG_NUM_CCID;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------
|
||||||
|
* Callbacks
|
||||||
|
*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
void USBDDriverCallbacks_ConfigurationChanged(uint8_t cfgnum)
|
||||||
|
{
|
||||||
|
TRACE_INFO_WP("cfgChanged%d ", cfgnum);
|
||||||
|
simtrace_config = cfgnum;
|
||||||
|
}
|
||||||
|
|
||||||
|
void USART1_IrqHandler(void)
|
||||||
|
{
|
||||||
|
config_func_ptrs[simtrace_config].usart1_irq();
|
||||||
|
}
|
||||||
|
|
||||||
|
void USART0_IrqHandler(void)
|
||||||
|
{
|
||||||
|
config_func_ptrs[simtrace_config].usart0_irq();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* returns '1' in case we should break any endless loop */
|
||||||
|
static void check_exec_dbg_cmd(void)
|
||||||
|
{
|
||||||
|
int ch;
|
||||||
|
|
||||||
|
if (!UART_IsRxReady())
|
||||||
|
return;
|
||||||
|
|
||||||
|
ch = UART_GetChar();
|
||||||
|
|
||||||
|
board_exec_dbg_cmd(ch);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------------
|
||||||
|
* Main
|
||||||
|
*------------------------------------------------------------------------------*/
|
||||||
|
#define MAX_USB_ITER BOARD_MCK/72 // This should be around a second
|
||||||
|
extern int main(void)
|
||||||
|
{
|
||||||
|
uint8_t isUsbConnected = 0;
|
||||||
|
enum confNum last_simtrace_config = simtrace_config;
|
||||||
|
unsigned int i = 0;
|
||||||
|
|
||||||
|
LED_Configure(LED_NUM_RED);
|
||||||
|
LED_Configure(LED_NUM_GREEN);
|
||||||
|
LED_Set(LED_NUM_RED);
|
||||||
|
|
||||||
|
/* Disable watchdog */
|
||||||
|
WDT_Disable(WDT);
|
||||||
|
|
||||||
|
req_ctx_init();
|
||||||
|
|
||||||
|
PIO_InitializeInterrupts(0);
|
||||||
|
|
||||||
|
EEFC_ReadUniqueID(g_unique_id);
|
||||||
|
|
||||||
|
printf("\r\n\r\n"
|
||||||
|
"=============================================================================\r\n"
|
||||||
|
"SIMtrace2 firmware " GIT_VERSION " (C) 2010-2016 by Harald Welte\r\n"
|
||||||
|
"=============================================================================\r\n");
|
||||||
|
|
||||||
|
TRACE_INFO("Serial Nr. %08x-%08x-%08x-%08x\r\n",
|
||||||
|
g_unique_id[0], g_unique_id[1],
|
||||||
|
g_unique_id[2], g_unique_id[3]);
|
||||||
|
|
||||||
|
board_main_top();
|
||||||
|
|
||||||
|
TRACE_INFO("USB init...\r\n");
|
||||||
|
SIMtrace_USB_Initialize();
|
||||||
|
|
||||||
|
while (USBD_GetState() < USBD_STATE_CONFIGURED) {
|
||||||
|
check_exec_dbg_cmd();
|
||||||
|
#if 0
|
||||||
|
if (i >= MAX_USB_ITER * 3) {
|
||||||
|
TRACE_ERROR("Resetting board (USB could "
|
||||||
|
"not be configured)\r\n");
|
||||||
|
NVIC_SystemReset();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
TRACE_INFO("calling configure of all configurations...\r\n");
|
||||||
|
for (i = 1; i < sizeof(config_func_ptrs) / sizeof(config_func_ptrs[0]);
|
||||||
|
++i) {
|
||||||
|
if (config_func_ptrs[i].configure)
|
||||||
|
config_func_ptrs[i].configure();
|
||||||
|
}
|
||||||
|
|
||||||
|
TRACE_INFO("calling init of config %u...\r\n", simtrace_config);
|
||||||
|
config_func_ptrs[simtrace_config].init();
|
||||||
|
last_simtrace_config = simtrace_config;
|
||||||
|
|
||||||
|
TRACE_INFO("entering main loop...\r\n");
|
||||||
|
while (1) {
|
||||||
|
#if TRACE_LEVEL >= TRACE_LEVEL_DEBUG
|
||||||
|
const char rotor[] = { '-', '\\', '|', '/' };
|
||||||
|
putchar('\b');
|
||||||
|
putchar(rotor[i++ % ARRAY_SIZE(rotor)]);
|
||||||
|
#endif
|
||||||
|
check_exec_dbg_cmd();
|
||||||
|
osmo_timers_prepare();
|
||||||
|
osmo_timers_update();
|
||||||
|
|
||||||
|
if (USBD_GetState() < USBD_STATE_CONFIGURED) {
|
||||||
|
|
||||||
|
if (isUsbConnected) {
|
||||||
|
isUsbConnected = 0;
|
||||||
|
}
|
||||||
|
} else if (isUsbConnected == 0) {
|
||||||
|
TRACE_INFO("USB is now configured\r\n");
|
||||||
|
LED_Set(LED_NUM_GREEN);
|
||||||
|
LED_Clear(LED_NUM_RED);
|
||||||
|
|
||||||
|
isUsbConnected = 1;
|
||||||
|
}
|
||||||
|
if (last_simtrace_config != simtrace_config) {
|
||||||
|
TRACE_INFO("USB config chg %u -> %u\r\n",
|
||||||
|
last_simtrace_config, simtrace_config);
|
||||||
|
config_func_ptrs[last_simtrace_config].exit();
|
||||||
|
config_func_ptrs[simtrace_config].init();
|
||||||
|
last_simtrace_config = simtrace_config;
|
||||||
|
} else {
|
||||||
|
config_func_ptrs[simtrace_config].run();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
0
firmware/apps/ccid/main.c
Normal file
0
firmware/apps/ccid/main.c
Normal file
12
firmware/apps/dfu/Makefile
Normal file
12
firmware/apps/dfu/Makefile
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
|
||||||
|
C_FILES += $(C_LIBUSB_DFU)
|
||||||
|
|
||||||
|
# Trace level used for compilation
|
||||||
|
# (can be overriden by adding TRACE_LEVEL=#number to the command-line)
|
||||||
|
# TRACE_LEVEL_DEBUG 5
|
||||||
|
# TRACE_LEVEL_INFO 4
|
||||||
|
# TRACE_LEVEL_WARNING 3
|
||||||
|
# TRACE_LEVEL_ERROR 2
|
||||||
|
# TRACE_LEVEL_FATAL 1
|
||||||
|
# TRACE_LEVEL_NO_TRACE 0
|
||||||
|
TRACE_LEVEL ?= 3
|
||||||
195
firmware/apps/dfu/main.c
Normal file
195
firmware/apps/dfu/main.c
Normal file
@@ -0,0 +1,195 @@
|
|||||||
|
#include "board.h"
|
||||||
|
#include "utils.h"
|
||||||
|
#include "usb/device/dfu/dfu.h"
|
||||||
|
#include "usb/common/dfu/usb_dfu.h"
|
||||||
|
#include "manifest.h"
|
||||||
|
|
||||||
|
#define ALTIF_RAM 0
|
||||||
|
#define ALTIF_FLASH 1
|
||||||
|
|
||||||
|
unsigned int g_unique_id[4];
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------
|
||||||
|
* Callbacks
|
||||||
|
*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#define RAM_ADDR(offset) (IRAM_ADDR + BOARD_DFU_RAM_SIZE + offset)
|
||||||
|
#define FLASH_ADDR(offset) (IFLASH_ADDR + BOARD_DFU_BOOT_SIZE + offset)
|
||||||
|
|
||||||
|
#define IFLASH_END ((uint8_t *)IFLASH_ADDR + IFLASH_SIZE)
|
||||||
|
#define IRAM_END ((uint8_t *)IRAM_ADDR + IRAM_SIZE)
|
||||||
|
|
||||||
|
/* incoming call-back: Host has transfered 'len' bytes (stored at
|
||||||
|
* 'data'), which we shall write to 'offset' into the partition
|
||||||
|
* associated with 'altif'. Guaranted to be les than
|
||||||
|
* BOARD_DFU_PAGE_SIZE */
|
||||||
|
int USBDFU_handle_dnload(uint8_t altif, unsigned int offset,
|
||||||
|
uint8_t *data, unsigned int len)
|
||||||
|
{
|
||||||
|
uint32_t addr;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
printf("dnload(altif=%u, offset=%u, len=%u)\n\r", altif, offset, len);
|
||||||
|
|
||||||
|
switch (altif) {
|
||||||
|
case ALTIF_RAM:
|
||||||
|
addr = RAM_ADDR(offset);
|
||||||
|
if (addr > IRAM_ADDR + IRAM_SIZE) {
|
||||||
|
g_dfu->state = DFU_STATE_dfuERROR;
|
||||||
|
g_dfu->status = DFU_STATUS_errADDRESS;
|
||||||
|
return DFU_RET_STALL;
|
||||||
|
}
|
||||||
|
memcpy((void *)addr, data, len);
|
||||||
|
return DFU_RET_ZLP;
|
||||||
|
case ALTIF_FLASH:
|
||||||
|
addr = FLASH_ADDR(offset);
|
||||||
|
if (addr > IFLASH_ADDR + IFLASH_SIZE) {
|
||||||
|
g_dfu->state = DFU_STATE_dfuERROR;
|
||||||
|
g_dfu->status = DFU_STATUS_errADDRESS;
|
||||||
|
return DFU_RET_STALL;
|
||||||
|
}
|
||||||
|
rc = FLASHD_Write(addr, data, len);
|
||||||
|
if (rc != 0) {
|
||||||
|
/* FIXME: set error codes */
|
||||||
|
return DFU_RET_STALL;
|
||||||
|
}
|
||||||
|
return DFU_RET_ZLP;
|
||||||
|
default:
|
||||||
|
/* FIXME: set error codes */
|
||||||
|
TRACE_ERROR("DFU download for unknown AltIf %d\n\r", altif);
|
||||||
|
return DFU_RET_STALL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* incoming call-back: Host has requested to read back 'req_len' bytes
|
||||||
|
* starting from 'offset' of the firmware * associated with partition
|
||||||
|
* 'altif' */
|
||||||
|
int USBDFU_handle_upload(uint8_t altif, unsigned int offset,
|
||||||
|
uint8_t *data, unsigned int req_len)
|
||||||
|
{
|
||||||
|
uint32_t addr;
|
||||||
|
|
||||||
|
printf("upload(altif=%u, offset=%u, len=%u)", altif, offset, req_len);
|
||||||
|
|
||||||
|
switch (altif) {
|
||||||
|
case ALTIF_RAM:
|
||||||
|
addr = RAM_ADDR(offset);
|
||||||
|
if (addr > IRAM_ADDR + IRAM_SIZE) {
|
||||||
|
g_dfu->state = DFU_STATE_dfuERROR;
|
||||||
|
g_dfu->status = DFU_STATUS_errADDRESS;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if ((uint8_t *)addr + req_len > IRAM_END)
|
||||||
|
req_len = IRAM_END - (uint8_t *)addr;
|
||||||
|
memcpy(data, (void *)addr, req_len);
|
||||||
|
break;
|
||||||
|
case ALTIF_FLASH:
|
||||||
|
addr = FLASH_ADDR(offset);
|
||||||
|
if (addr > IFLASH_ADDR + IFLASH_SIZE) {
|
||||||
|
g_dfu->state = DFU_STATE_dfuERROR;
|
||||||
|
g_dfu->status = DFU_STATUS_errADDRESS;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if ((uint8_t *)addr + req_len > IFLASH_END)
|
||||||
|
req_len = IFLASH_END - (uint8_t *)addr;
|
||||||
|
memcpy(data, (void *)addr, req_len);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
TRACE_ERROR("DFU upload for unknown AltIf %d\n\r", altif);
|
||||||
|
/* FIXME: set error codes */
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
printf("=%u\r\n", req_len);
|
||||||
|
return req_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* returns '1' in case we should break any endless loop */
|
||||||
|
static void check_exec_dbg_cmd(void)
|
||||||
|
{
|
||||||
|
int ch;
|
||||||
|
|
||||||
|
if (!UART_IsRxReady())
|
||||||
|
return;
|
||||||
|
|
||||||
|
ch = UART_GetChar();
|
||||||
|
|
||||||
|
//board_exec_dbg_cmd(ch);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------------
|
||||||
|
* Main
|
||||||
|
*------------------------------------------------------------------------------*/
|
||||||
|
#define MAX_USB_ITER BOARD_MCK/72 // This should be around a second
|
||||||
|
extern int main(void)
|
||||||
|
{
|
||||||
|
uint8_t isUsbConnected = 0;
|
||||||
|
unsigned int i = 0;
|
||||||
|
|
||||||
|
LED_Configure(LED_NUM_RED);
|
||||||
|
LED_Configure(LED_NUM_GREEN);
|
||||||
|
LED_Set(LED_NUM_RED);
|
||||||
|
|
||||||
|
/* Disable watchdog */
|
||||||
|
WDT_Disable(WDT);
|
||||||
|
|
||||||
|
//req_ctx_init();
|
||||||
|
|
||||||
|
PIO_InitializeInterrupts(0);
|
||||||
|
|
||||||
|
EEFC_ReadUniqueID(g_unique_id);
|
||||||
|
|
||||||
|
printf("\r\n\r\n"
|
||||||
|
"=============================================================================\r\n"
|
||||||
|
"DFU bootloader %s for board %s (C) 2010-2017 by Harald Welte\r\n"
|
||||||
|
"=============================================================================\r\n",
|
||||||
|
manifest_revision, manifest_board);
|
||||||
|
|
||||||
|
TRACE_INFO("Chip ID: 0x%08x (Ext 0x%08x)\r\n", CHIPID->CHIPID_CIDR, CHIPID->CHIPID_EXID);
|
||||||
|
TRACE_INFO("Serial Nr. %08x-%08x-%08x-%08x\r\n",
|
||||||
|
g_unique_id[0], g_unique_id[1],
|
||||||
|
g_unique_id[2], g_unique_id[3]);
|
||||||
|
|
||||||
|
//board_main_top();
|
||||||
|
|
||||||
|
TRACE_INFO("USB init...\r\n");
|
||||||
|
USBDFU_Initialize(&dfu_descriptors);
|
||||||
|
|
||||||
|
while (USBD_GetState() < USBD_STATE_CONFIGURED) {
|
||||||
|
check_exec_dbg_cmd();
|
||||||
|
#if 1
|
||||||
|
if (i >= MAX_USB_ITER * 3) {
|
||||||
|
TRACE_ERROR("Resetting board (USB could "
|
||||||
|
"not be configured)\r\n");
|
||||||
|
NVIC_SystemReset();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
FLASHD_Initialize(BOARD_MCK, 1);
|
||||||
|
TRACE_INFO("entering main loop...\r\n");
|
||||||
|
while (1) {
|
||||||
|
#if TRACE_LEVEL >= TRACE_LEVEL_DEBUG
|
||||||
|
const char rotor[] = { '-', '\\', '|', '/' };
|
||||||
|
putchar('\b');
|
||||||
|
putchar(rotor[i++ % ARRAY_SIZE(rotor)]);
|
||||||
|
#endif
|
||||||
|
check_exec_dbg_cmd();
|
||||||
|
//osmo_timers_prepare();
|
||||||
|
//osmo_timers_update();
|
||||||
|
|
||||||
|
if (USBD_GetState() < USBD_STATE_CONFIGURED) {
|
||||||
|
|
||||||
|
if (isUsbConnected) {
|
||||||
|
isUsbConnected = 0;
|
||||||
|
}
|
||||||
|
} else if (isUsbConnected == 0) {
|
||||||
|
TRACE_INFO("USB is now configured\r\n");
|
||||||
|
LED_Set(LED_NUM_GREEN);
|
||||||
|
LED_Clear(LED_NUM_RED);
|
||||||
|
|
||||||
|
isUsbConnected = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
0
firmware/apps/trace/main.c
Normal file
0
firmware/apps/trace/main.c
Normal file
3
firmware/apps/triple_play/Makefile
Normal file
3
firmware/apps/triple_play/Makefile
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
C_FILES += $(C_LIBUSB_RT)
|
||||||
|
|
||||||
|
C_FILES += card_emu.c ccid.c host_communication.c iso7816_4.c iso7816_fidi.c mitm.c mode_cardemu.c simtrace_iso7816.c sniffer.c tc_etu.c usb.c
|
||||||
207
firmware/apps/triple_play/main.c
Normal file
207
firmware/apps/triple_play/main.c
Normal file
@@ -0,0 +1,207 @@
|
|||||||
|
// FIXME: Copyright license here
|
||||||
|
/*------------------------------------------------------------------------------
|
||||||
|
* Headers
|
||||||
|
*------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "board.h"
|
||||||
|
#include "simtrace.h"
|
||||||
|
#include "utils.h"
|
||||||
|
#include "req_ctx.h"
|
||||||
|
#include "osmocom/core/timer.h"
|
||||||
|
|
||||||
|
unsigned int g_unique_id[4];
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------------
|
||||||
|
* Internal variables
|
||||||
|
*------------------------------------------------------------------------------*/
|
||||||
|
typedef struct {
|
||||||
|
/* static initialization, called whether or not the usb config is active */
|
||||||
|
void (*configure) (void);
|
||||||
|
/* initialization function after the config was selected */
|
||||||
|
void (*init) (void);
|
||||||
|
/* de-initialization before selecting new config */
|
||||||
|
void (*exit) (void);
|
||||||
|
/* main loop content for given configuration */
|
||||||
|
void (*run) (void);
|
||||||
|
/* Interrupt handler for USART1 */
|
||||||
|
void (*usart0_irq) (void);
|
||||||
|
/* Interrupt handler for USART1 */
|
||||||
|
void (*usart1_irq) (void);
|
||||||
|
} conf_func;
|
||||||
|
|
||||||
|
static const conf_func config_func_ptrs[] = {
|
||||||
|
/* array slot 0 is empty, usb configs start at 1 */
|
||||||
|
#ifdef HAVE_SNIFFER
|
||||||
|
[CFG_NUM_SNIFF] = {
|
||||||
|
.configure = Sniffer_configure,
|
||||||
|
.init = Sniffer_init,
|
||||||
|
.exit = Sniffer_exit,
|
||||||
|
.run = Sniffer_run,
|
||||||
|
},
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_CCID
|
||||||
|
[CFG_NUM_CCID] = {
|
||||||
|
.configure = CCID_configure,
|
||||||
|
.init = CCID_init,
|
||||||
|
.exit = CCID_exit,
|
||||||
|
.run = CCID_run,
|
||||||
|
},
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_CARDEM
|
||||||
|
[CFG_NUM_PHONE] = {
|
||||||
|
.configure = mode_cardemu_configure,
|
||||||
|
.init = mode_cardemu_init,
|
||||||
|
.exit = mode_cardemu_exit,
|
||||||
|
.run = mode_cardemu_run,
|
||||||
|
.usart0_irq = mode_cardemu_usart0_irq,
|
||||||
|
.usart1_irq = mode_cardemu_usart1_irq,
|
||||||
|
},
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_MITM
|
||||||
|
[CFG_NUM_MITM] = {
|
||||||
|
.configure = MITM_configure,
|
||||||
|
.init = MITM_init,
|
||||||
|
.exit = MITM_exit,
|
||||||
|
.run = MITM_run,
|
||||||
|
},
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------------
|
||||||
|
* Internal variables
|
||||||
|
*------------------------------------------------------------------------------*/
|
||||||
|
#if defined(HAVE_SNIFFER)
|
||||||
|
static volatile enum confNum simtrace_config = CFG_NUM_SNIFF;
|
||||||
|
#elif defined(HAVE_CARDEM)
|
||||||
|
static volatile enum confNum simtrace_config = CFG_NUM_PHONE;
|
||||||
|
#elif defined(HAVE_CCID)
|
||||||
|
static volatile enum confNum simtrace_config = CFG_NUM_CCID;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------
|
||||||
|
* Callbacks
|
||||||
|
*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
void USBDDriverCallbacks_ConfigurationChanged(uint8_t cfgnum)
|
||||||
|
{
|
||||||
|
TRACE_INFO_WP("cfgChanged%d ", cfgnum);
|
||||||
|
simtrace_config = cfgnum;
|
||||||
|
}
|
||||||
|
|
||||||
|
void USART1_IrqHandler(void)
|
||||||
|
{
|
||||||
|
config_func_ptrs[simtrace_config].usart1_irq();
|
||||||
|
}
|
||||||
|
|
||||||
|
void USART0_IrqHandler(void)
|
||||||
|
{
|
||||||
|
config_func_ptrs[simtrace_config].usart0_irq();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* returns '1' in case we should break any endless loop */
|
||||||
|
static void check_exec_dbg_cmd(void)
|
||||||
|
{
|
||||||
|
int ch;
|
||||||
|
|
||||||
|
if (!UART_IsRxReady())
|
||||||
|
return;
|
||||||
|
|
||||||
|
ch = UART_GetChar();
|
||||||
|
|
||||||
|
board_exec_dbg_cmd(ch);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------------
|
||||||
|
* Main
|
||||||
|
*------------------------------------------------------------------------------*/
|
||||||
|
#define MAX_USB_ITER BOARD_MCK/72 // This should be around a second
|
||||||
|
extern int main(void)
|
||||||
|
{
|
||||||
|
uint8_t isUsbConnected = 0;
|
||||||
|
enum confNum last_simtrace_config = simtrace_config;
|
||||||
|
unsigned int i = 0;
|
||||||
|
|
||||||
|
LED_Configure(LED_NUM_RED);
|
||||||
|
LED_Configure(LED_NUM_GREEN);
|
||||||
|
LED_Set(LED_NUM_RED);
|
||||||
|
|
||||||
|
/* Disable watchdog */
|
||||||
|
WDT_Disable(WDT);
|
||||||
|
|
||||||
|
req_ctx_init();
|
||||||
|
|
||||||
|
PIO_InitializeInterrupts(0);
|
||||||
|
|
||||||
|
EEFC_ReadUniqueID(g_unique_id);
|
||||||
|
|
||||||
|
printf("\r\n\r\n"
|
||||||
|
"=============================================================================\r\n"
|
||||||
|
"SIMtrace2 firmware " GIT_REVISION " (C) 2010-2017 by Harald Welte\r\n"
|
||||||
|
"=============================================================================\r\n");
|
||||||
|
|
||||||
|
TRACE_INFO("Serial Nr. %08x-%08x-%08x-%08x\r\n",
|
||||||
|
g_unique_id[0], g_unique_id[1],
|
||||||
|
g_unique_id[2], g_unique_id[3]);
|
||||||
|
|
||||||
|
board_main_top();
|
||||||
|
|
||||||
|
TRACE_INFO("USB init...\r\n");
|
||||||
|
SIMtrace_USB_Initialize();
|
||||||
|
|
||||||
|
while (USBD_GetState() < USBD_STATE_CONFIGURED) {
|
||||||
|
check_exec_dbg_cmd();
|
||||||
|
#if 0
|
||||||
|
if (i >= MAX_USB_ITER * 3) {
|
||||||
|
TRACE_ERROR("Resetting board (USB could "
|
||||||
|
"not be configured)\r\n");
|
||||||
|
NVIC_SystemReset();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
TRACE_INFO("calling configure of all configurations...\r\n");
|
||||||
|
for (i = 1; i < sizeof(config_func_ptrs) / sizeof(config_func_ptrs[0]);
|
||||||
|
++i) {
|
||||||
|
if (config_func_ptrs[i].configure)
|
||||||
|
config_func_ptrs[i].configure();
|
||||||
|
}
|
||||||
|
|
||||||
|
TRACE_INFO("calling init of config %u...\r\n", simtrace_config);
|
||||||
|
config_func_ptrs[simtrace_config].init();
|
||||||
|
last_simtrace_config = simtrace_config;
|
||||||
|
|
||||||
|
TRACE_INFO("entering main loop...\r\n");
|
||||||
|
while (1) {
|
||||||
|
#if TRACE_LEVEL >= TRACE_LEVEL_DEBUG
|
||||||
|
const char rotor[] = { '-', '\\', '|', '/' };
|
||||||
|
putchar('\b');
|
||||||
|
putchar(rotor[i++ % ARRAY_SIZE(rotor)]);
|
||||||
|
#endif
|
||||||
|
check_exec_dbg_cmd();
|
||||||
|
osmo_timers_prepare();
|
||||||
|
osmo_timers_update();
|
||||||
|
|
||||||
|
if (USBD_GetState() < USBD_STATE_CONFIGURED) {
|
||||||
|
|
||||||
|
if (isUsbConnected) {
|
||||||
|
isUsbConnected = 0;
|
||||||
|
}
|
||||||
|
} else if (isUsbConnected == 0) {
|
||||||
|
TRACE_INFO("USB is now configured\r\n");
|
||||||
|
LED_Set(LED_NUM_GREEN);
|
||||||
|
LED_Clear(LED_NUM_RED);
|
||||||
|
|
||||||
|
isUsbConnected = 1;
|
||||||
|
}
|
||||||
|
if (last_simtrace_config != simtrace_config) {
|
||||||
|
TRACE_INFO("USB config chg %u -> %u\r\n",
|
||||||
|
last_simtrace_config, simtrace_config);
|
||||||
|
config_func_ptrs[last_simtrace_config].exit();
|
||||||
|
config_func_ptrs[simtrace_config].init();
|
||||||
|
last_simtrace_config = simtrace_config;
|
||||||
|
} else {
|
||||||
|
config_func_ptrs[simtrace_config].run();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -52,5 +52,8 @@
|
|||||||
|
|
||||||
#include "trace.h"
|
#include "trace.h"
|
||||||
#include "wdt.h"
|
#include "wdt.h"
|
||||||
|
#include "unique_id.h"
|
||||||
|
#include "efc.h"
|
||||||
|
#include "flashd.h"
|
||||||
|
|
||||||
#endif /* _LIB_SAM3S_ */
|
#endif /* _LIB_SAM3S_ */
|
||||||
113
firmware/atmel_softpack_libraries/libchip_sam3s/include/efc.h
Normal file
113
firmware/atmel_softpack_libraries/libchip_sam3s/include/efc.h
Normal file
@@ -0,0 +1,113 @@
|
|||||||
|
/* ----------------------------------------------------------------------------
|
||||||
|
* ATMEL Microcontroller Software Support
|
||||||
|
* ----------------------------------------------------------------------------
|
||||||
|
* Copyright (c) 2009, Atmel Corporation
|
||||||
|
*
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* - Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the disclaimer below.
|
||||||
|
*
|
||||||
|
* Atmel's name may not be used to endorse or promote products derived from
|
||||||
|
* this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
|
||||||
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||||||
|
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
|
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||||
|
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
* ----------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \file
|
||||||
|
*
|
||||||
|
* \section Purpose
|
||||||
|
*
|
||||||
|
* Interface for configuration the Enhanced Embedded Flash Controller (EEFC) peripheral.
|
||||||
|
*
|
||||||
|
* \section Usage
|
||||||
|
*
|
||||||
|
* -# Enable/disable %flash ready interrupt sources using EFC_EnableFrdyIt()
|
||||||
|
* and EFC_DisableFrdyIt().
|
||||||
|
* -# Translates the given address into which EEFC, page and offset values
|
||||||
|
* for difference density %flash memory using EFC_TranslateAddress().
|
||||||
|
* -# Computes the address of a %flash access given the EFC, page and offset
|
||||||
|
* for difference density %flash memory using EFC_ComputeAddress().
|
||||||
|
* -# Start the executing command with EFC_StartCommand()
|
||||||
|
* -# Retrieve the current status of the EFC using EFC_GetStatus().
|
||||||
|
* -# Retrieve the result of the last executed command with EFC_GetResult().
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _EEFC_
|
||||||
|
#define _EEFC_
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------
|
||||||
|
* Headers
|
||||||
|
*----------------------------------------------------------------------------*/
|
||||||
|
#include "chip.h"
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------
|
||||||
|
* Definitions
|
||||||
|
*----------------------------------------------------------------------------*/
|
||||||
|
/* EFC command */
|
||||||
|
#define EFC_FCMD_GETD 0x00
|
||||||
|
#define EFC_FCMD_WP 0x01
|
||||||
|
#define EFC_FCMD_WPL 0x02
|
||||||
|
#define EFC_FCMD_EWP 0x03
|
||||||
|
#define EFC_FCMD_EWPL 0x04
|
||||||
|
#define EFC_FCMD_EA 0x05
|
||||||
|
#define EFC_FCMD_SLB 0x08
|
||||||
|
#define EFC_FCMD_CLB 0x09
|
||||||
|
#define EFC_FCMD_GLB 0x0A
|
||||||
|
#define EFC_FCMD_SFB 0x0B
|
||||||
|
#define EFC_FCMD_CFB 0x0C
|
||||||
|
#define EFC_FCMD_GFB 0x0D
|
||||||
|
#define EFC_FCMD_STUI 0x0E /* Start unique ID */
|
||||||
|
#define EFC_FCMD_SPUI 0x0F /* Stop unique ID */
|
||||||
|
|
||||||
|
/* The IAP function entry addreass */
|
||||||
|
#define CHIP_FLASH_IAP_ADDRESS (0x00800008)
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------
|
||||||
|
* Exported functions
|
||||||
|
*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
extern void EFC_EnableFrdyIt( Efc* efc ) ;
|
||||||
|
|
||||||
|
extern void EFC_DisableFrdyIt( Efc* efc ) ;
|
||||||
|
|
||||||
|
extern void EFC_SetWaitState( Efc* efc, uint8_t cycles ) ;
|
||||||
|
|
||||||
|
extern void EFC_TranslateAddress( Efc** pEfc, uint32_t dwAddress, uint16_t *pwPage, uint16_t *pwOffset ) ;
|
||||||
|
|
||||||
|
extern void EFC_ComputeAddress( Efc* efc, uint16_t wPage, uint16_t wOffset, uint32_t *pdwAddress ) ;
|
||||||
|
|
||||||
|
extern void EFC_StartCommand( Efc* efc, uint32_t dwCommand, uint32_t dwArgument ) ;
|
||||||
|
|
||||||
|
extern uint32_t EFC_PerformCommand( Efc* efc, uint32_t dwCommand, uint32_t dwArgument, uint32_t dwUseIAP ) ;
|
||||||
|
|
||||||
|
extern uint32_t EFC_GetStatus( Efc* efc ) ;
|
||||||
|
|
||||||
|
extern uint32_t EFC_GetResult( Efc* efc ) ;
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* #ifndef _EEFC_ */
|
||||||
|
|
||||||
@@ -0,0 +1,79 @@
|
|||||||
|
/* ----------------------------------------------------------------------------
|
||||||
|
* ATMEL Microcontroller Software Support
|
||||||
|
* ----------------------------------------------------------------------------
|
||||||
|
* Copyright (c) 2009, Atmel Corporation
|
||||||
|
*
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* - Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the disclaimer below.
|
||||||
|
*
|
||||||
|
* Atmel's name may not be used to endorse or promote products derived from
|
||||||
|
* this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
|
||||||
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||||||
|
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
|
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||||
|
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
* ----------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \file
|
||||||
|
*
|
||||||
|
* The flash driver provides the unified interface for flash program operations.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _FLASHD_
|
||||||
|
#define _FLASHD_
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------
|
||||||
|
* Exported functions
|
||||||
|
*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
extern void FLASHD_Initialize( uint32_t dwMCk, uint32_t dwUseIAP ) ;
|
||||||
|
|
||||||
|
extern uint32_t FLASHD_Erase( uint32_t dwAddress ) ;
|
||||||
|
|
||||||
|
extern uint32_t FLASHD_Write( uint32_t dwAddress, const void *pvBuffer, uint32_t dwSize ) ;
|
||||||
|
|
||||||
|
extern uint32_t FLASHD_Lock( uint32_t dwStart, uint32_t dwEnd, uint32_t *pdwActualStart, uint32_t *pdwActualEnd ) ;
|
||||||
|
|
||||||
|
extern uint32_t FLASHD_Unlock( uint32_t dwStart, uint32_t dwEnd, uint32_t *pdwActualStart, uint32_t *pdwActualEnd ) ;
|
||||||
|
|
||||||
|
extern uint32_t FLASHD_IsLocked( uint32_t dwStart, uint32_t dwEnd ) ;
|
||||||
|
|
||||||
|
extern uint32_t FLASHD_SetGPNVM( uint8_t gpnvm ) ;
|
||||||
|
|
||||||
|
extern uint32_t FLASHD_ClearGPNVM( uint8_t gpnvm ) ;
|
||||||
|
|
||||||
|
extern uint32_t FLASHD_IsGPNVMSet( uint8_t gpnvm ) ;
|
||||||
|
|
||||||
|
#define FLASHD_IsSecurityBitSet() FLASHD_IsGPNVMSet( 0 )
|
||||||
|
|
||||||
|
#define FLASHD_SetSecurityBit() FLASHD_SetGPNVM( 0 )
|
||||||
|
|
||||||
|
extern uint32_t FLASHD_ReadUniqueID( uint32_t* pdwUniqueID ) ;
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* #ifndef _FLASHD_ */
|
||||||
|
|
||||||
@@ -176,7 +176,7 @@ extern void TRACE_CONFIGURE( uint32_t dwBaudRate, uint32_t dwMCk ) ;
|
|||||||
|
|
||||||
/* Trace compilation depends on TRACE_LEVEL value */
|
/* Trace compilation depends on TRACE_LEVEL value */
|
||||||
#if (TRACE_LEVEL >= TRACE_LEVEL_DEBUG)
|
#if (TRACE_LEVEL >= TRACE_LEVEL_DEBUG)
|
||||||
#define TRACE_DEBUG(...) { printf("-D- " __VA_ARGS__); printf("(%s func. %s)\n\r", __FILE__, __FUNCTION__); }
|
#define TRACE_DEBUG(...) { printf("-D- " __VA_ARGS__); }
|
||||||
#define TRACE_DEBUG_WP(...) { printf(__VA_ARGS__); }
|
#define TRACE_DEBUG_WP(...) { printf(__VA_ARGS__); }
|
||||||
#else
|
#else
|
||||||
#define TRACE_DEBUG(...) { }
|
#define TRACE_DEBUG(...) { }
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
void EEFC_ReadUniqueID(unsigned int *pdwUniqueID);
|
||||||
@@ -45,8 +45,14 @@
|
|||||||
* Headers
|
* Headers
|
||||||
*---------------------------------------------------------------------------*/
|
*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifdef TRACE_LEVEL
|
||||||
|
#undef TRACE_LEVEL
|
||||||
|
#endif
|
||||||
|
#define TRACE_LEVEL TRACE_LEVEL_WARNING
|
||||||
|
|
||||||
#include "chip.h"
|
#include "chip.h"
|
||||||
#include "USBD_HAL.h"
|
#include "USBD_HAL.h"
|
||||||
|
#include <usb/device/dfu/dfu.h>
|
||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
@@ -1156,6 +1162,22 @@ void USBD_IrqHandler(void)
|
|||||||
else if ((status & UDP_ISR_ENDBUSRES) != 0) {
|
else if ((status & UDP_ISR_ENDBUSRES) != 0) {
|
||||||
|
|
||||||
TRACE_INFO_WP("EoBRes ");
|
TRACE_INFO_WP("EoBRes ");
|
||||||
|
|
||||||
|
#if defined(BOARD_USB_DFU)
|
||||||
|
#if defined(APPLICATION_dfu)
|
||||||
|
/* if we are currently in the DFU bootloader, and we are beyond
|
||||||
|
* the MANIFEST stage, we shall switch to the normal
|
||||||
|
* application */
|
||||||
|
if (g_dfu->past_manifest)
|
||||||
|
USBDFU_SwitchToApp();
|
||||||
|
#else
|
||||||
|
/* if we are currently in the main application, and we are in
|
||||||
|
* appDETACH state, switch into the DFU bootloader */
|
||||||
|
if (g_dfu->state == DFU_STATE_appDETACH)
|
||||||
|
DFURT_SwitchToDFU();
|
||||||
|
#endif /* APPLICATION_dfu */
|
||||||
|
#endif /* BOARD_USB_DFU */
|
||||||
|
|
||||||
/* Flush and enable the Suspend interrupt */
|
/* Flush and enable the Suspend interrupt */
|
||||||
UDP->UDP_ICR = UDP_ICR_WAKEUP | UDP_ICR_RXRSM | UDP_ICR_RXSUSP;
|
UDP->UDP_ICR = UDP_ICR_WAKEUP | UDP_ICR_RXRSM | UDP_ICR_RXSUSP;
|
||||||
UDP->UDP_IER = UDP_IER_RXSUSP;
|
UDP->UDP_IER = UDP_IER_RXSUSP;
|
||||||
290
firmware/atmel_softpack_libraries/libchip_sam3s/source/efc.c
Normal file
290
firmware/atmel_softpack_libraries/libchip_sam3s/source/efc.c
Normal file
@@ -0,0 +1,290 @@
|
|||||||
|
/* ----------------------------------------------------------------------------
|
||||||
|
* ATMEL Microcontroller Software Support
|
||||||
|
* ----------------------------------------------------------------------------
|
||||||
|
* Copyright (c) 2009, Atmel Corporation
|
||||||
|
*
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* - Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the disclaimer below.
|
||||||
|
*
|
||||||
|
* Atmel's name may not be used to endorse or promote products derived from
|
||||||
|
* this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
|
||||||
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||||||
|
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
|
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||||
|
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
* ----------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** \addtogroup efc_module Working with EEFC
|
||||||
|
* The EEFC driver provides the interface to configure and use the EEFC
|
||||||
|
* peripheral.
|
||||||
|
*
|
||||||
|
* The user needs to set the number of wait states depending on the frequency used.\n
|
||||||
|
* Configure number of cycles for flash read/write operations in the FWS field of EEFC_FMR.
|
||||||
|
*
|
||||||
|
* It offers a function to send flash command to EEFC and waits for the
|
||||||
|
* flash to be ready.
|
||||||
|
*
|
||||||
|
* To send flash command, the user could do in either of following way:
|
||||||
|
* <ul>
|
||||||
|
* <li>Write a correct key, command and argument in EEFC_FCR. </li>
|
||||||
|
* <li>Or, Use IAP (In Application Programming) function which is executed from
|
||||||
|
* ROM directly, this allows flash programming to be done by code running in flash.</li>
|
||||||
|
* <li>Once the command is achieved, it can be detected even by polling EEFC_FSR or interrupt.
|
||||||
|
* </ul>
|
||||||
|
*
|
||||||
|
* The command argument could be a page number,GPNVM number or nothing, it depends on
|
||||||
|
* the command itself. Some useful functions in this driver could help user tranlate physical
|
||||||
|
* flash address into a page number and vice verse.
|
||||||
|
*
|
||||||
|
* For more accurate information, please look at the EEFC section of the
|
||||||
|
* Datasheet.
|
||||||
|
*
|
||||||
|
* Related files :\n
|
||||||
|
* \ref efc.c\n
|
||||||
|
* \ref efc.h.\n
|
||||||
|
*/
|
||||||
|
/*@{*/
|
||||||
|
/*@}*/
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \file
|
||||||
|
*
|
||||||
|
* Implementation of Enhanced Embedded Flash Controller (EEFC).
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------
|
||||||
|
* Headers
|
||||||
|
*----------------------------------------------------------------------------*/
|
||||||
|
#include "chip.h"
|
||||||
|
#include "efc.h"
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------
|
||||||
|
* Exported functions
|
||||||
|
*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Enables the flash ready interrupt source on the EEFC peripheral.
|
||||||
|
*
|
||||||
|
* \param efc Pointer to a Efc instance
|
||||||
|
*/
|
||||||
|
extern void EFC_EnableFrdyIt( Efc* efc )
|
||||||
|
{
|
||||||
|
efc->EEFC_FMR |= EEFC_FMR_FRDY ;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Disables the flash ready interrupt source on the EEFC peripheral.
|
||||||
|
*
|
||||||
|
* \param efc Pointer to a Efc instance
|
||||||
|
*/
|
||||||
|
|
||||||
|
extern void EFC_DisableFrdyIt( Efc* efc )
|
||||||
|
{
|
||||||
|
efc->EEFC_FMR &= ~((uint32_t)EEFC_FMR_FRDY) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Set read/write wait state on the EEFC perpherial.
|
||||||
|
*
|
||||||
|
* \param efc Pointer to a Efc instance
|
||||||
|
* \param cycles the number of wait states in cycle.
|
||||||
|
*/
|
||||||
|
|
||||||
|
extern void EFC_SetWaitState( Efc* efc, uint8_t ucCycles )
|
||||||
|
{
|
||||||
|
uint32_t dwValue ;
|
||||||
|
|
||||||
|
dwValue = efc->EEFC_FMR ;
|
||||||
|
dwValue &= ~((uint32_t)EEFC_FMR_FWS_Msk) ;
|
||||||
|
dwValue |= EEFC_FMR_FWS(ucCycles);
|
||||||
|
efc->EEFC_FMR = dwValue ;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Returns the current status of the EEFC.
|
||||||
|
*
|
||||||
|
* \note Keep in mind that this function clears the value of some status bits (LOCKE, PROGE).
|
||||||
|
*
|
||||||
|
* \param efc Pointer to a Efc instance
|
||||||
|
*/
|
||||||
|
extern uint32_t EFC_GetStatus( Efc* efc )
|
||||||
|
{
|
||||||
|
return efc->EEFC_FSR ;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Returns the result of the last executed command.
|
||||||
|
*
|
||||||
|
* \param efc Pointer to a Efc instance
|
||||||
|
*/
|
||||||
|
extern uint32_t EFC_GetResult( Efc* efc )
|
||||||
|
{
|
||||||
|
return efc->EEFC_FRR ;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Translates the given address page and offset values.
|
||||||
|
* \note The resulting values are stored in the provided variables if they are not null.
|
||||||
|
*
|
||||||
|
* \param efc Pointer to a Efc instance
|
||||||
|
* \param address Address to translate.
|
||||||
|
* \param pPage First page accessed.
|
||||||
|
* \param pOffset Byte offset in first page.
|
||||||
|
*/
|
||||||
|
extern void EFC_TranslateAddress( Efc** ppEfc, uint32_t dwAddress, uint16_t* pwPage, uint16_t* pwOffset )
|
||||||
|
{
|
||||||
|
Efc *pEfc ;
|
||||||
|
uint16_t wPage ;
|
||||||
|
uint16_t wOffset ;
|
||||||
|
|
||||||
|
assert( dwAddress >= IFLASH_ADDR ) ;
|
||||||
|
assert( dwAddress <= (IFLASH_ADDR + IFLASH_SIZE) ) ;
|
||||||
|
|
||||||
|
pEfc = EFC ;
|
||||||
|
wPage = (dwAddress - IFLASH_ADDR) / IFLASH_PAGE_SIZE;
|
||||||
|
wOffset = (dwAddress - IFLASH_ADDR) % IFLASH_PAGE_SIZE;
|
||||||
|
|
||||||
|
TRACE_DEBUG( "Translated 0x%08X to page=%d and offset=%d\n\r", dwAddress, wPage, wOffset ) ;
|
||||||
|
/* Store values */
|
||||||
|
if ( pEfc )
|
||||||
|
{
|
||||||
|
*ppEfc = pEfc ;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( pwPage )
|
||||||
|
{
|
||||||
|
*pwPage = wPage ;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( pwOffset )
|
||||||
|
{
|
||||||
|
*pwOffset = wOffset ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Computes the address of a flash access given the page and offset.
|
||||||
|
*
|
||||||
|
* \param efc Pointer to a Efc instance
|
||||||
|
* \param page Page number.
|
||||||
|
* \param offset Byte offset inside page.
|
||||||
|
* \param pAddress Computed address (optional).
|
||||||
|
*/
|
||||||
|
extern void EFC_ComputeAddress( Efc *efc, uint16_t wPage, uint16_t wOffset, uint32_t *pdwAddress )
|
||||||
|
{
|
||||||
|
uint32_t dwAddress ;
|
||||||
|
|
||||||
|
assert( efc ) ;
|
||||||
|
assert( wPage <= IFLASH_NB_OF_PAGES ) ;
|
||||||
|
assert( wOffset < IFLASH_PAGE_SIZE ) ;
|
||||||
|
|
||||||
|
/* Compute address */
|
||||||
|
dwAddress = IFLASH_ADDR + wPage * IFLASH_PAGE_SIZE + wOffset ;
|
||||||
|
|
||||||
|
/* Store result */
|
||||||
|
if ( pdwAddress != NULL )
|
||||||
|
{
|
||||||
|
*pdwAddress = dwAddress ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Starts the executing the given command on the EEFC and returns as soon as the command is started.
|
||||||
|
*
|
||||||
|
* \note It does NOT set the FMCN field automatically.
|
||||||
|
* \param efc Pointer to a Efc instance
|
||||||
|
* \param command Command to execute.
|
||||||
|
* \param argument Command argument (should be 0 if not used).
|
||||||
|
*/
|
||||||
|
extern void EFC_StartCommand( Efc* efc, uint32_t dwCommand, uint32_t dwArgument )
|
||||||
|
{
|
||||||
|
/* Check command & argument */
|
||||||
|
switch ( dwCommand )
|
||||||
|
{
|
||||||
|
case EFC_FCMD_WP:
|
||||||
|
case EFC_FCMD_WPL:
|
||||||
|
case EFC_FCMD_EWP:
|
||||||
|
case EFC_FCMD_EWPL:
|
||||||
|
case EFC_FCMD_SLB:
|
||||||
|
case EFC_FCMD_CLB:
|
||||||
|
assert( dwArgument < IFLASH_NB_OF_PAGES ) ;
|
||||||
|
break ;
|
||||||
|
|
||||||
|
case EFC_FCMD_SFB:
|
||||||
|
case EFC_FCMD_CFB:
|
||||||
|
assert( dwArgument < 2 ) ;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EFC_FCMD_GETD:
|
||||||
|
case EFC_FCMD_EA:
|
||||||
|
case EFC_FCMD_GLB:
|
||||||
|
case EFC_FCMD_GFB:
|
||||||
|
case EFC_FCMD_STUI:
|
||||||
|
assert( dwArgument == 0 ) ;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default: assert( 0 ) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Start command Embedded flash */
|
||||||
|
assert( (efc->EEFC_FSR & EEFC_FMR_FRDY) == EEFC_FMR_FRDY ) ;
|
||||||
|
efc->EEFC_FCR = EEFC_FCR_FKEY(0x5A) | EEFC_FCR_FARG(dwArgument) | EEFC_FCR_FCMD(dwCommand) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Performs the given command and wait until its completion (or an error).
|
||||||
|
*
|
||||||
|
* \param efc Pointer to a Efc instance
|
||||||
|
* \param command Command to perform.
|
||||||
|
* \param argument Optional command argument.
|
||||||
|
*
|
||||||
|
* \return 0 if successful, otherwise returns an error code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
extern uint32_t EFC_PerformCommand( Efc* efc, uint32_t dwCommand, uint32_t dwArgument, uint32_t dwUseIAP )
|
||||||
|
{
|
||||||
|
if ( dwUseIAP != 0 )
|
||||||
|
{
|
||||||
|
/* Pointer on IAP function in ROM */
|
||||||
|
static uint32_t (*IAP_PerformCommand)( uint32_t, uint32_t ) ;
|
||||||
|
|
||||||
|
IAP_PerformCommand = (uint32_t (*)( uint32_t, uint32_t )) *((uint32_t*)CHIP_FLASH_IAP_ADDRESS ) ;
|
||||||
|
IAP_PerformCommand( 0, EEFC_FCR_FKEY(0x5A) | EEFC_FCR_FARG(dwArgument) | EEFC_FCR_FCMD(dwCommand) ) ;
|
||||||
|
|
||||||
|
return (efc->EEFC_FSR & (EEFC_FSR_FLOCKE | EEFC_FSR_FCMDE)) ;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
uint32_t dwStatus ;
|
||||||
|
|
||||||
|
efc->EEFC_FCR = EEFC_FCR_FKEY(0x5A) | EEFC_FCR_FARG(dwArgument) | EEFC_FCR_FCMD(dwCommand) ;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
dwStatus = efc->EEFC_FSR ;
|
||||||
|
}
|
||||||
|
while ( (dwStatus & EEFC_FSR_FRDY) != EEFC_FSR_FRDY ) ;
|
||||||
|
|
||||||
|
return ( dwStatus & (EEFC_FSR_FLOCKE | EEFC_FSR_FCMDE) ) ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -52,6 +52,7 @@
|
|||||||
*/
|
*/
|
||||||
void IrqHandlerNotUsed( void )
|
void IrqHandlerNotUsed( void )
|
||||||
{
|
{
|
||||||
|
printf("NotUsed\r\n");
|
||||||
while ( 1 ) ;
|
while ( 1 ) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -60,15 +61,50 @@ void IrqHandlerNotUsed( void )
|
|||||||
*/
|
*/
|
||||||
WEAK void NMI_Handler( void )
|
WEAK void NMI_Handler( void )
|
||||||
{
|
{
|
||||||
|
printf("NMI\r\n");
|
||||||
while ( 1 ) ;
|
while ( 1 ) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Default HardFault interrupt handler.
|
* \brief Default HardFault interrupt handler.
|
||||||
*/
|
*/
|
||||||
|
struct hardfault_args {
|
||||||
|
unsigned long r0;
|
||||||
|
unsigned long r1;
|
||||||
|
unsigned long r2;
|
||||||
|
unsigned long r3;
|
||||||
|
unsigned long r12;
|
||||||
|
unsigned long lr;
|
||||||
|
unsigned long pc;
|
||||||
|
unsigned long psr;
|
||||||
|
};
|
||||||
|
|
||||||
|
void hard_fault_handler_c(struct hardfault_args *args)
|
||||||
|
{
|
||||||
|
printf("HardFault\r\n");
|
||||||
|
printf("R0=%08x, R1=%08x, R2=%08x, R3=%08x, R12=%08x\r\n",
|
||||||
|
args->r0, args->r1, args->r2, args->r3, args->r12);
|
||||||
|
printf("LR[R14]=%08x, PC[R15]=%08x, PSR=%08x\r\n",
|
||||||
|
args->lr, args->pc, args->psr);
|
||||||
|
printf("BFAR=%08x, CFSR=%08x, HFSR=%08x\r\n",
|
||||||
|
SCB->BFAR, SCB->CFSR, SCB->HFSR);
|
||||||
|
printf("DFSR=%08x, AFSR=%08x, SHCSR=%08x\r\n",
|
||||||
|
SCB->DFSR, SCB->CFSR, SCB->SHCSR);
|
||||||
|
while ( 1 ) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__((naked))
|
||||||
WEAK void HardFault_Handler( void )
|
WEAK void HardFault_Handler( void )
|
||||||
{
|
{
|
||||||
while ( 1 ) ;
|
__asm volatile(
|
||||||
|
".syntax unified \n"
|
||||||
|
" tst lr, #4 \n"
|
||||||
|
" ite eq \n"
|
||||||
|
" mrseq r0, msp \n"
|
||||||
|
" mrsne r0, psp \n"
|
||||||
|
//" ldr r1, [r0, #24] \n"
|
||||||
|
" b hard_fault_handler_c\n"
|
||||||
|
".syntax divided \n");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -76,6 +112,7 @@ WEAK void HardFault_Handler( void )
|
|||||||
*/
|
*/
|
||||||
WEAK void MemManage_Handler( void )
|
WEAK void MemManage_Handler( void )
|
||||||
{
|
{
|
||||||
|
printf("MemManage\r\n");
|
||||||
while ( 1 ) ;
|
while ( 1 ) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -84,6 +121,7 @@ WEAK void MemManage_Handler( void )
|
|||||||
*/
|
*/
|
||||||
WEAK void BusFault_Handler( void )
|
WEAK void BusFault_Handler( void )
|
||||||
{
|
{
|
||||||
|
printf("BusFault\r\n");
|
||||||
while ( 1 ) ;
|
while ( 1 ) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -92,6 +130,7 @@ WEAK void BusFault_Handler( void )
|
|||||||
*/
|
*/
|
||||||
WEAK void UsageFault_Handler( void )
|
WEAK void UsageFault_Handler( void )
|
||||||
{
|
{
|
||||||
|
printf("UsageFault\r\n");
|
||||||
while ( 1 ) ;
|
while ( 1 ) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -100,6 +139,7 @@ WEAK void UsageFault_Handler( void )
|
|||||||
*/
|
*/
|
||||||
WEAK void SVC_Handler( void )
|
WEAK void SVC_Handler( void )
|
||||||
{
|
{
|
||||||
|
printf("SVC\r\n");
|
||||||
while ( 1 ) ;
|
while ( 1 ) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -108,6 +148,7 @@ WEAK void SVC_Handler( void )
|
|||||||
*/
|
*/
|
||||||
WEAK void DebugMon_Handler( void )
|
WEAK void DebugMon_Handler( void )
|
||||||
{
|
{
|
||||||
|
printf("DebugMon\r\n");
|
||||||
while ( 1 ) ;
|
while ( 1 ) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -116,6 +157,7 @@ WEAK void DebugMon_Handler( void )
|
|||||||
*/
|
*/
|
||||||
WEAK void PendSV_Handler( void )
|
WEAK void PendSV_Handler( void )
|
||||||
{
|
{
|
||||||
|
printf("PendSV\r\n");
|
||||||
while ( 1 ) ;
|
while ( 1 ) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -124,6 +166,7 @@ WEAK void PendSV_Handler( void )
|
|||||||
*/
|
*/
|
||||||
WEAK void SysTick_Handler( void )
|
WEAK void SysTick_Handler( void )
|
||||||
{
|
{
|
||||||
|
printf("SysTick\r\n");
|
||||||
while ( 1 ) ;
|
while ( 1 ) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -132,6 +175,7 @@ WEAK void SysTick_Handler( void )
|
|||||||
*/
|
*/
|
||||||
WEAK void SUPC_IrqHandler( void )
|
WEAK void SUPC_IrqHandler( void )
|
||||||
{
|
{
|
||||||
|
printf("SUPC\r\n");
|
||||||
while ( 1 ) ;
|
while ( 1 ) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -140,6 +184,7 @@ WEAK void SUPC_IrqHandler( void )
|
|||||||
*/
|
*/
|
||||||
WEAK void RSTC_IrqHandler( void )
|
WEAK void RSTC_IrqHandler( void )
|
||||||
{
|
{
|
||||||
|
printf("RSTC\r\n");
|
||||||
while ( 1 ) ;
|
while ( 1 ) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -148,6 +193,7 @@ WEAK void RSTC_IrqHandler( void )
|
|||||||
*/
|
*/
|
||||||
WEAK void RTC_IrqHandler( void )
|
WEAK void RTC_IrqHandler( void )
|
||||||
{
|
{
|
||||||
|
printf("RTC\r\n");
|
||||||
while ( 1 ) ;
|
while ( 1 ) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -156,6 +202,7 @@ WEAK void RTC_IrqHandler( void )
|
|||||||
*/
|
*/
|
||||||
WEAK void RTT_IrqHandler( void )
|
WEAK void RTT_IrqHandler( void )
|
||||||
{
|
{
|
||||||
|
printf("RTT\r\n");
|
||||||
while ( 1 ) ;
|
while ( 1 ) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -164,6 +211,7 @@ WEAK void RTT_IrqHandler( void )
|
|||||||
*/
|
*/
|
||||||
WEAK void WDT_IrqHandler( void )
|
WEAK void WDT_IrqHandler( void )
|
||||||
{
|
{
|
||||||
|
printf("WDT\r\n");
|
||||||
while ( 1 ) ;
|
while ( 1 ) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -172,6 +220,7 @@ WEAK void WDT_IrqHandler( void )
|
|||||||
*/
|
*/
|
||||||
WEAK void PMC_IrqHandler( void )
|
WEAK void PMC_IrqHandler( void )
|
||||||
{
|
{
|
||||||
|
printf("PMC\r\n");
|
||||||
while ( 1 ) ;
|
while ( 1 ) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -180,6 +229,7 @@ WEAK void PMC_IrqHandler( void )
|
|||||||
*/
|
*/
|
||||||
WEAK void EEFC_IrqHandler( void )
|
WEAK void EEFC_IrqHandler( void )
|
||||||
{
|
{
|
||||||
|
printf("EEFC\r\n");
|
||||||
while ( 1 ) ;
|
while ( 1 ) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -188,6 +238,7 @@ WEAK void EEFC_IrqHandler( void )
|
|||||||
*/
|
*/
|
||||||
WEAK void UART0_IrqHandler( void )
|
WEAK void UART0_IrqHandler( void )
|
||||||
{
|
{
|
||||||
|
printf("UART0\r\n");
|
||||||
while ( 1 ) ;
|
while ( 1 ) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -196,6 +247,7 @@ WEAK void UART0_IrqHandler( void )
|
|||||||
*/
|
*/
|
||||||
WEAK void UART1_IrqHandler( void )
|
WEAK void UART1_IrqHandler( void )
|
||||||
{
|
{
|
||||||
|
printf("UART1\r\n");
|
||||||
while ( 1 ) ;
|
while ( 1 ) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -204,6 +256,7 @@ WEAK void UART1_IrqHandler( void )
|
|||||||
*/
|
*/
|
||||||
WEAK void SMC_IrqHandler( void )
|
WEAK void SMC_IrqHandler( void )
|
||||||
{
|
{
|
||||||
|
printf("SMC\r\n");
|
||||||
while ( 1 ) ;
|
while ( 1 ) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -212,6 +265,7 @@ WEAK void SMC_IrqHandler( void )
|
|||||||
*/
|
*/
|
||||||
WEAK void PIOA_IrqHandler( void )
|
WEAK void PIOA_IrqHandler( void )
|
||||||
{
|
{
|
||||||
|
printf("PIOA\r\n");
|
||||||
while ( 1 ) ;
|
while ( 1 ) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -220,6 +274,7 @@ WEAK void PIOA_IrqHandler( void )
|
|||||||
*/
|
*/
|
||||||
WEAK void PIOB_IrqHandler( void )
|
WEAK void PIOB_IrqHandler( void )
|
||||||
{
|
{
|
||||||
|
printf("PIOB\r\n");
|
||||||
while ( 1 ) ;
|
while ( 1 ) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -228,6 +283,7 @@ WEAK void PIOB_IrqHandler( void )
|
|||||||
*/
|
*/
|
||||||
WEAK void PIOC_IrqHandler( void )
|
WEAK void PIOC_IrqHandler( void )
|
||||||
{
|
{
|
||||||
|
printf("PIOC\r\n");
|
||||||
while ( 1 ) ;
|
while ( 1 ) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -236,6 +292,7 @@ WEAK void PIOC_IrqHandler( void )
|
|||||||
*/
|
*/
|
||||||
WEAK void USART0_IrqHandler( void )
|
WEAK void USART0_IrqHandler( void )
|
||||||
{
|
{
|
||||||
|
printf("USART0\r\n");
|
||||||
while ( 1 ) ;
|
while ( 1 ) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -244,6 +301,7 @@ WEAK void USART0_IrqHandler( void )
|
|||||||
*/
|
*/
|
||||||
WEAK void USART1_IrqHandler( void )
|
WEAK void USART1_IrqHandler( void )
|
||||||
{
|
{
|
||||||
|
printf("USART1\r\n");
|
||||||
while ( 1 ) ;
|
while ( 1 ) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -252,6 +310,7 @@ WEAK void USART1_IrqHandler( void )
|
|||||||
*/
|
*/
|
||||||
WEAK void MCI_IrqHandler( void )
|
WEAK void MCI_IrqHandler( void )
|
||||||
{
|
{
|
||||||
|
printf("MCI\r\n");
|
||||||
while ( 1 ) ;
|
while ( 1 ) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -260,6 +319,7 @@ WEAK void MCI_IrqHandler( void )
|
|||||||
*/
|
*/
|
||||||
WEAK void TWI0_IrqHandler( void )
|
WEAK void TWI0_IrqHandler( void )
|
||||||
{
|
{
|
||||||
|
printf("TWI0\r\n");
|
||||||
while ( 1 ) ;
|
while ( 1 ) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -268,6 +328,7 @@ WEAK void TWI0_IrqHandler( void )
|
|||||||
*/
|
*/
|
||||||
WEAK void TWI1_IrqHandler( void )
|
WEAK void TWI1_IrqHandler( void )
|
||||||
{
|
{
|
||||||
|
printf("TWI1\r\n");
|
||||||
while ( 1 ) ;
|
while ( 1 ) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -276,6 +337,7 @@ WEAK void TWI1_IrqHandler( void )
|
|||||||
*/
|
*/
|
||||||
WEAK void SPI_IrqHandler( void )
|
WEAK void SPI_IrqHandler( void )
|
||||||
{
|
{
|
||||||
|
printf("SPI\r\n");
|
||||||
while ( 1 ) ;
|
while ( 1 ) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -284,6 +346,7 @@ WEAK void SPI_IrqHandler( void )
|
|||||||
*/
|
*/
|
||||||
WEAK void SSC_IrqHandler( void )
|
WEAK void SSC_IrqHandler( void )
|
||||||
{
|
{
|
||||||
|
printf("SSC\r\n");
|
||||||
while ( 1 ) ;
|
while ( 1 ) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -292,6 +355,7 @@ WEAK void SSC_IrqHandler( void )
|
|||||||
*/
|
*/
|
||||||
WEAK void TC0_IrqHandler( void )
|
WEAK void TC0_IrqHandler( void )
|
||||||
{
|
{
|
||||||
|
printf("TC0\r\n");
|
||||||
while ( 1 ) ;
|
while ( 1 ) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -300,6 +364,7 @@ WEAK void TC0_IrqHandler( void )
|
|||||||
*/
|
*/
|
||||||
WEAK void TC1_IrqHandler( void )
|
WEAK void TC1_IrqHandler( void )
|
||||||
{
|
{
|
||||||
|
printf("TC1\r\n");
|
||||||
while ( 1 ) ;
|
while ( 1 ) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -308,6 +373,7 @@ WEAK void TC1_IrqHandler( void )
|
|||||||
*/
|
*/
|
||||||
WEAK void TC2_IrqHandler( void )
|
WEAK void TC2_IrqHandler( void )
|
||||||
{
|
{
|
||||||
|
printf("TC2\r\n");
|
||||||
while ( 1 ) ;
|
while ( 1 ) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -316,6 +382,7 @@ WEAK void TC2_IrqHandler( void )
|
|||||||
*/
|
*/
|
||||||
WEAK void TC3_IrqHandler( void )
|
WEAK void TC3_IrqHandler( void )
|
||||||
{
|
{
|
||||||
|
printf("TC3\r\n");
|
||||||
while ( 1 ) ;
|
while ( 1 ) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -324,6 +391,7 @@ WEAK void TC3_IrqHandler( void )
|
|||||||
*/
|
*/
|
||||||
WEAK void TC4_IrqHandler( void )
|
WEAK void TC4_IrqHandler( void )
|
||||||
{
|
{
|
||||||
|
printf("TC4\r\n");
|
||||||
while ( 1 ) ;
|
while ( 1 ) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -332,6 +400,7 @@ WEAK void TC4_IrqHandler( void )
|
|||||||
*/
|
*/
|
||||||
WEAK void TC5_IrqHandler( void )
|
WEAK void TC5_IrqHandler( void )
|
||||||
{
|
{
|
||||||
|
printf("TC5\r\n");
|
||||||
while ( 1 ) ;
|
while ( 1 ) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -340,6 +409,7 @@ WEAK void TC5_IrqHandler( void )
|
|||||||
*/
|
*/
|
||||||
WEAK void ADC_IrqHandler( void )
|
WEAK void ADC_IrqHandler( void )
|
||||||
{
|
{
|
||||||
|
printf("ADC\r\n");
|
||||||
while ( 1 ) ;
|
while ( 1 ) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -348,6 +418,7 @@ WEAK void ADC_IrqHandler( void )
|
|||||||
*/
|
*/
|
||||||
WEAK void DAC_IrqHandler( void )
|
WEAK void DAC_IrqHandler( void )
|
||||||
{
|
{
|
||||||
|
printf("DAC\r\n");
|
||||||
while ( 1 ) ;
|
while ( 1 ) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -356,6 +427,7 @@ WEAK void DAC_IrqHandler( void )
|
|||||||
*/
|
*/
|
||||||
WEAK void PWM_IrqHandler( void )
|
WEAK void PWM_IrqHandler( void )
|
||||||
{
|
{
|
||||||
|
printf("PWM\r\n");
|
||||||
while ( 1 ) ;
|
while ( 1 ) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -364,6 +436,7 @@ WEAK void PWM_IrqHandler( void )
|
|||||||
*/
|
*/
|
||||||
WEAK void CRCCU_IrqHandler( void )
|
WEAK void CRCCU_IrqHandler( void )
|
||||||
{
|
{
|
||||||
|
printf("CRCCU\r\n");
|
||||||
while ( 1 ) ;
|
while ( 1 ) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -372,6 +445,7 @@ WEAK void CRCCU_IrqHandler( void )
|
|||||||
*/
|
*/
|
||||||
WEAK void ACC_IrqHandler( void )
|
WEAK void ACC_IrqHandler( void )
|
||||||
{
|
{
|
||||||
|
printf("ACC\r\n");
|
||||||
while ( 1 ) ;
|
while ( 1 ) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -380,5 +454,6 @@ WEAK void ACC_IrqHandler( void )
|
|||||||
*/
|
*/
|
||||||
WEAK void USBD_IrqHandler( void )
|
WEAK void USBD_IrqHandler( void )
|
||||||
{
|
{
|
||||||
|
printf("USBD\r\n");
|
||||||
while ( 1 ) ;
|
while ( 1 ) ;
|
||||||
}
|
}
|
||||||
517
firmware/atmel_softpack_libraries/libchip_sam3s/source/flashd.c
Normal file
517
firmware/atmel_softpack_libraries/libchip_sam3s/source/flashd.c
Normal file
@@ -0,0 +1,517 @@
|
|||||||
|
/* ----------------------------------------------------------------------------
|
||||||
|
* ATMEL Microcontroller Software Support
|
||||||
|
* ----------------------------------------------------------------------------
|
||||||
|
* Copyright (c) 2009, Atmel Corporation
|
||||||
|
*
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* - Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the disclaimer below.
|
||||||
|
*
|
||||||
|
* Atmel's name may not be used to endorse or promote products derived from
|
||||||
|
* this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
|
||||||
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||||||
|
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
|
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||||
|
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
* ----------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** \addtogroup flashd_module Flash Memory Interface
|
||||||
|
* The flash driver manages the programming, erasing, locking and unlocking sequences
|
||||||
|
* with dedicated commands.
|
||||||
|
*
|
||||||
|
* To implement flash programing operation, the user has to follow these few steps :
|
||||||
|
* <ul>
|
||||||
|
* <li>Configue flash wait states to initializes the flash. </li>
|
||||||
|
* <li>Checks whether a region to be programmed is locked. </li>
|
||||||
|
* <li>Unlocks the user region to be programmed if the region have locked before.</li>
|
||||||
|
* <li>Erases the user page before program (optional).</li>
|
||||||
|
* <li>Writes the user page from the page buffer.</li>
|
||||||
|
* <li>Locks the region of programmed area if any.</li>
|
||||||
|
* </ul>
|
||||||
|
*
|
||||||
|
* Writing 8-bit and 16-bit data is not allowed and may lead to unpredictable data corruption.
|
||||||
|
* A check of this validity and padding for 32-bit alignment should be done in write algorithm.
|
||||||
|
|
||||||
|
* Lock/unlock range associated with the user address range is automatically translated.
|
||||||
|
*
|
||||||
|
* This security bit can be enabled through the command "Set General Purpose NVM Bit 0".
|
||||||
|
*
|
||||||
|
* A 128-bit factory programmed unique ID could be read to serve several purposes.
|
||||||
|
*
|
||||||
|
* The driver accesses the flash memory by calling the lowlevel module provided in \ref efc_module.
|
||||||
|
* For more accurate information, please look at the EEFC section of the Datasheet.
|
||||||
|
*
|
||||||
|
* Related files :\n
|
||||||
|
* \ref flashd.c\n
|
||||||
|
* \ref flashd.h.\n
|
||||||
|
* \ref efc.c\n
|
||||||
|
* \ref efc.h.\n
|
||||||
|
*/
|
||||||
|
/*@{*/
|
||||||
|
/*@}*/
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \file
|
||||||
|
*
|
||||||
|
* The flash driver provides the unified interface for flash program operations.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------
|
||||||
|
* Headers
|
||||||
|
*----------------------------------------------------------------------------*/
|
||||||
|
#include "chip.h"
|
||||||
|
#include "flashd.h"
|
||||||
|
#include "efc.h"
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------
|
||||||
|
* Local variables
|
||||||
|
*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
//static NO_INIT uint8_t _aucPageBuffer[IFLASH_PAGE_SIZE] ;
|
||||||
|
static NO_INIT uint32_t _adwPageBuffer[IFLASH_PAGE_SIZE/4] ;
|
||||||
|
static uint8_t* _aucPageBuffer = (uint8_t*)_adwPageBuffer;
|
||||||
|
static NO_INIT uint32_t _dwUseIAP ;
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------
|
||||||
|
* Local macros
|
||||||
|
*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#define min( a, b ) (((a) < (b)) ? (a) : (b))
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------
|
||||||
|
* Local functions
|
||||||
|
*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Computes the lock range associated with the given address range.
|
||||||
|
*
|
||||||
|
* \param dwStart Start address of lock range.
|
||||||
|
* \param dwEnd End address of lock range.
|
||||||
|
* \param pdwActualStart Actual start address of lock range.
|
||||||
|
* \param pdwActualEnd Actual end address of lock range.
|
||||||
|
*/
|
||||||
|
static void ComputeLockRange( uint32_t dwStart, uint32_t dwEnd, uint32_t *pdwActualStart, uint32_t *pdwActualEnd )
|
||||||
|
{
|
||||||
|
Efc* pStartEfc ;
|
||||||
|
Efc* pEndEfc ;
|
||||||
|
uint16_t wStartPage ;
|
||||||
|
uint16_t wEndPage ;
|
||||||
|
uint16_t wNumPagesInRegion ;
|
||||||
|
uint16_t wActualStartPage ;
|
||||||
|
uint16_t wActualEndPage ;
|
||||||
|
|
||||||
|
// Convert start and end address in page numbers
|
||||||
|
EFC_TranslateAddress( &pStartEfc, dwStart, &wStartPage, 0 ) ;
|
||||||
|
EFC_TranslateAddress( &pEndEfc, dwEnd, &wEndPage, 0 ) ;
|
||||||
|
|
||||||
|
// Find out the first page of the first region to lock
|
||||||
|
wNumPagesInRegion = IFLASH_LOCK_REGION_SIZE / IFLASH_PAGE_SIZE ;
|
||||||
|
wActualStartPage = wStartPage - (wStartPage % wNumPagesInRegion) ;
|
||||||
|
wActualEndPage = wEndPage ;
|
||||||
|
|
||||||
|
if ( (wEndPage % wNumPagesInRegion) != 0 )
|
||||||
|
{
|
||||||
|
wActualEndPage += wNumPagesInRegion - (wEndPage % wNumPagesInRegion) ;
|
||||||
|
}
|
||||||
|
// Store actual page numbers
|
||||||
|
EFC_ComputeAddress( pStartEfc, wActualStartPage, 0, pdwActualStart ) ;
|
||||||
|
EFC_ComputeAddress( pEndEfc, wActualEndPage, 0, pdwActualEnd ) ;
|
||||||
|
TRACE_DEBUG( "Actual lock range is 0x%06X - 0x%06X\n\r", *pdwActualStart, *pdwActualEnd ) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------
|
||||||
|
* Exported functions
|
||||||
|
*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Initializes the flash driver.
|
||||||
|
*
|
||||||
|
* \param mck Master clock frequency in Hz.
|
||||||
|
*/
|
||||||
|
|
||||||
|
extern void FLASHD_Initialize( uint32_t dwMCk, uint32_t dwUseIAP )
|
||||||
|
{
|
||||||
|
EFC_DisableFrdyIt( EFC ) ;
|
||||||
|
#if 1
|
||||||
|
/* See Revision A errata 46.1.1.3 */
|
||||||
|
EFC_SetWaitState(EFC, 6);
|
||||||
|
#else
|
||||||
|
if ( (dwMCk/1000000) >= 64 )
|
||||||
|
{
|
||||||
|
EFC_SetWaitState( EFC, 2 ) ;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ( (dwMCk/1000000) >= 50 )
|
||||||
|
{
|
||||||
|
EFC_SetWaitState( EFC, 1 ) ;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
EFC_SetWaitState( EFC, 0 ) ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
_dwUseIAP=dwUseIAP ;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Erases the entire flash.
|
||||||
|
*
|
||||||
|
* \param address Flash start address.
|
||||||
|
* \return 0 if successful; otherwise returns an error code.
|
||||||
|
*/
|
||||||
|
extern uint32_t FLASHD_Erase( uint32_t dwAddress )
|
||||||
|
{
|
||||||
|
Efc* pEfc ;
|
||||||
|
uint16_t wPage ;
|
||||||
|
uint16_t wOffset ;
|
||||||
|
uint32_t dwError ;
|
||||||
|
|
||||||
|
assert( (dwAddress >=IFLASH_ADDR) || (dwAddress <= (IFLASH_ADDR + IFLASH_SIZE)) ) ;
|
||||||
|
|
||||||
|
// Translate write address
|
||||||
|
EFC_TranslateAddress( &pEfc, dwAddress, &wPage, &wOffset ) ;
|
||||||
|
dwError = EFC_PerformCommand( pEfc, EFC_FCMD_EA, 0, _dwUseIAP ) ;
|
||||||
|
|
||||||
|
return dwError ;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Writes a data buffer in the internal flash
|
||||||
|
*
|
||||||
|
* \note This function works in polling mode, and thus only returns when the
|
||||||
|
* data has been effectively written.
|
||||||
|
* \param address Write address.
|
||||||
|
* \param pBuffer Data buffer.
|
||||||
|
* \param size Size of data buffer in bytes.
|
||||||
|
* \return 0 if successful, otherwise returns an error code.
|
||||||
|
*/
|
||||||
|
extern uint32_t FLASHD_Write( uint32_t dwAddress, const void *pvBuffer, uint32_t dwSize )
|
||||||
|
{
|
||||||
|
Efc* pEfc ;
|
||||||
|
uint16_t page ;
|
||||||
|
uint16_t offset ;
|
||||||
|
uint32_t writeSize ;
|
||||||
|
uint32_t pageAddress ;
|
||||||
|
uint16_t padding ;
|
||||||
|
uint32_t dwError ;
|
||||||
|
uint32_t sizeTmp ;
|
||||||
|
uint32_t *pAlignedDestination ;
|
||||||
|
uint32_t *pAlignedSource ;
|
||||||
|
|
||||||
|
assert( pvBuffer ) ;
|
||||||
|
assert( dwAddress >=IFLASH_ADDR ) ;
|
||||||
|
assert( (dwAddress + dwSize) <= (IFLASH_ADDR + IFLASH_SIZE) ) ;
|
||||||
|
|
||||||
|
/* Translate write address */
|
||||||
|
EFC_TranslateAddress( &pEfc, dwAddress, &page, &offset ) ;
|
||||||
|
|
||||||
|
/* Write all pages */
|
||||||
|
while ( dwSize > 0 )
|
||||||
|
{
|
||||||
|
/* Copy data in temporary buffer to avoid alignment problems */
|
||||||
|
writeSize = min((uint32_t)IFLASH_PAGE_SIZE - offset, dwSize ) ;
|
||||||
|
EFC_ComputeAddress(pEfc, page, 0, &pageAddress ) ;
|
||||||
|
padding = IFLASH_PAGE_SIZE - offset - writeSize ;
|
||||||
|
|
||||||
|
/* Pre-buffer data */
|
||||||
|
memcpy( _aucPageBuffer, (void *) pageAddress, offset);
|
||||||
|
|
||||||
|
/* Buffer data */
|
||||||
|
memcpy( _aucPageBuffer + offset, pvBuffer, writeSize);
|
||||||
|
|
||||||
|
/* Post-buffer data */
|
||||||
|
memcpy( _aucPageBuffer + offset + writeSize, (void *) (pageAddress + offset + writeSize), padding);
|
||||||
|
|
||||||
|
/* Write page
|
||||||
|
* Writing 8-bit and 16-bit data is not allowed and may lead to unpredictable data corruption
|
||||||
|
*/
|
||||||
|
pAlignedDestination = (uint32_t*)pageAddress ;
|
||||||
|
pAlignedSource = (uint32_t*)_adwPageBuffer ;
|
||||||
|
sizeTmp = IFLASH_PAGE_SIZE ;
|
||||||
|
|
||||||
|
while ( sizeTmp >= 4 )
|
||||||
|
{
|
||||||
|
*pAlignedDestination++ = *pAlignedSource++;
|
||||||
|
sizeTmp -= 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Send writing command */
|
||||||
|
dwError = EFC_PerformCommand( pEfc, EFC_FCMD_EWP, page, _dwUseIAP ) ;
|
||||||
|
if ( dwError )
|
||||||
|
{
|
||||||
|
return dwError ;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Progression */
|
||||||
|
dwAddress += IFLASH_PAGE_SIZE ;
|
||||||
|
pvBuffer = (void *)((uint32_t) pvBuffer + writeSize) ;
|
||||||
|
dwSize -= writeSize ;
|
||||||
|
page++;
|
||||||
|
offset = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0 ;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* \brief Locks all the regions in the given address range. The actual lock range is
|
||||||
|
* reported through two output parameters.
|
||||||
|
*
|
||||||
|
* \param start Start address of lock range.
|
||||||
|
* \param end End address of lock range.
|
||||||
|
* \param pActualStart Start address of the actual lock range (optional).
|
||||||
|
* \param pActualEnd End address of the actual lock range (optional).
|
||||||
|
* \return 0 if successful, otherwise returns an error code.
|
||||||
|
*/
|
||||||
|
extern uint32_t FLASHD_Lock( uint32_t start, uint32_t end, uint32_t *pActualStart, uint32_t *pActualEnd )
|
||||||
|
{
|
||||||
|
Efc *pEfc ;
|
||||||
|
uint32_t actualStart, actualEnd ;
|
||||||
|
uint16_t startPage, endPage ;
|
||||||
|
uint32_t dwError ;
|
||||||
|
uint16_t numPagesInRegion = IFLASH_LOCK_REGION_SIZE / IFLASH_PAGE_SIZE;
|
||||||
|
|
||||||
|
/* Compute actual lock range and store it */
|
||||||
|
ComputeLockRange( start, end, &actualStart, &actualEnd ) ;
|
||||||
|
if ( pActualStart != NULL )
|
||||||
|
{
|
||||||
|
*pActualStart = actualStart ;
|
||||||
|
}
|
||||||
|
if ( pActualEnd != NULL )
|
||||||
|
{
|
||||||
|
*pActualEnd = actualEnd;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Compute page numbers */
|
||||||
|
EFC_TranslateAddress( &pEfc, actualStart, &startPage, 0 ) ;
|
||||||
|
EFC_TranslateAddress( 0, actualEnd, &endPage, 0 ) ;
|
||||||
|
|
||||||
|
/* Lock all pages */
|
||||||
|
while ( startPage < endPage )
|
||||||
|
{
|
||||||
|
dwError = EFC_PerformCommand( pEfc, EFC_FCMD_SLB, startPage, _dwUseIAP ) ;
|
||||||
|
if ( dwError )
|
||||||
|
{
|
||||||
|
return dwError ;
|
||||||
|
}
|
||||||
|
startPage += numPagesInRegion;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0 ;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Unlocks all the regions in the given address range. The actual unlock range is
|
||||||
|
* reported through two output parameters.
|
||||||
|
* \param start Start address of unlock range.
|
||||||
|
* \param end End address of unlock range.
|
||||||
|
* \param pActualStart Start address of the actual unlock range (optional).
|
||||||
|
* \param pActualEnd End address of the actual unlock range (optional).
|
||||||
|
* \return 0 if successful, otherwise returns an error code.
|
||||||
|
*/
|
||||||
|
extern uint32_t FLASHD_Unlock( uint32_t start, uint32_t end, uint32_t *pActualStart, uint32_t *pActualEnd )
|
||||||
|
{
|
||||||
|
Efc* pEfc ;
|
||||||
|
uint32_t actualStart, actualEnd ;
|
||||||
|
uint16_t startPage, endPage ;
|
||||||
|
uint32_t dwError ;
|
||||||
|
uint16_t numPagesInRegion = IFLASH_LOCK_REGION_SIZE / IFLASH_PAGE_SIZE;
|
||||||
|
|
||||||
|
// Compute actual unlock range and store it
|
||||||
|
ComputeLockRange(start, end, &actualStart, &actualEnd);
|
||||||
|
if ( pActualStart != NULL )
|
||||||
|
{
|
||||||
|
*pActualStart = actualStart ;
|
||||||
|
}
|
||||||
|
if ( pActualEnd != NULL )
|
||||||
|
{
|
||||||
|
*pActualEnd = actualEnd ;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compute page numbers
|
||||||
|
EFC_TranslateAddress( &pEfc, actualStart, &startPage, 0 ) ;
|
||||||
|
EFC_TranslateAddress( 0, actualEnd, &endPage, 0 ) ;
|
||||||
|
|
||||||
|
// Unlock all pages
|
||||||
|
while ( startPage < endPage )
|
||||||
|
{
|
||||||
|
dwError = EFC_PerformCommand( pEfc, EFC_FCMD_CLB, startPage, _dwUseIAP ) ;
|
||||||
|
if ( dwError )
|
||||||
|
{
|
||||||
|
return dwError ;
|
||||||
|
}
|
||||||
|
startPage += numPagesInRegion ;
|
||||||
|
}
|
||||||
|
return 0 ;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Returns the number of locked regions inside the given address range.
|
||||||
|
*
|
||||||
|
* \param start Start address of range
|
||||||
|
* \param end End address of range.
|
||||||
|
*/
|
||||||
|
extern uint32_t FLASHD_IsLocked( uint32_t start, uint32_t end )
|
||||||
|
{
|
||||||
|
Efc *pEfc ;
|
||||||
|
uint16_t startPage, endPage ;
|
||||||
|
uint8_t startRegion, endRegion ;
|
||||||
|
uint32_t numPagesInRegion ;
|
||||||
|
uint32_t status ;
|
||||||
|
uint32_t dwError ;
|
||||||
|
uint32_t numLockedRegions = 0 ;
|
||||||
|
|
||||||
|
assert( end >= start ) ;
|
||||||
|
assert( (start >=IFLASH_ADDR) && (end <= IFLASH_ADDR + IFLASH_SIZE) ) ;
|
||||||
|
|
||||||
|
// Compute page numbers
|
||||||
|
EFC_TranslateAddress( &pEfc, start, &startPage, 0 ) ;
|
||||||
|
EFC_TranslateAddress( 0, end, &endPage, 0 ) ;
|
||||||
|
|
||||||
|
// Compute region numbers
|
||||||
|
numPagesInRegion = IFLASH_LOCK_REGION_SIZE / IFLASH_PAGE_SIZE ;
|
||||||
|
startRegion = startPage / numPagesInRegion ;
|
||||||
|
endRegion = endPage / numPagesInRegion ;
|
||||||
|
if ((endPage % numPagesInRegion) != 0)
|
||||||
|
{
|
||||||
|
endRegion++ ;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Retrieve lock status
|
||||||
|
dwError = EFC_PerformCommand( pEfc, EFC_FCMD_GLB, 0, _dwUseIAP ) ;
|
||||||
|
assert( !dwError ) ;
|
||||||
|
status = EFC_GetResult( pEfc ) ;
|
||||||
|
|
||||||
|
// Check status of each involved region
|
||||||
|
while ( startRegion < endRegion )
|
||||||
|
{
|
||||||
|
if ( (status & (1 << startRegion)) != 0 )
|
||||||
|
{
|
||||||
|
numLockedRegions++ ;
|
||||||
|
}
|
||||||
|
startRegion++ ;
|
||||||
|
}
|
||||||
|
|
||||||
|
return numLockedRegions ;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Check if the given GPNVM bit is set or not.
|
||||||
|
*
|
||||||
|
* \param gpnvm GPNVM bit index.
|
||||||
|
* \returns 1 if the given GPNVM bit is currently set; otherwise returns 0.
|
||||||
|
*/
|
||||||
|
extern uint32_t FLASHD_IsGPNVMSet( uint8_t ucGPNVM )
|
||||||
|
{
|
||||||
|
uint32_t dwError ;
|
||||||
|
uint32_t dwStatus ;
|
||||||
|
|
||||||
|
assert( ucGPNVM < 2 ) ;
|
||||||
|
|
||||||
|
/* Get GPNVMs status */
|
||||||
|
dwError = EFC_PerformCommand( EFC, EFC_FCMD_GFB, 0, _dwUseIAP ) ;
|
||||||
|
assert( !dwError ) ;
|
||||||
|
dwStatus = EFC_GetResult( EFC ) ;
|
||||||
|
|
||||||
|
/* Check if GPNVM is set */
|
||||||
|
if ( (dwStatus & (1 << ucGPNVM)) != 0 )
|
||||||
|
{
|
||||||
|
return 1 ;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return 0 ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Sets the selected GPNVM bit.
|
||||||
|
*
|
||||||
|
* \param gpnvm GPNVM bit index.
|
||||||
|
* \returns 0 if successful; otherwise returns an error code.
|
||||||
|
*/
|
||||||
|
extern uint32_t FLASHD_SetGPNVM( uint8_t ucGPNVM )
|
||||||
|
{
|
||||||
|
assert( ucGPNVM < 2 ) ;
|
||||||
|
|
||||||
|
if ( !FLASHD_IsGPNVMSet( ucGPNVM ) )
|
||||||
|
{
|
||||||
|
return EFC_PerformCommand( EFC, EFC_FCMD_SFB, ucGPNVM, _dwUseIAP ) ;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return 0 ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Clears the selected GPNVM bit.
|
||||||
|
*
|
||||||
|
* \param gpnvm GPNVM bit index.
|
||||||
|
* \returns 0 if successful; otherwise returns an error code.
|
||||||
|
*/
|
||||||
|
extern uint32_t FLASHD_ClearGPNVM( uint8_t ucGPNVM )
|
||||||
|
{
|
||||||
|
assert( ucGPNVM < 2 ) ;
|
||||||
|
|
||||||
|
if ( FLASHD_IsGPNVMSet( ucGPNVM ) )
|
||||||
|
{
|
||||||
|
return EFC_PerformCommand( EFC, EFC_FCMD_CFB, ucGPNVM, _dwUseIAP ) ;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return 0 ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* \brief Read the unique ID.
|
||||||
|
*
|
||||||
|
* \param uniqueID pointer on a 4bytes char containing the unique ID value.
|
||||||
|
* \returns 0 if successful; otherwise returns an error code.
|
||||||
|
*/
|
||||||
|
extern uint32_t FLASHD_ReadUniqueID( uint32_t* pdwUniqueID )
|
||||||
|
{
|
||||||
|
uint32_t dwError ;
|
||||||
|
|
||||||
|
assert( pdwUniqueID != NULL ) ;
|
||||||
|
|
||||||
|
pdwUniqueID[0] = 0 ;
|
||||||
|
pdwUniqueID[1] = 0 ;
|
||||||
|
pdwUniqueID[2] = 0 ;
|
||||||
|
pdwUniqueID[3] = 0 ;
|
||||||
|
|
||||||
|
EFC_StartCommand( EFC, EFC_FCMD_STUI, 0 ) ;
|
||||||
|
|
||||||
|
pdwUniqueID[0] = *(uint32_t*) IFLASH_ADDR;
|
||||||
|
pdwUniqueID[1] = *(uint32_t*)(IFLASH_ADDR + 4) ;
|
||||||
|
pdwUniqueID[2] = *(uint32_t*)(IFLASH_ADDR + 8) ;
|
||||||
|
pdwUniqueID[3] = *(uint32_t*)(IFLASH_ADDR + 12) ;
|
||||||
|
|
||||||
|
dwError = EFC_PerformCommand( EFC, EFC_FCMD_SPUI, 0, _dwUseIAP ) ;
|
||||||
|
if ( dwError )
|
||||||
|
{
|
||||||
|
return dwError ;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0 ;
|
||||||
|
}
|
||||||
@@ -83,9 +83,9 @@ static uint32_t _dwNumSources = 0;
|
|||||||
* \brief Stub, to handling all PIO Capture interrupts, if not defined.
|
* \brief Stub, to handling all PIO Capture interrupts, if not defined.
|
||||||
*/
|
*/
|
||||||
/*----------------------------------------------------------------------------*/
|
/*----------------------------------------------------------------------------*/
|
||||||
//extern WEAK void PIO_CaptureHandler( void )
|
extern WEAK void PIO_CaptureHandler( void )
|
||||||
//{
|
{
|
||||||
//}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Handles all interrupts on the given PIO controller.
|
* \brief Handles all interrupts on the given PIO controller.
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
#include "chip.h"
|
||||||
|
|
||||||
|
#define EFC_FCMD_STUI 0x0E
|
||||||
|
#define EFC_FCMD_SPUI 0x0F
|
||||||
|
|
||||||
|
__attribute__ ((section(".ramfunc")))
|
||||||
|
void EEFC_ReadUniqueID(unsigned int *pdwUniqueID)
|
||||||
|
{
|
||||||
|
unsigned int status;
|
||||||
|
|
||||||
|
/* Errata / Workaround: Set bit 16 of EEFC Flash Mode Register
|
||||||
|
* to 1 */
|
||||||
|
EFC->EEFC_FMR |= (1 << 16);
|
||||||
|
|
||||||
|
/* Send the Start Read unique Identifier command (STUI) by
|
||||||
|
* writing the Flash Command Register with the STUI command. */
|
||||||
|
EFC->EEFC_FCR = (0x5A << 24) | EFC_FCMD_STUI;
|
||||||
|
|
||||||
|
/* Wait for the FRDY bit to fall */
|
||||||
|
do {
|
||||||
|
status = EFC->EEFC_FSR;
|
||||||
|
} while ((status & EEFC_FSR_FRDY) == EEFC_FSR_FRDY);
|
||||||
|
|
||||||
|
/* The Unique Identifier is located in the first 128 bits of the
|
||||||
|
* Flash memory mapping. So, at the address 0x400000-0x400003.
|
||||||
|
* */
|
||||||
|
pdwUniqueID[0] = *(uint32_t *) IFLASH_ADDR;
|
||||||
|
pdwUniqueID[1] = *(uint32_t *) (IFLASH_ADDR + 4);
|
||||||
|
pdwUniqueID[2] = *(uint32_t *) (IFLASH_ADDR + 8);
|
||||||
|
pdwUniqueID[3] = *(uint32_t *) (IFLASH_ADDR + 12);
|
||||||
|
|
||||||
|
/* To stop the Unique Identifier mode, the user needs to send
|
||||||
|
* the Stop Read unique Identifier command (SPUI) by writing the
|
||||||
|
* Flash Command Register with the SPUI command. */
|
||||||
|
EFC->EEFC_FCR = (0x5A << 24) | EFC_FCMD_SPUI;
|
||||||
|
|
||||||
|
/* When the Stop read Unique Unique Identifier command (SPUI)
|
||||||
|
* has been performed, the FRDY bit in the Flash Programming
|
||||||
|
* Status Register (EEFC_FSR) rises. */
|
||||||
|
do {
|
||||||
|
status = EFC->EEFC_FSR;
|
||||||
|
} while ((status & EEFC_FSR_FRDY) != EEFC_FSR_FRDY);
|
||||||
|
}
|
||||||
81
firmware/atmel_softpack_libraries/usb/common/dfu/usb_dfu.h
Normal file
81
firmware/atmel_softpack_libraries/usb/common/dfu/usb_dfu.h
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
#ifndef _USB_DFU_H
|
||||||
|
#define _USB_DFU_H
|
||||||
|
/* USB Device Firmware Update Implementation for OpenPCD
|
||||||
|
* (C) 2006 by Harald Welte <hwelte@hmw-consulting.de>
|
||||||
|
*
|
||||||
|
* Protocol definitions for USB DFU
|
||||||
|
*
|
||||||
|
* This ought to be compliant to the USB DFU Spec 1.0 as available from
|
||||||
|
* http://www.usb.org/developers/devclass_docs/usbdfu10.pdf
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include <usb/include/USBRequests.h>
|
||||||
|
|
||||||
|
#define USB_DT_DFU 0x21
|
||||||
|
|
||||||
|
struct usb_dfu_func_descriptor {
|
||||||
|
uint8_t bLength;
|
||||||
|
uint8_t bDescriptorType;
|
||||||
|
uint8_t bmAttributes;
|
||||||
|
#define USB_DFU_CAN_DOWNLOAD (1 << 0)
|
||||||
|
#define USB_DFU_CAN_UPLOAD (1 << 1)
|
||||||
|
#define USB_DFU_MANIFEST_TOL (1 << 2)
|
||||||
|
#define USB_DFU_WILL_DETACH (1 << 3)
|
||||||
|
uint16_t wDetachTimeOut;
|
||||||
|
uint16_t wTransferSize;
|
||||||
|
uint16_t bcdDFUVersion;
|
||||||
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
|
#define USB_DT_DFU_SIZE 9
|
||||||
|
|
||||||
|
/* DFU class-specific requests (Section 3, DFU Rev 1.1) */
|
||||||
|
#define USB_REQ_DFU_DETACH 0x00
|
||||||
|
#define USB_REQ_DFU_DNLOAD 0x01
|
||||||
|
#define USB_REQ_DFU_UPLOAD 0x02
|
||||||
|
#define USB_REQ_DFU_GETSTATUS 0x03
|
||||||
|
#define USB_REQ_DFU_CLRSTATUS 0x04
|
||||||
|
#define USB_REQ_DFU_GETSTATE 0x05
|
||||||
|
#define USB_REQ_DFU_ABORT 0x06
|
||||||
|
|
||||||
|
struct dfu_status {
|
||||||
|
uint8_t bStatus;
|
||||||
|
uint8_t bwPollTimeout[3];
|
||||||
|
uint8_t bState;
|
||||||
|
uint8_t iString;
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
#define DFU_STATUS_OK 0x00
|
||||||
|
#define DFU_STATUS_errTARGET 0x01
|
||||||
|
#define DFU_STATUS_errFILE 0x02
|
||||||
|
#define DFU_STATUS_errWRITE 0x03
|
||||||
|
#define DFU_STATUS_errERASE 0x04
|
||||||
|
#define DFU_STATUS_errCHECK_ERASED 0x05
|
||||||
|
#define DFU_STATUS_errPROG 0x06
|
||||||
|
#define DFU_STATUS_errVERIFY 0x07
|
||||||
|
#define DFU_STATUS_errADDRESS 0x08
|
||||||
|
#define DFU_STATUS_errNOTDONE 0x09
|
||||||
|
#define DFU_STATUS_errFIRMWARE 0x0a
|
||||||
|
#define DFU_STATUS_errVENDOR 0x0b
|
||||||
|
#define DFU_STATUS_errUSBR 0x0c
|
||||||
|
#define DFU_STATUS_errPOR 0x0d
|
||||||
|
#define DFU_STATUS_errUNKNOWN 0x0e
|
||||||
|
#define DFU_STATUS_errSTALLEDPKT 0x0f
|
||||||
|
|
||||||
|
enum dfu_state {
|
||||||
|
DFU_STATE_appIDLE = 0,
|
||||||
|
DFU_STATE_appDETACH = 1,
|
||||||
|
DFU_STATE_dfuIDLE = 2,
|
||||||
|
DFU_STATE_dfuDNLOAD_SYNC = 3,
|
||||||
|
DFU_STATE_dfuDNBUSY = 4,
|
||||||
|
DFU_STATE_dfuDNLOAD_IDLE = 5,
|
||||||
|
DFU_STATE_dfuMANIFEST_SYNC = 6,
|
||||||
|
DFU_STATE_dfuMANIFEST = 7,
|
||||||
|
DFU_STATE_dfuMANIFEST_WAIT_RST = 8,
|
||||||
|
DFU_STATE_dfuUPLOAD_IDLE = 9,
|
||||||
|
DFU_STATE_dfuERROR = 10,
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* _USB_DFU_H */
|
||||||
49
firmware/atmel_softpack_libraries/usb/device/dfu/dfu.c
Normal file
49
firmware/atmel_softpack_libraries/usb/device/dfu/dfu.c
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
|
||||||
|
#include <usb/include/USBDescriptors.h>
|
||||||
|
#include <usb/device/dfu/dfu.h>
|
||||||
|
|
||||||
|
|
||||||
|
/* String 1 "SimTrace DFU Interface - Application Partition" */
|
||||||
|
const struct USBStringDescriptor USBDFU_string1 = {
|
||||||
|
.hdr = {
|
||||||
|
.bLength = sizeof(USBGenericDescriptor) + 46 * sizeof(unsigned short),
|
||||||
|
.bDescriptorType = USBGenericDescriptor_STRING,
|
||||||
|
},
|
||||||
|
.wData = { 0x0053, 0x0069, 0x006d, 0x0054, 0x0072, 0x0061,
|
||||||
|
0x0063, 0x0065, 0x0020, 0x0044, 0x0046, 0x0055,
|
||||||
|
0x0020, 0x0049, 0x006e, 0x0074, 0x0065, 0x0072,
|
||||||
|
0x0066, 0x0061, 0x0063, 0x0065, 0x0020, 0x002d,
|
||||||
|
0x0020, 0x0041, 0x0070, 0x0070, 0x006c, 0x0069,
|
||||||
|
0x0063, 0x0061, 0x0074, 0x0069, 0x006f, 0x006e,
|
||||||
|
0x0020, 0x0050, 0x0061, 0x0072, 0x0074, 0x0069,
|
||||||
|
0x0074, 0x0069, 0x006f, 0x006e, },
|
||||||
|
};
|
||||||
|
|
||||||
|
/* String 2 "SimTrace DFU Interface - Bootloader Partition" */
|
||||||
|
const struct USBStringDescriptor USBDFU_string2 = {
|
||||||
|
.hdr = {
|
||||||
|
.bLength = sizeof(USBGenericDescriptor) + 45 * sizeof(unsigned short),
|
||||||
|
.bDescriptorType = USBGenericDescriptor_STRING,
|
||||||
|
},
|
||||||
|
.wData = { 0x0053, 0x0069, 0x006d, 0x0054, 0x0072, 0x0061,
|
||||||
|
0x0063, 0x0065, 0x0020, 0x0044, 0x0046, 0x0055,
|
||||||
|
0x0020, 0x0049, 0x006e, 0x0074, 0x0065, 0x0072,
|
||||||
|
0x0066, 0x0061, 0x0063, 0x0065, 0x0020, 0x002d,
|
||||||
|
0x0020, 0x0042, 0x006f, 0x006f, 0x0074, 0x006c,
|
||||||
|
0x006f, 0x0061, 0x0064, 0x0065, 0x0072, 0x0020,
|
||||||
|
0x0050, 0x0061, 0x0072, 0x0074, 0x0069, 0x0074,
|
||||||
|
0x0069, 0x006f, 0x006e, },
|
||||||
|
};
|
||||||
|
|
||||||
|
/* String 3 "SimTrace DFU Interface - RAM" */
|
||||||
|
const struct USBStringDescriptor USBDFU_string3 = {
|
||||||
|
.hdr = {
|
||||||
|
.bLength = sizeof(USBGenericDescriptor) + 28 * sizeof(unsigned short),
|
||||||
|
.bDescriptorType = USBGenericDescriptor_STRING,
|
||||||
|
},
|
||||||
|
.wData = { 0x0053, 0x0069, 0x006d, 0x0054, 0x0072, 0x0061,
|
||||||
|
0x0063, 0x0065, 0x0020, 0x0044, 0x0046, 0x0055,
|
||||||
|
0x0020, 0x0049, 0x006e, 0x0074, 0x0065, 0x0072,
|
||||||
|
0x0066, 0x0061, 0x0063, 0x0065, 0x0020, 0x002d,
|
||||||
|
0x0020, 0x0052, 0x0041, 0x004d, },
|
||||||
|
};
|
||||||
131
firmware/atmel_softpack_libraries/usb/device/dfu/dfu.h
Normal file
131
firmware/atmel_softpack_libraries/usb/device/dfu/dfu.h
Normal file
@@ -0,0 +1,131 @@
|
|||||||
|
#ifndef _USB_DEV_DFU_H
|
||||||
|
#define _USB_DEV_DFU_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <board.h>
|
||||||
|
#include <usb/include/USBDescriptors.h>
|
||||||
|
#include <usb/include/USBDDriver.h>
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
/* This is valid for CCID */
|
||||||
|
#define CONFIG_DFU_NUM_APP_IF 1
|
||||||
|
#define CONFIG_DFU_NUM_APP_STR 4
|
||||||
|
#else
|
||||||
|
/* This is valid for CDC-Serial */
|
||||||
|
#define CONFIG_DFU_NUM_APP_IF 2
|
||||||
|
#define CONFIG_DFU_NUM_APP_STR 2
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct USBStringDescriptor {
|
||||||
|
USBGenericDescriptor hdr;
|
||||||
|
unsigned short wData[];
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef BOARD_USB_DFU
|
||||||
|
|
||||||
|
#include <usb/common/dfu/usb_dfu.h>
|
||||||
|
|
||||||
|
/* for board-specific config */
|
||||||
|
#include <board.h>
|
||||||
|
|
||||||
|
struct dfu_desc {
|
||||||
|
USBConfigurationDescriptor ucfg;
|
||||||
|
USBInterfaceDescriptor uif[BOARD_DFU_NUM_IF];
|
||||||
|
struct usb_dfu_func_descriptor func_dfu;
|
||||||
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
|
/* USB DFU functional descriptor */
|
||||||
|
#define DFU_FUNC_DESC { \
|
||||||
|
.bLength = USB_DT_DFU_SIZE, \
|
||||||
|
.bDescriptorType = USB_DT_DFU, \
|
||||||
|
.bmAttributes = USB_DFU_CAN_UPLOAD | USB_DFU_CAN_DOWNLOAD, \
|
||||||
|
.wDetachTimeOut = 0xff00, \
|
||||||
|
.wTransferSize = BOARD_DFU_PAGE_SIZE, \
|
||||||
|
.bcdDFUVersion = 0x0100, \
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Number of DFU interface during runtime mode */
|
||||||
|
#define DFURT_NUM_IF 1
|
||||||
|
|
||||||
|
/* to be used by the runtime as part of its USB descriptor structure
|
||||||
|
* declaration */
|
||||||
|
#define DFURT_IF_DESCRIPTOR_STRUCT \
|
||||||
|
USBInterfaceDescriptor dfu_rt; \
|
||||||
|
struct usb_dfu_func_descriptor func_dfu;
|
||||||
|
|
||||||
|
/* to be used by the runtime as part of its USB Dsecriptor structure
|
||||||
|
* definition */
|
||||||
|
#define DFURT_IF_DESCRIPTOR(dfuIF, dfuSTR) \
|
||||||
|
.dfu_rt = { \
|
||||||
|
.bLength = sizeof(USBInterfaceDescriptor), \
|
||||||
|
.bDescriptorType = USBGenericDescriptor_INTERFACE, \
|
||||||
|
.bInterfaceNumber = dfuIF, \
|
||||||
|
.bAlternateSetting = 0, \
|
||||||
|
.bNumEndpoints = 0, \
|
||||||
|
.bInterfaceClass = 0xFE, \
|
||||||
|
.bInterfaceSubClass = 0x01, \
|
||||||
|
.bInterfaceProtocol = 0x01, \
|
||||||
|
.iInterface = dfuSTR, \
|
||||||
|
}, \
|
||||||
|
.func_dfu = DFU_FUNC_DESC \
|
||||||
|
|
||||||
|
/* provided by dfu_desc.c */
|
||||||
|
extern const struct dfu_desc dfu_cfg_descriptor;
|
||||||
|
extern const USBDDriverDescriptors dfu_descriptors;
|
||||||
|
|
||||||
|
#else /* BOARD_USB_DFU */
|
||||||
|
|
||||||
|
/* no DFU bootloader is being used */
|
||||||
|
#define DFURT_NUM_IF 0
|
||||||
|
#define DFURT_IF_DESCRIPTOR_STRUCT(a, b)
|
||||||
|
#define DFURT_IF_DESCRIPTOR
|
||||||
|
|
||||||
|
#endif /* BOARD_USB_DFU */
|
||||||
|
|
||||||
|
/* magic value we use during boot to detect if we should start in DFU
|
||||||
|
* mode or runtime mode */
|
||||||
|
#define USB_DFU_MAGIC 0xDFDFDFDF
|
||||||
|
|
||||||
|
/* The API between the core DFU handler and the board/soc specific code */
|
||||||
|
|
||||||
|
struct dfudata {
|
||||||
|
uint32_t magic;
|
||||||
|
uint8_t status;
|
||||||
|
uint32_t state;
|
||||||
|
int past_manifest;
|
||||||
|
unsigned int total_bytes;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* RAM address for this magic value above */
|
||||||
|
extern struct dfudata _g_dfu;
|
||||||
|
extern struct dfudata *g_dfu;
|
||||||
|
|
||||||
|
void set_usb_serial_str(const uint8_t *serial_usbstr);
|
||||||
|
|
||||||
|
void DFURT_SwitchToDFU(void);
|
||||||
|
|
||||||
|
/* call-backs from DFU USB function driver to the board/SOC */
|
||||||
|
extern int USBDFU_handle_dnload(uint8_t altif, unsigned int offset,
|
||||||
|
uint8_t *data, unsigned int len);
|
||||||
|
extern int USBDFU_handle_upload(uint8_t altif, unsigned int offset,
|
||||||
|
uint8_t *data, unsigned int req_len);
|
||||||
|
|
||||||
|
/* function to be called at end of EP0 handler during runtime */
|
||||||
|
void USBDFU_Runtime_RequestHandler(const USBGenericRequest *request);
|
||||||
|
|
||||||
|
/* function to be called at end of EP0 handler during DFU mode */
|
||||||
|
void USBDFU_DFU_RequestHandler(const USBGenericRequest *request);
|
||||||
|
|
||||||
|
/* initialization of USB DFU driver (in DFU mode */
|
||||||
|
void USBDFU_Initialize(const USBDDriverDescriptors *pDescriptors);
|
||||||
|
|
||||||
|
/* USBD tells us to switch from DFU mode to application mode */
|
||||||
|
void USBDFU_SwitchToApp(void);
|
||||||
|
|
||||||
|
/* Return values to be used by USBDFU_handle_{dn,up}load */
|
||||||
|
#define DFU_RET_NOTHING 0
|
||||||
|
#define DFU_RET_ZLP 1
|
||||||
|
#define DFU_RET_STALL 2
|
||||||
|
|
||||||
|
#endif
|
||||||
214
firmware/atmel_softpack_libraries/usb/device/dfu/dfu_desc.c
Normal file
214
firmware/atmel_softpack_libraries/usb/device/dfu/dfu_desc.c
Normal file
@@ -0,0 +1,214 @@
|
|||||||
|
/* DFU related USB Descriptors */
|
||||||
|
/* (C) 2006-2017 Harald Welte <hwelte@hmw-consulting.de> */
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "board.h"
|
||||||
|
#include "utils.h"
|
||||||
|
|
||||||
|
#include <usb/include/USBDescriptors.h>
|
||||||
|
|
||||||
|
#include <usb/include/USBDDriver.h>
|
||||||
|
|
||||||
|
#include <usb/common/dfu/usb_dfu.h>
|
||||||
|
#include <usb/device/dfu/dfu.h>
|
||||||
|
|
||||||
|
enum {
|
||||||
|
STR_MANUF = 1,
|
||||||
|
STR_PROD,
|
||||||
|
STR_CONFIG,
|
||||||
|
_STR_FIRST_ALT,
|
||||||
|
STR_SERIAL = (_STR_FIRST_ALT+BOARD_DFU_NUM_IF),
|
||||||
|
};
|
||||||
|
|
||||||
|
static const USBDeviceDescriptor fsDevice = {
|
||||||
|
.bLength = sizeof(USBDeviceDescriptor),
|
||||||
|
.bDescriptorType = USBGenericDescriptor_DEVICE,
|
||||||
|
.bcdUSB = USBDeviceDescriptor_USB2_00,
|
||||||
|
.bDeviceClass = 0,
|
||||||
|
.bDeviceSubClass = 0,
|
||||||
|
.bDeviceProtocol = 0,
|
||||||
|
.bMaxPacketSize0 = BOARD_USB_ENDPOINTS_MAXPACKETSIZE(0),
|
||||||
|
.idVendor = BOARD_USB_VENDOR,
|
||||||
|
.idProduct = BOARD_USB_PRODUCT,
|
||||||
|
.bcdDevice = BOARD_USB_RELEASE,
|
||||||
|
.iManufacturer = STR_MANUF,
|
||||||
|
.iProduct = STR_PROD,
|
||||||
|
#ifdef BOARD_USB_SERIAL
|
||||||
|
.iSerialNumber = STR_SERIAL,
|
||||||
|
#else
|
||||||
|
.iSerialNumber = 0,
|
||||||
|
#endif
|
||||||
|
.bNumConfigurations = 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Alternate Interface Descriptor, we use one per partition/memory type */
|
||||||
|
#define DFU_IF(ALT) \
|
||||||
|
{ \
|
||||||
|
.bLength = sizeof(USBInterfaceDescriptor), \
|
||||||
|
.bDescriptorType = USBGenericDescriptor_INTERFACE, \
|
||||||
|
.bInterfaceNumber = 0, \
|
||||||
|
.bAlternateSetting = ALT, \
|
||||||
|
.bNumEndpoints = 0, \
|
||||||
|
.bInterfaceClass = 0xfe, \
|
||||||
|
.bInterfaceSubClass = 1, \
|
||||||
|
.iInterface = (_STR_FIRST_ALT+ALT), \
|
||||||
|
.bInterfaceProtocol = 2, \
|
||||||
|
}
|
||||||
|
|
||||||
|
/* overall descriptor for the DFU configuration, including all
|
||||||
|
* descriptors for alternate interfaces */
|
||||||
|
const struct dfu_desc dfu_cfg_descriptor = {
|
||||||
|
.ucfg = {
|
||||||
|
.bLength = sizeof(USBConfigurationDescriptor),
|
||||||
|
.bDescriptorType = USBGenericDescriptor_CONFIGURATION,
|
||||||
|
.wTotalLength = sizeof(struct dfu_desc),
|
||||||
|
.bNumInterfaces = 1,
|
||||||
|
.bConfigurationValue = 1,
|
||||||
|
.iConfiguration = STR_CONFIG,
|
||||||
|
.bmAttributes = BOARD_USB_BMATTRIBUTES,
|
||||||
|
.bMaxPower = 100,
|
||||||
|
},
|
||||||
|
.uif[0] = DFU_IF(0),
|
||||||
|
#if BOARD_DFU_NUM_IF > 1
|
||||||
|
.uif[1] = DFU_IF(1),
|
||||||
|
#endif
|
||||||
|
#if BOARD_DFU_NUM_IF > 2
|
||||||
|
.uif[2] = DFU_IF(2),
|
||||||
|
#endif
|
||||||
|
#if BOARD_DFU_NUM_IF > 3
|
||||||
|
.uif[3] = DFU_IF(3),
|
||||||
|
#endif
|
||||||
|
#if BOARD_DFU_NUM_IF > 4
|
||||||
|
.uif[4] = DFU_IF(4),
|
||||||
|
#endif
|
||||||
|
.func_dfu = DFU_FUNC_DESC
|
||||||
|
};
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
#include "usb_strings.h"
|
||||||
|
|
||||||
|
|
||||||
|
static const unsigned char *usb_strings[] = {
|
||||||
|
USB_STRINGS_GENERATED
|
||||||
|
#ifdef BOARD_USB_SERIAL
|
||||||
|
NULL
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
void set_usb_serial_str(const uint8_t *serial_usbstr)
|
||||||
|
{
|
||||||
|
usb_strings[STR_SERIAL] = serial_usbstr;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
static const unsigned char langDesc[] = {
|
||||||
|
USBStringDescriptor_LENGTH(1),
|
||||||
|
USBGenericDescriptor_STRING,
|
||||||
|
USBStringDescriptor_ENGLISH_US
|
||||||
|
};
|
||||||
|
|
||||||
|
static const unsigned char manufStringDescriptor[] = {
|
||||||
|
USBStringDescriptor_LENGTH(24),
|
||||||
|
USBGenericDescriptor_STRING,
|
||||||
|
USBStringDescriptor_UNICODE('s'),
|
||||||
|
USBStringDescriptor_UNICODE('y'),
|
||||||
|
USBStringDescriptor_UNICODE('s'),
|
||||||
|
USBStringDescriptor_UNICODE('m'),
|
||||||
|
USBStringDescriptor_UNICODE('o'),
|
||||||
|
USBStringDescriptor_UNICODE('c'),
|
||||||
|
USBStringDescriptor_UNICODE('o'),
|
||||||
|
USBStringDescriptor_UNICODE('m'),
|
||||||
|
USBStringDescriptor_UNICODE(' '),
|
||||||
|
USBStringDescriptor_UNICODE('-'),
|
||||||
|
USBStringDescriptor_UNICODE(' '),
|
||||||
|
USBStringDescriptor_UNICODE('s'),
|
||||||
|
USBStringDescriptor_UNICODE('.'),
|
||||||
|
USBStringDescriptor_UNICODE('f'),
|
||||||
|
USBStringDescriptor_UNICODE('.'),
|
||||||
|
USBStringDescriptor_UNICODE('m'),
|
||||||
|
USBStringDescriptor_UNICODE('.'),
|
||||||
|
USBStringDescriptor_UNICODE('c'),
|
||||||
|
USBStringDescriptor_UNICODE('.'),
|
||||||
|
USBStringDescriptor_UNICODE(' '),
|
||||||
|
USBStringDescriptor_UNICODE('G'),
|
||||||
|
USBStringDescriptor_UNICODE('m'),
|
||||||
|
USBStringDescriptor_UNICODE('b'),
|
||||||
|
USBStringDescriptor_UNICODE('H'),
|
||||||
|
};
|
||||||
|
|
||||||
|
static const unsigned char productStringDescriptor[] = {
|
||||||
|
USBStringDescriptor_LENGTH(10),
|
||||||
|
USBGenericDescriptor_STRING,
|
||||||
|
USBStringDescriptor_UNICODE('S'),
|
||||||
|
USBStringDescriptor_UNICODE('I'),
|
||||||
|
USBStringDescriptor_UNICODE('M'),
|
||||||
|
USBStringDescriptor_UNICODE('t'),
|
||||||
|
USBStringDescriptor_UNICODE('r'),
|
||||||
|
USBStringDescriptor_UNICODE('a'),
|
||||||
|
USBStringDescriptor_UNICODE('c'),
|
||||||
|
USBStringDescriptor_UNICODE('e'),
|
||||||
|
USBStringDescriptor_UNICODE(' '),
|
||||||
|
USBStringDescriptor_UNICODE('2'),
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static const unsigned char configStringDescriptor[] = {
|
||||||
|
USBStringDescriptor_LENGTH(3),
|
||||||
|
USBGenericDescriptor_STRING,
|
||||||
|
USBStringDescriptor_UNICODE('D'),
|
||||||
|
USBStringDescriptor_UNICODE('F'),
|
||||||
|
USBStringDescriptor_UNICODE('U'),
|
||||||
|
};
|
||||||
|
|
||||||
|
static const unsigned char altRamStringDescriptor[] = {
|
||||||
|
USBStringDescriptor_LENGTH(3),
|
||||||
|
USBGenericDescriptor_STRING,
|
||||||
|
USBStringDescriptor_UNICODE('R'),
|
||||||
|
USBStringDescriptor_UNICODE('A'),
|
||||||
|
USBStringDescriptor_UNICODE('M'),
|
||||||
|
};
|
||||||
|
|
||||||
|
static const unsigned char altAppStringDescriptor[] = {
|
||||||
|
USBStringDescriptor_LENGTH(11),
|
||||||
|
USBGenericDescriptor_STRING,
|
||||||
|
USBStringDescriptor_UNICODE('F'),
|
||||||
|
USBStringDescriptor_UNICODE('l'),
|
||||||
|
USBStringDescriptor_UNICODE('a'),
|
||||||
|
USBStringDescriptor_UNICODE('s'),
|
||||||
|
USBStringDescriptor_UNICODE('h'),
|
||||||
|
USBStringDescriptor_UNICODE(' '),
|
||||||
|
USBStringDescriptor_UNICODE('('),
|
||||||
|
USBStringDescriptor_UNICODE('A'),
|
||||||
|
USBStringDescriptor_UNICODE('p'),
|
||||||
|
USBStringDescriptor_UNICODE('p'),
|
||||||
|
USBStringDescriptor_UNICODE(')'),
|
||||||
|
};
|
||||||
|
|
||||||
|
/** List of string descriptors used by the device */
|
||||||
|
static const unsigned char *usb_strings[] = {
|
||||||
|
langDesc,
|
||||||
|
[STR_MANUF] = manufStringDescriptor,
|
||||||
|
[STR_PROD] = productStringDescriptor,
|
||||||
|
[STR_CONFIG] = configStringDescriptor,
|
||||||
|
[_STR_FIRST_ALT] = altRamStringDescriptor,
|
||||||
|
[_STR_FIRST_ALT+1] = altAppStringDescriptor,
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static const USBConfigurationDescriptor *conf_desc_arr[] = {
|
||||||
|
&dfu_cfg_descriptor.ucfg,
|
||||||
|
};
|
||||||
|
|
||||||
|
const USBDDriverDescriptors dfu_descriptors = {
|
||||||
|
.pFsDevice = &fsDevice,
|
||||||
|
.pFsConfiguration = (const USBConfigurationDescriptor **)&conf_desc_arr,
|
||||||
|
/* DFU only supports FS for now */
|
||||||
|
.pFsQualifier = NULL,
|
||||||
|
.pFsOtherSpeed = NULL,
|
||||||
|
.pHsDevice = NULL,
|
||||||
|
.pHsConfiguration = NULL,
|
||||||
|
.pHsQualifier = NULL,
|
||||||
|
.pHsOtherSpeed = NULL,
|
||||||
|
.pStrings = usb_strings,
|
||||||
|
.numStrings = ARRAY_SIZE(usb_strings),
|
||||||
|
};
|
||||||
478
firmware/atmel_softpack_libraries/usb/device/dfu/dfu_driver.c
Normal file
478
firmware/atmel_softpack_libraries/usb/device/dfu/dfu_driver.c
Normal file
@@ -0,0 +1,478 @@
|
|||||||
|
/* USB Device Firmware Update Implementation for OpenPCD, OpenPICC SIMtrace
|
||||||
|
* (C) 2006-2017 by Harald Welte <hwelte@hmw-consulting.de>
|
||||||
|
*
|
||||||
|
* This ought to be compliant to the USB DFU Spec 1.0 as available from
|
||||||
|
* http://www.usb.org/developers/devclass_docs/usbdfu10.pdf
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include <board.h>
|
||||||
|
#include <core_cm3.h>
|
||||||
|
|
||||||
|
#include "trace.h"
|
||||||
|
|
||||||
|
#include <usb/include/USBDescriptors.h>
|
||||||
|
#include <usb/include/USBRequests.h>
|
||||||
|
#include <usb/include/USBD.h>
|
||||||
|
#include <usb/common/dfu/usb_dfu.h>
|
||||||
|
#include <usb/device/dfu/dfu.h>
|
||||||
|
|
||||||
|
/* FIXME: this was used for a special ELF section which then got called
|
||||||
|
* by DFU code and Application code, across flash partitions */
|
||||||
|
#define __dfudata __attribute__ ((section (".dfudata")))
|
||||||
|
#define __dfufunc
|
||||||
|
|
||||||
|
/// Standard device driver instance.
|
||||||
|
static USBDDriver usbdDriver;
|
||||||
|
static unsigned char if_altsettings[1];
|
||||||
|
|
||||||
|
__dfudata struct dfudata _g_dfu = {
|
||||||
|
.state = DFU_STATE_appIDLE,
|
||||||
|
.past_manifest = 0,
|
||||||
|
.total_bytes = 0,
|
||||||
|
};
|
||||||
|
struct dfudata *g_dfu = &_g_dfu;
|
||||||
|
|
||||||
|
WEAK void dfu_drv_updstatus(void)
|
||||||
|
{
|
||||||
|
TRACE_INFO("DFU: updstatus()\n\r");
|
||||||
|
|
||||||
|
/* we transition immediately from MANIFEST_SYNC to MANIFEST,
|
||||||
|
* as the flash-writing is not asynchronous in this
|
||||||
|
* implementation */
|
||||||
|
if (g_dfu->state == DFU_STATE_dfuMANIFEST_SYNC)
|
||||||
|
g_dfu->state = DFU_STATE_dfuMANIFEST;
|
||||||
|
}
|
||||||
|
|
||||||
|
static __dfufunc void handle_getstatus(void)
|
||||||
|
{
|
||||||
|
/* has to be static as USBD_Write is async ? */
|
||||||
|
static struct dfu_status dstat;
|
||||||
|
static const uint8_t poll_timeout_10ms[] = { 10, 0, 0 };
|
||||||
|
|
||||||
|
dfu_drv_updstatus();
|
||||||
|
|
||||||
|
/* send status response */
|
||||||
|
dstat.bStatus = g_dfu->status;
|
||||||
|
dstat.bState = g_dfu->state;
|
||||||
|
dstat.iString = 0;
|
||||||
|
memcpy(&dstat.bwPollTimeout, poll_timeout_10ms, sizeof(dstat.bwPollTimeout));
|
||||||
|
|
||||||
|
TRACE_DEBUG("handle_getstatus(%u, %u)\n\r", dstat.bStatus, dstat.bState);
|
||||||
|
|
||||||
|
USBD_Write(0, (char *)&dstat, sizeof(dstat), NULL, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __dfufunc handle_getstate(void)
|
||||||
|
{
|
||||||
|
uint8_t u8 = g_dfu->state;
|
||||||
|
|
||||||
|
TRACE_DEBUG("handle_getstate(%u)\n\r", g_dfu->state);
|
||||||
|
|
||||||
|
USBD_Write(0, (char *)&u8, sizeof(u8), NULL, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void TerminateCtrlInWithNull(void *pArg,
|
||||||
|
unsigned char status,
|
||||||
|
unsigned long int transferred,
|
||||||
|
unsigned long int remaining)
|
||||||
|
{
|
||||||
|
USBD_Write(0, // Endpoint #0
|
||||||
|
0, // No data buffer
|
||||||
|
0, // No data buffer
|
||||||
|
(TransferCallback) 0,
|
||||||
|
(void *) 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint8_t dfu_buf[BOARD_DFU_PAGE_SIZE];
|
||||||
|
|
||||||
|
/* download of a single page has completed */
|
||||||
|
static void dnload_cb(void *arg, unsigned char status, unsigned long int transferred,
|
||||||
|
unsigned long int remaining)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
TRACE_DEBUG("COMPLETE\n\r");
|
||||||
|
|
||||||
|
if (status != USBD_STATUS_SUCCESS) {
|
||||||
|
TRACE_ERROR("USBD download callback status %d\n\r", status);
|
||||||
|
USBD_Stall(0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = USBDFU_handle_dnload(if_altsettings[0], g_dfu->total_bytes, dfu_buf, transferred);
|
||||||
|
switch (rc) {
|
||||||
|
case DFU_RET_ZLP:
|
||||||
|
g_dfu->total_bytes += transferred;
|
||||||
|
g_dfu->state = DFU_STATE_dfuDNLOAD_IDLE;
|
||||||
|
TerminateCtrlInWithNull(0,0,0,0);
|
||||||
|
break;
|
||||||
|
case DFU_RET_STALL:
|
||||||
|
g_dfu->state = DFU_STATE_dfuERROR;
|
||||||
|
USBD_Stall(0);
|
||||||
|
break;
|
||||||
|
case DFU_RET_NOTHING:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static int handle_dnload(uint16_t val, uint16_t len, int first)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
if (len > BOARD_DFU_PAGE_SIZE) {
|
||||||
|
TRACE_ERROR("DFU length exceeds flash page size\n\r");
|
||||||
|
g_dfu->state = DFU_STATE_dfuERROR;
|
||||||
|
g_dfu->status = DFU_STATUS_errADDRESS;
|
||||||
|
return DFU_RET_STALL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (len & 0x03) {
|
||||||
|
TRACE_ERROR("DFU length not four-byte-aligned\n\r");
|
||||||
|
g_dfu->state = DFU_STATE_dfuERROR;
|
||||||
|
g_dfu->status = DFU_STATUS_errADDRESS;
|
||||||
|
return DFU_RET_STALL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (first)
|
||||||
|
g_dfu->total_bytes = 0;
|
||||||
|
|
||||||
|
if (len == 0) {
|
||||||
|
TRACE_DEBUG("zero-size write -> MANIFEST_SYNC\n\r");
|
||||||
|
g_dfu->state = DFU_STATE_dfuMANIFEST_SYNC;
|
||||||
|
return DFU_RET_ZLP;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* else: actually read data */
|
||||||
|
rc = USBD_Read(0, dfu_buf, len, &dnload_cb, 0);
|
||||||
|
if (rc == USBD_STATUS_SUCCESS)
|
||||||
|
return DFU_RET_NOTHING;
|
||||||
|
else
|
||||||
|
return DFU_RET_STALL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* upload of a single page has completed */
|
||||||
|
static void upload_cb(void *arg, unsigned char status, unsigned long int transferred,
|
||||||
|
unsigned long int remaining)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
TRACE_DEBUG("COMPLETE\n\r");
|
||||||
|
|
||||||
|
if (status != USBD_STATUS_SUCCESS) {
|
||||||
|
TRACE_ERROR("USBD upload callback status %d\n\r", status);
|
||||||
|
USBD_Stall(0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_dfu->total_bytes += transferred;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int handle_upload(uint16_t val, uint16_t len, int first)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
if (first)
|
||||||
|
g_dfu->total_bytes = 0;
|
||||||
|
|
||||||
|
if (len > BOARD_DFU_PAGE_SIZE) {
|
||||||
|
TRACE_ERROR("DFU length exceeds flash page size\n\r");
|
||||||
|
g_dfu->state = DFU_STATE_dfuERROR;
|
||||||
|
g_dfu->status = DFU_STATUS_errADDRESS;
|
||||||
|
return DFU_RET_STALL;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = USBDFU_handle_upload(if_altsettings[0], g_dfu->total_bytes, dfu_buf, len);
|
||||||
|
if (rc < 0) {
|
||||||
|
TRACE_ERROR("application handle_upload() returned %d\n\r", rc);
|
||||||
|
return DFU_RET_STALL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (USBD_Write(0, dfu_buf, rc, &upload_cb, 0) == USBD_STATUS_SUCCESS)
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
return DFU_RET_STALL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* this function gets daisy-chained into processing EP0 requests */
|
||||||
|
void USBDFU_DFU_RequestHandler(const USBGenericRequest *request)
|
||||||
|
{
|
||||||
|
uint8_t req = USBGenericRequest_GetRequest(request);
|
||||||
|
uint16_t len = USBGenericRequest_GetLength(request);
|
||||||
|
uint16_t val = USBGenericRequest_GetValue(request);
|
||||||
|
int rc, ret;
|
||||||
|
|
||||||
|
TRACE_DEBUG("type=0x%x, recipient=0x%x val=0x%x len=%u\n\r",
|
||||||
|
USBGenericRequest_GetType(request),
|
||||||
|
USBGenericRequest_GetRecipient(request),
|
||||||
|
val, len);
|
||||||
|
|
||||||
|
/* check for GET_DESCRIPTOR on DFU */
|
||||||
|
if (USBGenericRequest_GetType(request) == USBGenericRequest_STANDARD &&
|
||||||
|
USBGenericRequest_GetRecipient(request) == USBGenericRequest_DEVICE &&
|
||||||
|
USBGenericRequest_GetRequest(request) == USBGenericRequest_GETDESCRIPTOR &&
|
||||||
|
USBGetDescriptorRequest_GetDescriptorType(request) == USB_DT_DFU) {
|
||||||
|
uint16_t length = sizeof(struct usb_dfu_func_descriptor);
|
||||||
|
const USBDeviceDescriptor *pDevice;
|
||||||
|
int terminateWithNull;
|
||||||
|
|
||||||
|
if (USBD_IsHighSpeed())
|
||||||
|
pDevice = usbdDriver.pDescriptors->pHsDevice;
|
||||||
|
else
|
||||||
|
pDevice = usbdDriver.pDescriptors->pFsDevice;
|
||||||
|
|
||||||
|
terminateWithNull = ((length % pDevice->bMaxPacketSize0) == 0);
|
||||||
|
USBD_Write(0, &dfu_cfg_descriptor.func_dfu, length,
|
||||||
|
terminateWithNull ? TerminateCtrlInWithNull : 0, 0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* forward all non-DFU specific messages to core handler*/
|
||||||
|
if (USBGenericRequest_GetType(request) != USBGenericRequest_CLASS ||
|
||||||
|
USBGenericRequest_GetRecipient(request) != USBGenericRequest_INTERFACE) {
|
||||||
|
TRACE_DEBUG("std_ho_usbd ");
|
||||||
|
USBDDriver_RequestHandler(&usbdDriver, request);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (g_dfu->state) {
|
||||||
|
case DFU_STATE_appIDLE:
|
||||||
|
case DFU_STATE_appDETACH:
|
||||||
|
TRACE_ERROR("Invalid DFU State reached in DFU mode\r\n");
|
||||||
|
ret = DFU_RET_STALL;
|
||||||
|
break;
|
||||||
|
case DFU_STATE_dfuIDLE:
|
||||||
|
switch (req) {
|
||||||
|
case USB_REQ_DFU_DNLOAD:
|
||||||
|
if (len == 0) {
|
||||||
|
g_dfu->state = DFU_STATE_dfuERROR;
|
||||||
|
ret = DFU_RET_STALL;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
g_dfu->state = DFU_STATE_dfuDNLOAD_SYNC;
|
||||||
|
ret = handle_dnload(val, len, 1);
|
||||||
|
break;
|
||||||
|
case USB_REQ_DFU_UPLOAD:
|
||||||
|
g_dfu->state = DFU_STATE_dfuUPLOAD_IDLE;
|
||||||
|
handle_upload(val, len, 1);
|
||||||
|
break;
|
||||||
|
case USB_REQ_DFU_ABORT:
|
||||||
|
/* no zlp? */
|
||||||
|
ret = DFU_RET_ZLP;
|
||||||
|
break;
|
||||||
|
case USB_REQ_DFU_GETSTATUS:
|
||||||
|
handle_getstatus();
|
||||||
|
break;
|
||||||
|
case USB_REQ_DFU_GETSTATE:
|
||||||
|
handle_getstate();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
g_dfu->state = DFU_STATE_dfuERROR;
|
||||||
|
ret = DFU_RET_STALL;
|
||||||
|
goto out;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case DFU_STATE_dfuDNLOAD_SYNC:
|
||||||
|
switch (req) {
|
||||||
|
case USB_REQ_DFU_GETSTATUS:
|
||||||
|
handle_getstatus();
|
||||||
|
/* FIXME: state transition depending on block completeness */
|
||||||
|
break;
|
||||||
|
case USB_REQ_DFU_GETSTATE:
|
||||||
|
handle_getstate();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
g_dfu->state = DFU_STATE_dfuERROR;
|
||||||
|
ret = DFU_RET_STALL;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case DFU_STATE_dfuDNBUSY:
|
||||||
|
switch (req) {
|
||||||
|
case USB_REQ_DFU_GETSTATUS:
|
||||||
|
/* FIXME: only accept getstatus if bwPollTimeout
|
||||||
|
* has elapsed */
|
||||||
|
handle_getstatus();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
g_dfu->state = DFU_STATE_dfuERROR;
|
||||||
|
ret = DFU_RET_STALL;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case DFU_STATE_dfuDNLOAD_IDLE:
|
||||||
|
switch (req) {
|
||||||
|
case USB_REQ_DFU_DNLOAD:
|
||||||
|
g_dfu->state = DFU_STATE_dfuDNLOAD_SYNC;
|
||||||
|
ret = handle_dnload(val, len, 0);
|
||||||
|
break;
|
||||||
|
case USB_REQ_DFU_ABORT:
|
||||||
|
g_dfu->state = DFU_STATE_dfuIDLE;
|
||||||
|
ret = DFU_RET_ZLP;
|
||||||
|
break;
|
||||||
|
case USB_REQ_DFU_GETSTATUS:
|
||||||
|
handle_getstatus();
|
||||||
|
break;
|
||||||
|
case USB_REQ_DFU_GETSTATE:
|
||||||
|
handle_getstate();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
g_dfu->state = DFU_STATE_dfuERROR;
|
||||||
|
ret = DFU_RET_STALL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case DFU_STATE_dfuMANIFEST_SYNC:
|
||||||
|
switch (req) {
|
||||||
|
case USB_REQ_DFU_GETSTATUS:
|
||||||
|
handle_getstatus();
|
||||||
|
break;
|
||||||
|
case USB_REQ_DFU_GETSTATE:
|
||||||
|
handle_getstate();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
g_dfu->state = DFU_STATE_dfuERROR;
|
||||||
|
ret = DFU_RET_STALL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case DFU_STATE_dfuMANIFEST:
|
||||||
|
switch (req) {
|
||||||
|
case USB_REQ_DFU_GETSTATUS:
|
||||||
|
/* we don't want to change to WAIT_RST, as it
|
||||||
|
* would mean that we can not support another
|
||||||
|
* DFU transaction before doing the actual
|
||||||
|
* reset. Instead, we switch to idle and note
|
||||||
|
* that we've already been through MANIFST in
|
||||||
|
* the global variable 'past_manifest'.
|
||||||
|
*/
|
||||||
|
//g_dfu->state = DFU_STATE_dfuMANIFEST_WAIT_RST;
|
||||||
|
g_dfu->state = DFU_STATE_dfuIDLE;
|
||||||
|
g_dfu->past_manifest = 1;
|
||||||
|
handle_getstatus();
|
||||||
|
break;
|
||||||
|
case USB_REQ_DFU_GETSTATE:
|
||||||
|
handle_getstate();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
g_dfu->state = DFU_STATE_dfuERROR;
|
||||||
|
ret = DFU_RET_STALL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case DFU_STATE_dfuMANIFEST_WAIT_RST:
|
||||||
|
/* we should never go here */
|
||||||
|
break;
|
||||||
|
case DFU_STATE_dfuUPLOAD_IDLE:
|
||||||
|
switch (req) {
|
||||||
|
case USB_REQ_DFU_UPLOAD:
|
||||||
|
/* state transition if less data then requested */
|
||||||
|
rc = handle_upload(val, len, 0);
|
||||||
|
if (rc >= 0 && rc < len)
|
||||||
|
g_dfu->state = DFU_STATE_dfuIDLE;
|
||||||
|
break;
|
||||||
|
case USB_REQ_DFU_ABORT:
|
||||||
|
g_dfu->state = DFU_STATE_dfuIDLE;
|
||||||
|
/* no zlp? */
|
||||||
|
ret = DFU_RET_ZLP;
|
||||||
|
break;
|
||||||
|
case USB_REQ_DFU_GETSTATUS:
|
||||||
|
handle_getstatus();
|
||||||
|
break;
|
||||||
|
case USB_REQ_DFU_GETSTATE:
|
||||||
|
handle_getstate();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
g_dfu->state = DFU_STATE_dfuERROR;
|
||||||
|
ret = DFU_RET_STALL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case DFU_STATE_dfuERROR:
|
||||||
|
switch (req) {
|
||||||
|
case USB_REQ_DFU_GETSTATUS:
|
||||||
|
handle_getstatus();
|
||||||
|
break;
|
||||||
|
case USB_REQ_DFU_GETSTATE:
|
||||||
|
handle_getstate();
|
||||||
|
break;
|
||||||
|
case USB_REQ_DFU_CLRSTATUS:
|
||||||
|
g_dfu->state = DFU_STATE_dfuIDLE;
|
||||||
|
g_dfu->status = DFU_STATUS_OK;
|
||||||
|
/* no zlp? */
|
||||||
|
ret = DFU_RET_ZLP;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
g_dfu->state = DFU_STATE_dfuERROR;
|
||||||
|
ret = DFU_RET_STALL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
switch (ret) {
|
||||||
|
case DFU_RET_NOTHING:
|
||||||
|
break;
|
||||||
|
case DFU_RET_ZLP:
|
||||||
|
USBD_Write(0, 0, 0, 0, 0);
|
||||||
|
break;
|
||||||
|
case DFU_RET_STALL:
|
||||||
|
USBD_Stall(0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* we assume the caller has enabled the required clock/PLL for USB */
|
||||||
|
void USBDFU_Initialize(const USBDDriverDescriptors *pDescriptors)
|
||||||
|
{
|
||||||
|
/* We already start in DFU idle mode */
|
||||||
|
g_dfu->state = DFU_STATE_dfuIDLE;
|
||||||
|
|
||||||
|
USBDDriver_Initialize(&usbdDriver, pDescriptors, if_altsettings);
|
||||||
|
USBD_Init();
|
||||||
|
USBD_Connect();
|
||||||
|
//USBD_ConfigureSpeed(1);
|
||||||
|
|
||||||
|
NVIC_EnableIRQ(UDP_IRQn);
|
||||||
|
}
|
||||||
|
|
||||||
|
void USBDFU_SwitchToApp(void)
|
||||||
|
{
|
||||||
|
/* make sure the MAGIC is not set to enter DFU again */
|
||||||
|
g_dfu->magic = 0;
|
||||||
|
|
||||||
|
printf("switching to app\r\n");
|
||||||
|
|
||||||
|
/* disconnect from USB to ensure re-enumeration */
|
||||||
|
USBD_Disconnect();
|
||||||
|
|
||||||
|
/* disable any interrupts during transition */
|
||||||
|
__disable_irq();
|
||||||
|
|
||||||
|
/* Tell the hybrid to execute FTL JUMP! */
|
||||||
|
NVIC_SystemReset();
|
||||||
|
}
|
||||||
|
|
||||||
|
void USBDCallbacks_RequestReceived(const USBGenericRequest *request)
|
||||||
|
{
|
||||||
|
USBDFU_DFU_RequestHandler(request);
|
||||||
|
}
|
||||||
200
firmware/atmel_softpack_libraries/usb/device/dfu/dfu_runtime.c
Normal file
200
firmware/atmel_softpack_libraries/usb/device/dfu/dfu_runtime.c
Normal file
@@ -0,0 +1,200 @@
|
|||||||
|
/* DFU related functions that are active at runtime, i.e. during the
|
||||||
|
* normal operation of the device firmware, *not* during DFU update mode
|
||||||
|
* (C) 2006 Harald Welte <hwelte@hmw-consulting.de>
|
||||||
|
*
|
||||||
|
* This ought to be compliant to the USB DFU Spec 1.0 as available from
|
||||||
|
* http://www.usb.org/developers/devclass_docs/usbdfu10.pdf
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <board.h>
|
||||||
|
#include <core_cm3.h>
|
||||||
|
|
||||||
|
#include <usb/include/USBD.h>
|
||||||
|
#include <usb/device/dfu/dfu.h>
|
||||||
|
|
||||||
|
#include "trace.h"
|
||||||
|
|
||||||
|
#include <usb/include/USBDescriptors.h>
|
||||||
|
#include <usb/include/USBRequests.h>
|
||||||
|
#include <usb/include/USBD.h>
|
||||||
|
#include <usb/common/dfu/usb_dfu.h>
|
||||||
|
#include <usb/device/dfu/dfu.h>
|
||||||
|
|
||||||
|
struct dfudata *g_dfu = (struct dfudata *) IRAM_ADDR;
|
||||||
|
|
||||||
|
/* FIXME: this was used for a special ELF section which then got called
|
||||||
|
* by DFU code and Application code, across flash partitions */
|
||||||
|
#define __dfufunc
|
||||||
|
|
||||||
|
static __dfufunc void handle_getstatus(void)
|
||||||
|
{
|
||||||
|
/* has to be static as USBD_Write is async ? */
|
||||||
|
static struct dfu_status dstat;
|
||||||
|
static const uint8_t poll_timeout_10ms[] = { 10, 0, 0 };
|
||||||
|
|
||||||
|
/* send status response */
|
||||||
|
dstat.bStatus = g_dfu->status;
|
||||||
|
dstat.bState = g_dfu->state;
|
||||||
|
dstat.iString = 0;
|
||||||
|
memcpy(&dstat.bwPollTimeout, poll_timeout_10ms, sizeof(dstat.bwPollTimeout));
|
||||||
|
|
||||||
|
TRACE_DEBUG("handle_getstatus(%u, %u)\n\r", dstat.bStatus, dstat.bState);
|
||||||
|
|
||||||
|
USBD_Write(0, (char *)&dstat, sizeof(dstat), NULL, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __dfufunc handle_getstate(void)
|
||||||
|
{
|
||||||
|
uint8_t u8 = g_dfu->state;
|
||||||
|
|
||||||
|
TRACE_DEBUG("handle_getstate(%u)\n\r", g_dfu->state);
|
||||||
|
|
||||||
|
USBD_Write(0, (char *)&u8, sizeof(u8), NULL, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void TerminateCtrlInWithNull(void *pArg,
|
||||||
|
unsigned char status,
|
||||||
|
unsigned long int transferred,
|
||||||
|
unsigned long int remaining)
|
||||||
|
{
|
||||||
|
USBD_Write(0, // Endpoint #0
|
||||||
|
0, // No data buffer
|
||||||
|
0, // No data buffer
|
||||||
|
(TransferCallback) 0,
|
||||||
|
(void *) 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* this function gets daisy-chained into processing EP0 requests */
|
||||||
|
void USBDFU_Runtime_RequestHandler(const USBGenericRequest *request)
|
||||||
|
{
|
||||||
|
USBDDriver *usbdDriver = USBD_GetDriver();
|
||||||
|
uint8_t req = USBGenericRequest_GetRequest(request);
|
||||||
|
uint16_t len = USBGenericRequest_GetLength(request);
|
||||||
|
uint16_t val = USBGenericRequest_GetValue(request);
|
||||||
|
int rc, ret;
|
||||||
|
|
||||||
|
TRACE_DEBUG("type=0x%x, recipient=0x%x val=0x%x len=%u\n\r",
|
||||||
|
USBGenericRequest_GetType(request),
|
||||||
|
USBGenericRequest_GetRecipient(request),
|
||||||
|
val, len);
|
||||||
|
|
||||||
|
/* check for GET_DESCRIPTOR on DFU */
|
||||||
|
if (USBGenericRequest_GetType(request) == USBGenericRequest_STANDARD &&
|
||||||
|
USBGenericRequest_GetRecipient(request) == USBGenericRequest_DEVICE &&
|
||||||
|
USBGenericRequest_GetRequest(request) == USBGenericRequest_GETDESCRIPTOR &&
|
||||||
|
USBGetDescriptorRequest_GetDescriptorType(request) == USB_DT_DFU) {
|
||||||
|
uint16_t length = sizeof(struct usb_dfu_func_descriptor);
|
||||||
|
const USBDeviceDescriptor *pDevice;
|
||||||
|
int terminateWithNull;
|
||||||
|
|
||||||
|
if (USBD_IsHighSpeed())
|
||||||
|
pDevice = usbdDriver->pDescriptors->pHsDevice;
|
||||||
|
else
|
||||||
|
pDevice = usbdDriver->pDescriptors->pFsDevice;
|
||||||
|
|
||||||
|
terminateWithNull = ((length % pDevice->bMaxPacketSize0) == 0);
|
||||||
|
USBD_Write(0, &dfu_cfg_descriptor.func_dfu, length,
|
||||||
|
terminateWithNull ? TerminateCtrlInWithNull : 0, 0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* forward all non-DFU specific messages to core handler*/
|
||||||
|
if (USBGenericRequest_GetType(request) != USBGenericRequest_CLASS ||
|
||||||
|
USBGenericRequest_GetRecipient(request) != USBGenericRequest_INTERFACE) {
|
||||||
|
TRACE_DEBUG("std_ho_usbd ");
|
||||||
|
USBDDriver_RequestHandler(usbdDriver, request);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (g_dfu->state) {
|
||||||
|
case DFU_STATE_appIDLE:
|
||||||
|
switch (req) {
|
||||||
|
case USB_REQ_DFU_GETSTATUS:
|
||||||
|
handle_getstatus();
|
||||||
|
break;
|
||||||
|
case USB_REQ_DFU_GETSTATE:
|
||||||
|
handle_getstate();
|
||||||
|
break;
|
||||||
|
case USB_REQ_DFU_DETACH:
|
||||||
|
/* we switch it DETACH state, send a ZLP and
|
||||||
|
* return. The next USB reset in this state
|
||||||
|
* will then trigger DFURT_SwitchToDFU() below */
|
||||||
|
TRACE_DEBUG("\r\n====dfu_detach\n\r");
|
||||||
|
g_dfu->state = DFU_STATE_appDETACH;
|
||||||
|
ret = DFU_RET_ZLP;
|
||||||
|
goto out;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ret = DFU_RET_STALL;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case DFU_STATE_appDETACH:
|
||||||
|
switch (req) {
|
||||||
|
case USB_REQ_DFU_GETSTATUS:
|
||||||
|
handle_getstatus();
|
||||||
|
break;
|
||||||
|
case USB_REQ_DFU_GETSTATE:
|
||||||
|
handle_getstate();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
g_dfu->state = DFU_STATE_appIDLE;
|
||||||
|
ret = DFU_RET_STALL;
|
||||||
|
goto out;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* FIXME: implement timer to return to appIDLE */
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
TRACE_ERROR("Invalid DFU State reached in Runtime Mode\r\n");
|
||||||
|
ret = DFU_RET_STALL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
switch (ret) {
|
||||||
|
case DFU_RET_NOTHING:
|
||||||
|
break;
|
||||||
|
case DFU_RET_ZLP:
|
||||||
|
USBD_Write(0, 0, 0, 0, 0);
|
||||||
|
break;
|
||||||
|
case DFU_RET_STALL:
|
||||||
|
USBD_Stall(0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DFURT_SwitchToDFU(void)
|
||||||
|
{
|
||||||
|
/* store the magic value that the DFU loader can detect and
|
||||||
|
* activate itself, rather than boot into the application */
|
||||||
|
g_dfu->magic = USB_DFU_MAGIC;
|
||||||
|
|
||||||
|
/* Disconnect the USB by remoting the pull-up */
|
||||||
|
USBD_Disconnect();
|
||||||
|
__disable_irq();
|
||||||
|
|
||||||
|
/* reset the processor, we will start execution with the
|
||||||
|
* ResetVector of the bootloader */
|
||||||
|
NVIC_SystemReset();
|
||||||
|
}
|
||||||
|
|
||||||
|
void USBDCallbacks_RequestReceived(const USBGenericRequest *request)
|
||||||
|
{
|
||||||
|
/* FIXME: integration with CCID control point reqeusts */
|
||||||
|
USBDFU_Runtime_RequestHandler(request);
|
||||||
|
}
|
||||||
122
firmware/libboard/common/include/board_common.h
Normal file
122
firmware/libboard/common/include/board_common.h
Normal file
@@ -0,0 +1,122 @@
|
|||||||
|
#ifndef _BOARD_
|
||||||
|
#define _BOARD_
|
||||||
|
|
||||||
|
/** Headers */
|
||||||
|
#include "chip.h"
|
||||||
|
/* We need this for a nop instruction in USB_HAL.c */
|
||||||
|
#define __CC_ARM
|
||||||
|
|
||||||
|
/** Board */
|
||||||
|
#include "board_lowlevel.h"
|
||||||
|
#include "uart_console.h"
|
||||||
|
#include "iso7816_4.h"
|
||||||
|
#include "led.h"
|
||||||
|
#include "cciddriver.h"
|
||||||
|
#include "usart.h"
|
||||||
|
#include "USBD.h"
|
||||||
|
|
||||||
|
#include "USBD_Config.h"
|
||||||
|
#include "USBDDriver.h"
|
||||||
|
|
||||||
|
/** Highlevel */
|
||||||
|
#include "trace.h"
|
||||||
|
#include "stdio.h"
|
||||||
|
#include "stdlib.h"
|
||||||
|
#include "string.h"
|
||||||
|
#include "inttypes.h"
|
||||||
|
#include "syscalls.h"
|
||||||
|
|
||||||
|
#define MIN(a, b) ((a < b) ? a : b)
|
||||||
|
|
||||||
|
#ifdef __GNUC__
|
||||||
|
#undef __GNUC__
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** Family definition (already defined) */
|
||||||
|
#define sam3s
|
||||||
|
/** Core definition */
|
||||||
|
#define cortexm3
|
||||||
|
|
||||||
|
#define BOARD_MCK 48000000
|
||||||
|
|
||||||
|
#define LED_RED PIO_PA17
|
||||||
|
#define LED_GREEN PIO_PA18
|
||||||
|
|
||||||
|
#define PIN_LED_RED {LED_RED, PIOA, ID_PIOA, PIO_OUTPUT_1, PIO_DEFAULT}
|
||||||
|
#define PIN_LED_GREEN {LED_GREEN, PIOA, ID_PIOA, PIO_OUTPUT_1, PIO_DEFAULT}
|
||||||
|
#define PINS_LEDS PIN_LED_RED, PIN_LED_GREEN
|
||||||
|
|
||||||
|
#define LED_NUM_RED 0
|
||||||
|
#define LED_NUM_GREEN 1
|
||||||
|
|
||||||
|
/** USART0 pin RX */
|
||||||
|
#define PIN_USART0_RXD {PIO_PA9A_URXD0, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
|
||||||
|
/** USART0 pin TX */
|
||||||
|
#define PIN_USART0_TXD {PIO_PA10A_UTXD0, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
|
||||||
|
|
||||||
|
#define BOARD_PIN_USART_RXD PIN_USART0_RXD
|
||||||
|
#define BOARD_PIN_USART_TXD PIN_USART0_TXD
|
||||||
|
|
||||||
|
#define BOARD_ID_USART ID_USART0
|
||||||
|
#define BOARD_USART_BASE USART0
|
||||||
|
|
||||||
|
#define PINS_UART { PIO_PA9A_URXD0|PIO_PA10A_UTXD0, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
|
||||||
|
|
||||||
|
/** UART0 */
|
||||||
|
/** Console baudrate always using 115200. */
|
||||||
|
#define CONSOLE_BAUDRATE 115200
|
||||||
|
/** Usart Hw interface used by the console (UART0). */
|
||||||
|
#define CONSOLE_USART UART0
|
||||||
|
/** Usart Hw ID used by the console (UART0). */
|
||||||
|
#define CONSOLE_ID ID_UART0
|
||||||
|
/** Pins description corresponding to Rxd,Txd, (UART pins) */
|
||||||
|
#define CONSOLE_PINS {PINS_UART}
|
||||||
|
|
||||||
|
/// Smartcard detection pin
|
||||||
|
// FIXME: add connect pin as iso pin...should it be periph b or interrupt oder input?
|
||||||
|
#define BOARD_ISO7816_BASE_USART USART0
|
||||||
|
#define BOARD_ISO7816_ID_USART ID_USART0
|
||||||
|
|
||||||
|
#define USART_SIM USART0
|
||||||
|
#define ID_USART_SIM ID_USART0
|
||||||
|
#define USART_PHONE USART1
|
||||||
|
#define ID_USART_PHONE ID_USART1
|
||||||
|
|
||||||
|
#define SIM_PWEN PIO_PA5
|
||||||
|
#define VCC_FWD PIO_PA26
|
||||||
|
|
||||||
|
|
||||||
|
//** USB **/
|
||||||
|
// USB pull-up control pin definition (PA16).
|
||||||
|
// Default: 1 (USB Pullup deactivated)
|
||||||
|
#define PIN_USB_PULLUP {1 << 16, PIOA, ID_PIOA, PIO_OUTPUT_1, PIO_DEFAULT}
|
||||||
|
|
||||||
|
// Board has UDP controller
|
||||||
|
#define BOARD_USB_UDP
|
||||||
|
// D+ has external pull-up
|
||||||
|
#define BOARD_USB_PULLUP_EXTERNAL
|
||||||
|
|
||||||
|
#define BOARD_USB_NUMENDPOINTS 8
|
||||||
|
|
||||||
|
// FIXME: in all other cases return 0?
|
||||||
|
#define BOARD_USB_ENDPOINTS_MAXPACKETSIZE(i) (((i == 4) || (i == 5))? 512 : 64)
|
||||||
|
#define BOARD_USB_ENDPOINTS_BANKS(i) (((i == 0) || (i == 3)) ? 1 : 2)
|
||||||
|
|
||||||
|
/// USB attributes configuration descriptor (bus or self powered, remote wakeup)
|
||||||
|
//#define BOARD_USB_BMATTRIBUTES USBConfigurationDescriptor_SELFPOWERED_NORWAKEUP
|
||||||
|
#define BOARD_USB_BMATTRIBUTES USBConfigurationDescriptor_BUSPOWERED_NORWAKEUP
|
||||||
|
//#define BOARD_USB_BMATTRIBUTES USBConfigurationDescriptor_SELFPOWERED_RWAKEUP
|
||||||
|
|
||||||
|
#define BOARD_USB_VENDOR SIMTRACE_VENDOR_ID
|
||||||
|
#define BOARD_USB_PRODUCT SIMTRACE_PRODUCT_ID
|
||||||
|
#define BOARD_USB_RELEASE 0
|
||||||
|
|
||||||
|
#define BOARD_USB_DFU
|
||||||
|
#define BOARD_DFU_BOOT_SIZE (16 * 1024)
|
||||||
|
#define BOARD_DFU_RAM_SIZE (2 * 1024)
|
||||||
|
#define BOARD_DFU_PAGE_SIZE 512
|
||||||
|
#define BOARD_DFU_NUM_IF 2
|
||||||
|
|
||||||
|
extern void board_exec_dbg_cmd(int ch);
|
||||||
|
extern void board_main_top(void);
|
||||||
|
#endif
|
||||||
3
firmware/libboard/common/include/boardver_adc.h
Normal file
3
firmware/libboard/common/include/boardver_adc.h
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
int get_board_version_adc(void);
|
||||||
10
firmware/libboard/common/include/manifest.h
Normal file
10
firmware/libboard/common/include/manifest.h
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
|
||||||
|
#ifndef _MANIFEST_H
|
||||||
|
#define _MANIFEST_H
|
||||||
|
|
||||||
|
extern const char *manifest_application;
|
||||||
|
extern const char *manifest_revision;
|
||||||
|
extern const char *manifest_board;
|
||||||
|
extern const char *manifest_environment;
|
||||||
|
|
||||||
|
#endif /* !_MANIFEST_H */
|
||||||
142
firmware/libboard/common/resources/sam3s1/flash.ld
Normal file
142
firmware/libboard/common/resources/sam3s1/flash.ld
Normal file
@@ -0,0 +1,142 @@
|
|||||||
|
/* ----------------------------------------------------------------------------
|
||||||
|
* ATMEL Microcontroller Software Support
|
||||||
|
* ----------------------------------------------------------------------------
|
||||||
|
* Copyright (c) 2009, Atmel Corporation
|
||||||
|
*
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* - Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the disclaimer below.
|
||||||
|
*
|
||||||
|
* Atmel's name may not be used to endorse or promote products derived from
|
||||||
|
* this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
|
||||||
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||||||
|
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
|
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||||
|
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
* ----------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------------
|
||||||
|
* Linker script for running in internal FLASH on the ATSAM3S1
|
||||||
|
*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
|
||||||
|
OUTPUT_ARCH(arm)
|
||||||
|
SEARCH_DIR(.)
|
||||||
|
|
||||||
|
/* Memory Spaces Definitions */
|
||||||
|
MEMORY
|
||||||
|
{
|
||||||
|
rom (rx) : ORIGIN = 0x00400000, LENGTH = 0x00010000 /* Flash, 64K */
|
||||||
|
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00004000 /* sram, 16K */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Section Definitions */
|
||||||
|
SECTIONS
|
||||||
|
{
|
||||||
|
.text :
|
||||||
|
{
|
||||||
|
. = ALIGN(4);
|
||||||
|
_sfixed = .;
|
||||||
|
KEEP(*(.vectors .vectors.*))
|
||||||
|
*(.text .text.* .gnu.linkonce.t.*)
|
||||||
|
*(.glue_7t) *(.glue_7)
|
||||||
|
*(.rodata .rodata* .gnu.linkonce.r.*)
|
||||||
|
*(.ARM.extab* .gnu.linkonce.armextab.*)
|
||||||
|
|
||||||
|
/* Support C constructors, and C destructors in both user code
|
||||||
|
and the C library. This also provides support for C++ code. */
|
||||||
|
. = ALIGN(4);
|
||||||
|
KEEP(*(.init))
|
||||||
|
. = ALIGN(4);
|
||||||
|
__preinit_array_start = .;
|
||||||
|
KEEP (*(.preinit_array))
|
||||||
|
__preinit_array_end = .;
|
||||||
|
|
||||||
|
. = ALIGN(4);
|
||||||
|
__init_array_start = .;
|
||||||
|
KEEP (*(SORT(.init_array.*)))
|
||||||
|
KEEP (*(.init_array))
|
||||||
|
__init_array_end = .;
|
||||||
|
|
||||||
|
. = ALIGN(0x4);
|
||||||
|
KEEP (*crtbegin.o(.ctors))
|
||||||
|
KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
|
||||||
|
KEEP (*(SORT(.ctors.*)))
|
||||||
|
KEEP (*crtend.o(.ctors))
|
||||||
|
|
||||||
|
. = ALIGN(4);
|
||||||
|
KEEP(*(.fini))
|
||||||
|
|
||||||
|
. = ALIGN(4);
|
||||||
|
__fini_array_start = .;
|
||||||
|
KEEP (*(.fini_array))
|
||||||
|
KEEP (*(SORT(.fini_array.*)))
|
||||||
|
__fini_array_end = .;
|
||||||
|
|
||||||
|
KEEP (*crtbegin.o(.dtors))
|
||||||
|
KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
|
||||||
|
KEEP (*(SORT(.dtors.*)))
|
||||||
|
KEEP (*crtend.o(.dtors))
|
||||||
|
|
||||||
|
. = ALIGN(4);
|
||||||
|
_efixed = .; /* End of text section */
|
||||||
|
} > rom
|
||||||
|
|
||||||
|
/* .ARM.exidx is sorted, so has to go in its own output section. */
|
||||||
|
PROVIDE_HIDDEN (__exidx_start = .);
|
||||||
|
.ARM.exidx :
|
||||||
|
{
|
||||||
|
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
|
||||||
|
} > rom
|
||||||
|
PROVIDE_HIDDEN (__exidx_end = .);
|
||||||
|
|
||||||
|
. = ALIGN(4);
|
||||||
|
_etext = .;
|
||||||
|
|
||||||
|
.relocate : AT (_etext)
|
||||||
|
{
|
||||||
|
. = ALIGN(4);
|
||||||
|
_srelocate = .;
|
||||||
|
/* we must make sure the .dfudata is linked to start of RAM */
|
||||||
|
*(.dfudata .dfudata.*);
|
||||||
|
*(.ramfunc .ramfunc.*);
|
||||||
|
*(.data .data.*);
|
||||||
|
. = ALIGN(4);
|
||||||
|
_erelocate = .;
|
||||||
|
} > ram
|
||||||
|
|
||||||
|
/* .bss section which is used for uninitialized data */
|
||||||
|
.bss (NOLOAD) :
|
||||||
|
{
|
||||||
|
. = ALIGN(4);
|
||||||
|
_sbss = . ;
|
||||||
|
_szero = .;
|
||||||
|
*(.bss .bss.*)
|
||||||
|
*(COMMON)
|
||||||
|
. = ALIGN(4);
|
||||||
|
_ebss = . ;
|
||||||
|
_ezero = .;
|
||||||
|
} > ram
|
||||||
|
|
||||||
|
/* stack section */
|
||||||
|
.stack (NOLOAD):
|
||||||
|
{
|
||||||
|
. = ALIGN(8);
|
||||||
|
*(.stack .stack.*)
|
||||||
|
} > ram
|
||||||
|
|
||||||
|
. = ALIGN(4);
|
||||||
|
_end = . ;
|
||||||
|
}
|
||||||
140
firmware/libboard/common/resources/sam3s1/sram.ld
Normal file
140
firmware/libboard/common/resources/sam3s1/sram.ld
Normal file
@@ -0,0 +1,140 @@
|
|||||||
|
/* ----------------------------------------------------------------------------
|
||||||
|
* ATMEL Microcontroller Software Support
|
||||||
|
* ----------------------------------------------------------------------------
|
||||||
|
* Copyright (c) 2009, Atmel Corporation
|
||||||
|
*
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* - Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the disclaimer below.
|
||||||
|
*
|
||||||
|
* Atmel's name may not be used to endorse or promote products derived from
|
||||||
|
* this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
|
||||||
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||||||
|
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
|
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||||
|
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
* ----------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------------
|
||||||
|
* Linker script for running in internal SRAM on the ATSAM3S1
|
||||||
|
*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
|
||||||
|
OUTPUT_ARCH(arm)
|
||||||
|
SEARCH_DIR(.)
|
||||||
|
|
||||||
|
/* Memory Spaces Definitions */
|
||||||
|
MEMORY
|
||||||
|
{
|
||||||
|
rom (rx) : ORIGIN = 0x00400000, LENGTH = 0x00010000 /* Flash, 64K */
|
||||||
|
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00004000 /* sram, 16K */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Section Definitions */
|
||||||
|
SECTIONS
|
||||||
|
{
|
||||||
|
.text :
|
||||||
|
{
|
||||||
|
. = ALIGN(4);
|
||||||
|
_sfixed = .;
|
||||||
|
KEEP(*(.vectors .vectors.*))
|
||||||
|
*(.text .text.* .gnu.linkonce.t.*)
|
||||||
|
*(.glue_7t) *(.glue_7)
|
||||||
|
*(.rodata .rodata* .gnu.linkonce.r.*)
|
||||||
|
*(.ARM.extab* .gnu.linkonce.armextab.*)
|
||||||
|
|
||||||
|
/* Support C constructors, and C destructors in both user code
|
||||||
|
and the C library. This also provides support for C++ code. */
|
||||||
|
. = ALIGN(4);
|
||||||
|
KEEP(*(.init))
|
||||||
|
. = ALIGN(4);
|
||||||
|
__preinit_array_start = .;
|
||||||
|
KEEP (*(.preinit_array))
|
||||||
|
__preinit_array_end = .;
|
||||||
|
|
||||||
|
. = ALIGN(4);
|
||||||
|
__init_array_start = .;
|
||||||
|
KEEP (*(SORT(.init_array.*)))
|
||||||
|
KEEP (*(.init_array))
|
||||||
|
__init_array_end = .;
|
||||||
|
|
||||||
|
. = ALIGN(0x4);
|
||||||
|
KEEP (*crtbegin.o(.ctors))
|
||||||
|
KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
|
||||||
|
KEEP (*(SORT(.ctors.*)))
|
||||||
|
KEEP (*crtend.o(.ctors))
|
||||||
|
|
||||||
|
. = ALIGN(4);
|
||||||
|
KEEP(*(.fini))
|
||||||
|
|
||||||
|
. = ALIGN(4);
|
||||||
|
__fini_array_start = .;
|
||||||
|
KEEP (*(.fini_array))
|
||||||
|
KEEP (*(SORT(.fini_array.*)))
|
||||||
|
__fini_array_end = .;
|
||||||
|
|
||||||
|
KEEP (*crtbegin.o(.dtors))
|
||||||
|
KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
|
||||||
|
KEEP (*(SORT(.dtors.*)))
|
||||||
|
KEEP (*crtend.o(.dtors))
|
||||||
|
|
||||||
|
. = ALIGN(4);
|
||||||
|
_efixed = .; /* End of text section */
|
||||||
|
} > ram
|
||||||
|
|
||||||
|
. = ALIGN(4);
|
||||||
|
_etext = .;
|
||||||
|
|
||||||
|
.relocate : AT (_etext)
|
||||||
|
{
|
||||||
|
. = ALIGN(4);
|
||||||
|
_srelocate = .;
|
||||||
|
*(.ramfunc .ramfunc.*);
|
||||||
|
*(.data .data.*);
|
||||||
|
. = ALIGN(4);
|
||||||
|
_erelocate = .;
|
||||||
|
} > ram
|
||||||
|
|
||||||
|
/* .bss section which is used for uninitialized data */
|
||||||
|
.bss (NOLOAD) :
|
||||||
|
{
|
||||||
|
. = ALIGN(4);
|
||||||
|
_sbss = . ;
|
||||||
|
_szero = .;
|
||||||
|
*(.bss .bss.*)
|
||||||
|
*(COMMON)
|
||||||
|
. = ALIGN(4);
|
||||||
|
_ebss = . ;
|
||||||
|
_ezero = .;
|
||||||
|
} > ram
|
||||||
|
|
||||||
|
/* stack section */
|
||||||
|
.stack (NOLOAD):
|
||||||
|
{
|
||||||
|
. = ALIGN(8);
|
||||||
|
*(.stack .stack.*)
|
||||||
|
} > ram
|
||||||
|
|
||||||
|
/* .ARM.exidx is sorted, so has to go in its own output section. */
|
||||||
|
PROVIDE_HIDDEN (__exidx_start = .);
|
||||||
|
.ARM.exidx :
|
||||||
|
{
|
||||||
|
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
|
||||||
|
} > ram
|
||||||
|
PROVIDE_HIDDEN (__exidx_end = .);
|
||||||
|
|
||||||
|
. = ALIGN(4);
|
||||||
|
_end = . ;
|
||||||
|
}
|
||||||
91
firmware/libboard/common/resources/sam3s1/sram_samba.lds
Normal file
91
firmware/libboard/common/resources/sam3s1/sram_samba.lds
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
/* ----------------------------------------------------------------------------
|
||||||
|
* ATMEL Microcontroller Software Support
|
||||||
|
* ----------------------------------------------------------------------------
|
||||||
|
* Copyright (c) 2009, Atmel Corporation
|
||||||
|
*
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* - Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the disclaimer below.
|
||||||
|
*
|
||||||
|
* Atmel's name may not be used to endorse or promote products derived from
|
||||||
|
* this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
|
||||||
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||||||
|
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
|
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||||
|
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
* ----------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------------
|
||||||
|
* Linker script for running in internal SRAM on the AT91SAM3S1
|
||||||
|
*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
|
||||||
|
OUTPUT_ARCH(arm)
|
||||||
|
ENTRY(entry)
|
||||||
|
|
||||||
|
/* Memory Spaces Definitions */
|
||||||
|
MEMORY
|
||||||
|
{
|
||||||
|
romcodesram (W!RX) : ORIGIN = 0x20000000, LENGTH = 0x0800
|
||||||
|
sram (W!RX) : ORIGIN = 0x20000800, LENGTH = 0x00003800 /* sram, 16K - sizeof(romcodesram) */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Entry point */
|
||||||
|
/*ENTRY (ResetException)*/
|
||||||
|
|
||||||
|
SECTIONS
|
||||||
|
{
|
||||||
|
/* startup code in the .isr_vector */
|
||||||
|
.text :
|
||||||
|
{
|
||||||
|
. = ALIGN(4);
|
||||||
|
_stext = .;
|
||||||
|
KEEP(*(.isr_vector .isr_vector.*))
|
||||||
|
*(.mailbox)
|
||||||
|
*(.text .text.*)
|
||||||
|
*(.rodata .rodata.*)
|
||||||
|
*(.glue_7)
|
||||||
|
*(.glue_7t)
|
||||||
|
*(.gcc_except_table)
|
||||||
|
*(.rodata .rodata*)
|
||||||
|
*(.gnu.linkonce.r.*)
|
||||||
|
. = ALIGN(4);
|
||||||
|
_etext = .;
|
||||||
|
} > sram
|
||||||
|
|
||||||
|
/* data */
|
||||||
|
.data :
|
||||||
|
{
|
||||||
|
. = ALIGN(4);
|
||||||
|
_sidata = .;
|
||||||
|
_sdata = .;
|
||||||
|
|
||||||
|
*(.data)
|
||||||
|
*(.data.*)
|
||||||
|
. = ALIGN(4);
|
||||||
|
_edata = .;
|
||||||
|
} > sram
|
||||||
|
|
||||||
|
.bss (NOLOAD) : {
|
||||||
|
_szero = .;
|
||||||
|
*(.bss)
|
||||||
|
. = ALIGN(4);
|
||||||
|
_ezero = .;
|
||||||
|
} >sram
|
||||||
|
|
||||||
|
/* Stack in SRAM */
|
||||||
|
_sstack = 0x20003FFC;
|
||||||
|
}
|
||||||
|
end = .;
|
||||||
142
firmware/libboard/common/resources/sam3s2/flash.ld
Normal file
142
firmware/libboard/common/resources/sam3s2/flash.ld
Normal file
@@ -0,0 +1,142 @@
|
|||||||
|
/* ----------------------------------------------------------------------------
|
||||||
|
* ATMEL Microcontroller Software Support
|
||||||
|
* ----------------------------------------------------------------------------
|
||||||
|
* Copyright (c) 2009, Atmel Corporation
|
||||||
|
*
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* - Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the disclaimer below.
|
||||||
|
*
|
||||||
|
* Atmel's name may not be used to endorse or promote products derived from
|
||||||
|
* this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
|
||||||
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||||||
|
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
|
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||||
|
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
* ----------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------------
|
||||||
|
* Linker script for running in internal FLASH on the ATSAM3S2
|
||||||
|
*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
|
||||||
|
OUTPUT_ARCH(arm)
|
||||||
|
SEARCH_DIR(.)
|
||||||
|
|
||||||
|
/* Memory Spaces Definitions */
|
||||||
|
MEMORY
|
||||||
|
{
|
||||||
|
rom (rx) : ORIGIN = 0x00400000, LENGTH = 0x00020000 /* flash, 128K */
|
||||||
|
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00008000 /* sram, 32K */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Section Definitions */
|
||||||
|
SECTIONS
|
||||||
|
{
|
||||||
|
.text :
|
||||||
|
{
|
||||||
|
. = ALIGN(4);
|
||||||
|
_sfixed = .;
|
||||||
|
KEEP(*(.vectors .vectors.*))
|
||||||
|
*(.text .text.* .gnu.linkonce.t.*)
|
||||||
|
*(.glue_7t) *(.glue_7)
|
||||||
|
*(.rodata .rodata* .gnu.linkonce.r.*)
|
||||||
|
*(.ARM.extab* .gnu.linkonce.armextab.*)
|
||||||
|
|
||||||
|
/* Support C constructors, and C destructors in both user code
|
||||||
|
and the C library. This also provides support for C++ code. */
|
||||||
|
. = ALIGN(4);
|
||||||
|
KEEP(*(.init))
|
||||||
|
. = ALIGN(4);
|
||||||
|
__preinit_array_start = .;
|
||||||
|
KEEP (*(.preinit_array))
|
||||||
|
__preinit_array_end = .;
|
||||||
|
|
||||||
|
. = ALIGN(4);
|
||||||
|
__init_array_start = .;
|
||||||
|
KEEP (*(SORT(.init_array.*)))
|
||||||
|
KEEP (*(.init_array))
|
||||||
|
__init_array_end = .;
|
||||||
|
|
||||||
|
. = ALIGN(0x4);
|
||||||
|
KEEP (*crtbegin.o(.ctors))
|
||||||
|
KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
|
||||||
|
KEEP (*(SORT(.ctors.*)))
|
||||||
|
KEEP (*crtend.o(.ctors))
|
||||||
|
|
||||||
|
. = ALIGN(4);
|
||||||
|
KEEP(*(.fini))
|
||||||
|
|
||||||
|
. = ALIGN(4);
|
||||||
|
__fini_array_start = .;
|
||||||
|
KEEP (*(.fini_array))
|
||||||
|
KEEP (*(SORT(.fini_array.*)))
|
||||||
|
__fini_array_end = .;
|
||||||
|
|
||||||
|
KEEP (*crtbegin.o(.dtors))
|
||||||
|
KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
|
||||||
|
KEEP (*(SORT(.dtors.*)))
|
||||||
|
KEEP (*crtend.o(.dtors))
|
||||||
|
|
||||||
|
. = ALIGN(4);
|
||||||
|
_efixed = .; /* End of text section */
|
||||||
|
} > rom
|
||||||
|
|
||||||
|
/* .ARM.exidx is sorted, so has to go in its own output section. */
|
||||||
|
PROVIDE_HIDDEN (__exidx_start = .);
|
||||||
|
.ARM.exidx :
|
||||||
|
{
|
||||||
|
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
|
||||||
|
} > rom
|
||||||
|
PROVIDE_HIDDEN (__exidx_end = .);
|
||||||
|
|
||||||
|
. = ALIGN(4);
|
||||||
|
_etext = .;
|
||||||
|
|
||||||
|
.relocate : AT (_etext)
|
||||||
|
{
|
||||||
|
. = ALIGN(4);
|
||||||
|
_srelocate = .;
|
||||||
|
/* we must make sure the .dfudata is linked to start of RAM */
|
||||||
|
*(.dfudata .dfudata.*);
|
||||||
|
*(.ramfunc .ramfunc.*);
|
||||||
|
*(.data .data.*);
|
||||||
|
. = ALIGN(4);
|
||||||
|
_erelocate = .;
|
||||||
|
} > ram
|
||||||
|
|
||||||
|
/* .bss section which is used for uninitialized data */
|
||||||
|
.bss (NOLOAD) :
|
||||||
|
{
|
||||||
|
. = ALIGN(4);
|
||||||
|
_sbss = . ;
|
||||||
|
_szero = .;
|
||||||
|
*(.bss .bss.*)
|
||||||
|
*(COMMON)
|
||||||
|
. = ALIGN(4);
|
||||||
|
_ebss = . ;
|
||||||
|
_ezero = .;
|
||||||
|
} > ram
|
||||||
|
|
||||||
|
/* stack section */
|
||||||
|
.stack (NOLOAD):
|
||||||
|
{
|
||||||
|
. = ALIGN(8);
|
||||||
|
*(.stack .stack.*)
|
||||||
|
} > ram
|
||||||
|
|
||||||
|
. = ALIGN(4);
|
||||||
|
_end = . ;
|
||||||
|
}
|
||||||
140
firmware/libboard/common/resources/sam3s2/sram.ld
Normal file
140
firmware/libboard/common/resources/sam3s2/sram.ld
Normal file
@@ -0,0 +1,140 @@
|
|||||||
|
/* ----------------------------------------------------------------------------
|
||||||
|
* ATMEL Microcontroller Software Support
|
||||||
|
* ----------------------------------------------------------------------------
|
||||||
|
* Copyright (c) 2009, Atmel Corporation
|
||||||
|
*
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* - Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the disclaimer below.
|
||||||
|
*
|
||||||
|
* Atmel's name may not be used to endorse or promote products derived from
|
||||||
|
* this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
|
||||||
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||||||
|
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
|
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||||
|
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
* ----------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------------
|
||||||
|
* Linker script for running in internal SRAM on the ATSAM3S2
|
||||||
|
*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
OUTPUT_FORMAT ("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
|
||||||
|
OUTPUT_ARCH(arm)
|
||||||
|
SEARCH_DIR(.)
|
||||||
|
|
||||||
|
/* Memory Spaces Definitions */
|
||||||
|
MEMORY
|
||||||
|
{
|
||||||
|
rom (rx) : ORIGIN = 0x00400000, LENGTH = 0x00020000 /* flash, 128K */
|
||||||
|
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00008000 /* sram, 32K */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Section Definitions */
|
||||||
|
SECTIONS
|
||||||
|
{
|
||||||
|
.text :
|
||||||
|
{
|
||||||
|
. = ALIGN(4);
|
||||||
|
_sfixed = .;
|
||||||
|
KEEP(*(.vectors .vectors.*))
|
||||||
|
*(.text .text.* .gnu.linkonce.t.*)
|
||||||
|
*(.glue_7t) *(.glue_7)
|
||||||
|
*(.rodata .rodata* .gnu.linkonce.r.*)
|
||||||
|
*(.ARM.extab* .gnu.linkonce.armextab.*)
|
||||||
|
|
||||||
|
/* Support C constructors, and C destructors in both user code
|
||||||
|
and the C library. This also provides support for C++ code. */
|
||||||
|
. = ALIGN(4);
|
||||||
|
KEEP(*(.init))
|
||||||
|
. = ALIGN(4);
|
||||||
|
__preinit_array_start = .;
|
||||||
|
KEEP (*(.preinit_array))
|
||||||
|
__preinit_array_end = .;
|
||||||
|
|
||||||
|
. = ALIGN(4);
|
||||||
|
__init_array_start = .;
|
||||||
|
KEEP (*(SORT(.init_array.*)))
|
||||||
|
KEEP (*(.init_array))
|
||||||
|
__init_array_end = .;
|
||||||
|
|
||||||
|
. = ALIGN(0x4);
|
||||||
|
KEEP (*crtbegin.o(.ctors))
|
||||||
|
KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
|
||||||
|
KEEP (*(SORT(.ctors.*)))
|
||||||
|
KEEP (*crtend.o(.ctors))
|
||||||
|
|
||||||
|
. = ALIGN(4);
|
||||||
|
KEEP(*(.fini))
|
||||||
|
|
||||||
|
. = ALIGN(4);
|
||||||
|
__fini_array_start = .;
|
||||||
|
KEEP (*(.fini_array))
|
||||||
|
KEEP (*(SORT(.fini_array.*)))
|
||||||
|
__fini_array_end = .;
|
||||||
|
|
||||||
|
KEEP (*crtbegin.o(.dtors))
|
||||||
|
KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
|
||||||
|
KEEP (*(SORT(.dtors.*)))
|
||||||
|
KEEP (*crtend.o(.dtors))
|
||||||
|
|
||||||
|
. = ALIGN(4);
|
||||||
|
_efixed = .; /* End of text section */
|
||||||
|
} > ram
|
||||||
|
|
||||||
|
. = ALIGN(4);
|
||||||
|
_etext = .;
|
||||||
|
|
||||||
|
.relocate : AT (_etext)
|
||||||
|
{
|
||||||
|
. = ALIGN(4);
|
||||||
|
_srelocate = .;
|
||||||
|
*(.ramfunc .ramfunc.*);
|
||||||
|
*(.data .data.*);
|
||||||
|
. = ALIGN(4);
|
||||||
|
_erelocate = .;
|
||||||
|
} > ram
|
||||||
|
|
||||||
|
/* .bss section which is used for uninitialized data */
|
||||||
|
.bss (NOLOAD) :
|
||||||
|
{
|
||||||
|
. = ALIGN(4);
|
||||||
|
_sbss = . ;
|
||||||
|
_szero = .;
|
||||||
|
*(.bss .bss.*)
|
||||||
|
*(COMMON)
|
||||||
|
. = ALIGN(4);
|
||||||
|
_ebss = . ;
|
||||||
|
_ezero = .;
|
||||||
|
} > ram
|
||||||
|
|
||||||
|
/* stack section */
|
||||||
|
.stack (NOLOAD):
|
||||||
|
{
|
||||||
|
. = ALIGN(8);
|
||||||
|
*(.stack .stack.*)
|
||||||
|
} > ram
|
||||||
|
|
||||||
|
/* .ARM.exidx is sorted, so has to go in its own output section. */
|
||||||
|
PROVIDE_HIDDEN (__exidx_start = .);
|
||||||
|
.ARM.exidx :
|
||||||
|
{
|
||||||
|
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
|
||||||
|
} > ram
|
||||||
|
PROVIDE_HIDDEN (__exidx_end = .);
|
||||||
|
|
||||||
|
. = ALIGN(4);
|
||||||
|
_end = . ;
|
||||||
|
}
|
||||||
91
firmware/libboard/common/resources/sam3s2/sram_samba.lds
Normal file
91
firmware/libboard/common/resources/sam3s2/sram_samba.lds
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
/* ----------------------------------------------------------------------------
|
||||||
|
* ATMEL Microcontroller Software Support
|
||||||
|
* ----------------------------------------------------------------------------
|
||||||
|
* Copyright (c) 2009, Atmel Corporation
|
||||||
|
*
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* - Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the disclaimer below.
|
||||||
|
*
|
||||||
|
* Atmel's name may not be used to endorse or promote products derived from
|
||||||
|
* this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
|
||||||
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||||||
|
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
|
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||||
|
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
* ----------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------------
|
||||||
|
* Linker script for running in internal SRAM on the AT91SAM3S2
|
||||||
|
*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
|
||||||
|
OUTPUT_ARCH(arm)
|
||||||
|
ENTRY(entry)
|
||||||
|
|
||||||
|
/* Memory Spaces Definitions */
|
||||||
|
MEMORY
|
||||||
|
{
|
||||||
|
romcodesram (W!RX) : ORIGIN = 0x20000000, LENGTH = 0x0800
|
||||||
|
sram (W!RX) : ORIGIN = 0x20000800, LENGTH = 0x00007800 /* sram, 32K - sizeof(romcodesram) */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Entry point */
|
||||||
|
/*ENTRY (ResetException)*/
|
||||||
|
|
||||||
|
SECTIONS
|
||||||
|
{
|
||||||
|
/* startup code in the .isr_vector */
|
||||||
|
.text :
|
||||||
|
{
|
||||||
|
. = ALIGN(4);
|
||||||
|
_stext = .;
|
||||||
|
KEEP(*(.isr_vector .isr_vector.*))
|
||||||
|
*(.mailbox)
|
||||||
|
*(.text .text.*)
|
||||||
|
*(.rodata .rodata.*)
|
||||||
|
*(.glue_7)
|
||||||
|
*(.glue_7t)
|
||||||
|
*(.gcc_except_table)
|
||||||
|
*(.rodata .rodata*)
|
||||||
|
*(.gnu.linkonce.r.*)
|
||||||
|
. = ALIGN(4);
|
||||||
|
_etext = .;
|
||||||
|
} > sram
|
||||||
|
|
||||||
|
/* data */
|
||||||
|
.data :
|
||||||
|
{
|
||||||
|
. = ALIGN(4);
|
||||||
|
_sidata = .;
|
||||||
|
_sdata = .;
|
||||||
|
|
||||||
|
*(.data)
|
||||||
|
*(.data.*)
|
||||||
|
. = ALIGN(4);
|
||||||
|
_edata = .;
|
||||||
|
} > sram
|
||||||
|
|
||||||
|
.bss (NOLOAD) : {
|
||||||
|
_szero = .;
|
||||||
|
*(.bss)
|
||||||
|
. = ALIGN(4);
|
||||||
|
_ezero = .;
|
||||||
|
} >sram
|
||||||
|
|
||||||
|
/* Stack in SRAM */
|
||||||
|
_sstack = 0x20007FFC;
|
||||||
|
}
|
||||||
|
end = .;
|
||||||
142
firmware/libboard/common/resources/sam3s4/dfu.ld
Normal file
142
firmware/libboard/common/resources/sam3s4/dfu.ld
Normal file
@@ -0,0 +1,142 @@
|
|||||||
|
/* ----------------------------------------------------------------------------
|
||||||
|
* ATMEL Microcontroller Software Support
|
||||||
|
* ----------------------------------------------------------------------------
|
||||||
|
* Copyright (c) 2009, Atmel Corporation
|
||||||
|
*
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* - Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the disclaimer below.
|
||||||
|
*
|
||||||
|
* Atmel's name may not be used to endorse or promote products derived from
|
||||||
|
* this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
|
||||||
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||||||
|
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
|
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||||
|
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
* ----------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------------
|
||||||
|
* Linker script for running in internal FLASH on the ATSAM3S4
|
||||||
|
*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
|
||||||
|
OUTPUT_ARCH(arm)
|
||||||
|
SEARCH_DIR(.)
|
||||||
|
|
||||||
|
/* Memory Spaces Definitions */
|
||||||
|
MEMORY
|
||||||
|
{
|
||||||
|
/* reserve the first 16k (= 0x4000) for the DFU bootloader */
|
||||||
|
rom (rx) : ORIGIN = 0x00404000, LENGTH = 0x0003c000 /* flash, 256K */
|
||||||
|
/* reserve the first 32 (= 0x20) bytes for the _g_dfu struct */
|
||||||
|
ram (rwx) : ORIGIN = 0x20000020, LENGTH = 0x0000bfe0 /* sram, 48K */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Section Definitions */
|
||||||
|
SECTIONS
|
||||||
|
{
|
||||||
|
.text :
|
||||||
|
{
|
||||||
|
. = ALIGN(4);
|
||||||
|
_sfixed = .;
|
||||||
|
KEEP(*(.vectors .vectors.*))
|
||||||
|
*(.text .text.* .gnu.linkonce.t.*)
|
||||||
|
*(.glue_7t) *(.glue_7)
|
||||||
|
*(.rodata .rodata* .gnu.linkonce.r.*)
|
||||||
|
*(.ARM.extab* .gnu.linkonce.armextab.*)
|
||||||
|
|
||||||
|
/* Support C constructors, and C destructors in both user code
|
||||||
|
and the C library. This also provides support for C++ code. */
|
||||||
|
. = ALIGN(4);
|
||||||
|
KEEP(*(.init))
|
||||||
|
. = ALIGN(4);
|
||||||
|
__preinit_array_start = .;
|
||||||
|
KEEP (*(.preinit_array))
|
||||||
|
__preinit_array_end = .;
|
||||||
|
|
||||||
|
. = ALIGN(4);
|
||||||
|
__init_array_start = .;
|
||||||
|
KEEP (*(SORT(.init_array.*)))
|
||||||
|
KEEP (*(.init_array))
|
||||||
|
__init_array_end = .;
|
||||||
|
|
||||||
|
. = ALIGN(0x4);
|
||||||
|
KEEP (*crtbegin.o(.ctors))
|
||||||
|
KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
|
||||||
|
KEEP (*(SORT(.ctors.*)))
|
||||||
|
KEEP (*crtend.o(.ctors))
|
||||||
|
|
||||||
|
. = ALIGN(4);
|
||||||
|
KEEP(*(.fini))
|
||||||
|
|
||||||
|
. = ALIGN(4);
|
||||||
|
__fini_array_start = .;
|
||||||
|
KEEP (*(.fini_array))
|
||||||
|
KEEP (*(SORT(.fini_array.*)))
|
||||||
|
__fini_array_end = .;
|
||||||
|
|
||||||
|
KEEP (*crtbegin.o(.dtors))
|
||||||
|
KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
|
||||||
|
KEEP (*(SORT(.dtors.*)))
|
||||||
|
KEEP (*crtend.o(.dtors))
|
||||||
|
|
||||||
|
. = ALIGN(4);
|
||||||
|
_efixed = .; /* End of text section */
|
||||||
|
} > rom
|
||||||
|
|
||||||
|
/* .ARM.exidx is sorted, so has to go in its own output section. */
|
||||||
|
PROVIDE_HIDDEN (__exidx_start = .);
|
||||||
|
.ARM.exidx :
|
||||||
|
{
|
||||||
|
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
|
||||||
|
} > rom
|
||||||
|
PROVIDE_HIDDEN (__exidx_end = .);
|
||||||
|
|
||||||
|
. = ALIGN(4);
|
||||||
|
_etext = .;
|
||||||
|
|
||||||
|
.relocate : AT (_etext)
|
||||||
|
{
|
||||||
|
. = ALIGN(4);
|
||||||
|
_srelocate = .;
|
||||||
|
*(.ramfunc .ramfunc.*);
|
||||||
|
*(.data .data.*);
|
||||||
|
. = ALIGN(4);
|
||||||
|
_erelocate = .;
|
||||||
|
} > ram
|
||||||
|
|
||||||
|
/* .bss section which is used for uninitialized data */
|
||||||
|
.bss (NOLOAD) :
|
||||||
|
{
|
||||||
|
. = ALIGN(4);
|
||||||
|
_sbss = . ;
|
||||||
|
_szero = .;
|
||||||
|
*(.bss .bss.*)
|
||||||
|
*(COMMON)
|
||||||
|
. = ALIGN(4);
|
||||||
|
_ebss = . ;
|
||||||
|
_ezero = .;
|
||||||
|
} > ram
|
||||||
|
|
||||||
|
/* stack section */
|
||||||
|
.stack (NOLOAD):
|
||||||
|
{
|
||||||
|
. = ALIGN(8);
|
||||||
|
*(.stack .stack.*)
|
||||||
|
} > ram
|
||||||
|
|
||||||
|
. = ALIGN(4);
|
||||||
|
_end = . ;
|
||||||
|
}
|
||||||
@@ -1,143 +1,142 @@
|
|||||||
/* ----------------------------------------------------------------------------
|
/* ----------------------------------------------------------------------------
|
||||||
* ATMEL Microcontroller Software Support
|
* ATMEL Microcontroller Software Support
|
||||||
* ----------------------------------------------------------------------------
|
* ----------------------------------------------------------------------------
|
||||||
* Copyright (c) 2009, Atmel Corporation
|
* Copyright (c) 2009, Atmel Corporation
|
||||||
*
|
*
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
*
|
*
|
||||||
* - Redistributions of source code must retain the above copyright notice,
|
* - Redistributions of source code must retain the above copyright notice,
|
||||||
* this list of conditions and the disclaimer below.
|
* this list of conditions and the disclaimer below.
|
||||||
*
|
*
|
||||||
* Atmel's name may not be used to endorse or promote products derived from
|
* Atmel's name may not be used to endorse or promote products derived from
|
||||||
* this software without specific prior written permission.
|
* this software without specific prior written permission.
|
||||||
*
|
*
|
||||||
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
|
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
|
||||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||||
* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
|
* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||||||
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
* ----------------------------------------------------------------------------
|
* ----------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
/*------------------------------------------------------------------------------
|
||||||
* Linker script for running in internal FLASH on the ATSAM3S4
|
* Linker script for running in internal FLASH on the ATSAM3S4
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
|
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
|
||||||
OUTPUT_ARCH(arm)
|
OUTPUT_ARCH(arm)
|
||||||
SEARCH_DIR(.)
|
SEARCH_DIR(.)
|
||||||
ENTRY(main)
|
|
||||||
|
/* Memory Spaces Definitions */
|
||||||
/* Memory Spaces Definitions */
|
MEMORY
|
||||||
MEMORY
|
{
|
||||||
{
|
rom (rx) : ORIGIN = 0x00400000, LENGTH = 0x00040000 /* flash, 256K */
|
||||||
rom (rx) : ORIGIN = 0x00400000, LENGTH = 0x00020000 /* flash, 256K */
|
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 0x0000c000 /* sram, 48K */
|
||||||
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00008000 /* sram, 48K */
|
}
|
||||||
/* rom (rx) : ORIGIN = 0x00400000, LENGTH = 0x00040000 /* flash, 256K */
|
|
||||||
/*ram (rwx) : ORIGIN = 0x20000000, LENGTH = 0x0000c000 /* sram, 48K */
|
/* Section Definitions */
|
||||||
}
|
SECTIONS
|
||||||
|
{
|
||||||
/* Section Definitions */
|
.text :
|
||||||
SECTIONS
|
{
|
||||||
{
|
. = ALIGN(4);
|
||||||
.text :
|
_sfixed = .;
|
||||||
{
|
KEEP(*(.vectors .vectors.*))
|
||||||
. = ALIGN(4);
|
*(.text .text.* .gnu.linkonce.t.*)
|
||||||
_sfixed = .;
|
*(.glue_7t) *(.glue_7)
|
||||||
KEEP(*(.vectors .vectors.*))
|
*(.rodata .rodata* .gnu.linkonce.r.*)
|
||||||
*(.text .text.* .gnu.linkonce.t.*)
|
*(.ARM.extab* .gnu.linkonce.armextab.*)
|
||||||
*(.glue_7t) *(.glue_7)
|
|
||||||
*(.rodata .rodata* .gnu.linkonce.r.*)
|
/* Support C constructors, and C destructors in both user code
|
||||||
*(.ARM.extab* .gnu.linkonce.armextab.*)
|
and the C library. This also provides support for C++ code. */
|
||||||
|
. = ALIGN(4);
|
||||||
/* Support C constructors, and C destructors in both user code
|
KEEP(*(.init))
|
||||||
and the C library. This also provides support for C++ code. */
|
. = ALIGN(4);
|
||||||
. = ALIGN(4);
|
__preinit_array_start = .;
|
||||||
KEEP(*(.init))
|
KEEP (*(.preinit_array))
|
||||||
. = ALIGN(4);
|
__preinit_array_end = .;
|
||||||
__preinit_array_start = .;
|
|
||||||
KEEP (*(.preinit_array))
|
. = ALIGN(4);
|
||||||
__preinit_array_end = .;
|
__init_array_start = .;
|
||||||
|
KEEP (*(SORT(.init_array.*)))
|
||||||
. = ALIGN(4);
|
KEEP (*(.init_array))
|
||||||
__init_array_start = .;
|
__init_array_end = .;
|
||||||
KEEP (*(SORT(.init_array.*)))
|
|
||||||
KEEP (*(.init_array))
|
. = ALIGN(0x4);
|
||||||
__init_array_end = .;
|
KEEP (*crtbegin.o(.ctors))
|
||||||
|
KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
|
||||||
. = ALIGN(0x4);
|
KEEP (*(SORT(.ctors.*)))
|
||||||
KEEP (*crtbegin.o(.ctors))
|
KEEP (*crtend.o(.ctors))
|
||||||
KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
|
|
||||||
KEEP (*(SORT(.ctors.*)))
|
. = ALIGN(4);
|
||||||
KEEP (*crtend.o(.ctors))
|
KEEP(*(.fini))
|
||||||
|
|
||||||
. = ALIGN(4);
|
. = ALIGN(4);
|
||||||
KEEP(*(.fini))
|
__fini_array_start = .;
|
||||||
|
KEEP (*(.fini_array))
|
||||||
. = ALIGN(4);
|
KEEP (*(SORT(.fini_array.*)))
|
||||||
__fini_array_start = .;
|
__fini_array_end = .;
|
||||||
KEEP (*(.fini_array))
|
|
||||||
KEEP (*(SORT(.fini_array.*)))
|
KEEP (*crtbegin.o(.dtors))
|
||||||
__fini_array_end = .;
|
KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
|
||||||
|
KEEP (*(SORT(.dtors.*)))
|
||||||
KEEP (*crtbegin.o(.dtors))
|
KEEP (*crtend.o(.dtors))
|
||||||
KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
|
|
||||||
KEEP (*(SORT(.dtors.*)))
|
. = ALIGN(4);
|
||||||
KEEP (*crtend.o(.dtors))
|
_efixed = .; /* End of text section */
|
||||||
|
} > rom
|
||||||
. = ALIGN(4);
|
|
||||||
_efixed = .; /* End of text section */
|
/* .ARM.exidx is sorted, so has to go in its own output section. */
|
||||||
} > rom
|
PROVIDE_HIDDEN (__exidx_start = .);
|
||||||
|
.ARM.exidx :
|
||||||
/* .ARM.exidx is sorted, so has to go in its own output section. */
|
{
|
||||||
PROVIDE_HIDDEN (__exidx_start = .);
|
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
|
||||||
.ARM.exidx :
|
} > rom
|
||||||
{
|
PROVIDE_HIDDEN (__exidx_end = .);
|
||||||
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
|
|
||||||
} > rom
|
. = ALIGN(4);
|
||||||
PROVIDE_HIDDEN (__exidx_end = .);
|
_etext = .;
|
||||||
|
|
||||||
. = ALIGN(4);
|
.relocate : AT (_etext)
|
||||||
_etext = .;
|
{
|
||||||
|
. = ALIGN(4);
|
||||||
.relocate : AT (_etext)
|
_srelocate = .;
|
||||||
{
|
/* we must make sure the .dfudata is linked to start of RAM */
|
||||||
. = ALIGN(4);
|
*(.dfudata .dfudata.*);
|
||||||
_srelocate = .;
|
*(.ramfunc .ramfunc.*);
|
||||||
*(.ramfunc .ramfunc.*);
|
*(.data .data.*);
|
||||||
*(.data .data.*);
|
. = ALIGN(4);
|
||||||
. = ALIGN(4);
|
_erelocate = .;
|
||||||
_erelocate = .;
|
} > ram
|
||||||
} > ram
|
|
||||||
|
/* .bss section which is used for uninitialized data */
|
||||||
/* .bss section which is used for uninitialized data */
|
.bss (NOLOAD) :
|
||||||
.bss (NOLOAD) :
|
{
|
||||||
{
|
. = ALIGN(4);
|
||||||
. = ALIGN(4);
|
_sbss = . ;
|
||||||
_sbss = . ;
|
_szero = .;
|
||||||
_szero = .;
|
*(.bss .bss.*)
|
||||||
*(.bss .bss.*)
|
*(COMMON)
|
||||||
*(COMMON)
|
. = ALIGN(4);
|
||||||
. = ALIGN(4);
|
_ebss = . ;
|
||||||
_ebss = . ;
|
_ezero = .;
|
||||||
_ezero = .;
|
} > ram
|
||||||
} > ram
|
|
||||||
|
/* stack section */
|
||||||
/* stack section */
|
.stack (NOLOAD):
|
||||||
.stack (NOLOAD):
|
{
|
||||||
{
|
. = ALIGN(8);
|
||||||
. = ALIGN(8);
|
*(.stack .stack.*)
|
||||||
*(.stack .stack.*)
|
} > ram
|
||||||
} > ram
|
|
||||||
|
. = ALIGN(4);
|
||||||
. = ALIGN(4);
|
_end = . ;
|
||||||
_end = . ;
|
}
|
||||||
}
|
|
||||||
140
firmware/libboard/common/resources/sam3s4/sram.ld
Normal file
140
firmware/libboard/common/resources/sam3s4/sram.ld
Normal file
@@ -0,0 +1,140 @@
|
|||||||
|
/* ----------------------------------------------------------------------------
|
||||||
|
* ATMEL Microcontroller Software Support
|
||||||
|
* ----------------------------------------------------------------------------
|
||||||
|
* Copyright (c) 2009, Atmel Corporation
|
||||||
|
*
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* - Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the disclaimer below.
|
||||||
|
*
|
||||||
|
* Atmel's name may not be used to endorse or promote products derived from
|
||||||
|
* this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
|
||||||
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||||||
|
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
|
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||||
|
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
* ----------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------------
|
||||||
|
* Linker script for running in internal SRAM on the ATSAM3S4
|
||||||
|
*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
|
||||||
|
OUTPUT_ARCH(arm)
|
||||||
|
SEARCH_DIR(.)
|
||||||
|
|
||||||
|
/* Memory Spaces Definitions */
|
||||||
|
MEMORY
|
||||||
|
{
|
||||||
|
rom (rx) : ORIGIN = 0x00400000, LENGTH = 0x00040000 /* flash, 256K */
|
||||||
|
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 0x0000c000 /* sram, 48K */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Section Definitions */
|
||||||
|
SECTIONS
|
||||||
|
{
|
||||||
|
.text :
|
||||||
|
{
|
||||||
|
. = ALIGN(4);
|
||||||
|
_sfixed = .;
|
||||||
|
KEEP(*(.vectors .vectors.*))
|
||||||
|
*(.text .text.* .gnu.linkonce.t.*)
|
||||||
|
*(.glue_7t) *(.glue_7)
|
||||||
|
*(.rodata .rodata* .gnu.linkonce.r.*)
|
||||||
|
*(.ARM.extab* .gnu.linkonce.armextab.*)
|
||||||
|
|
||||||
|
/* Support C constructors, and C destructors in both user code
|
||||||
|
and the C library. This also provides support for C++ code. */
|
||||||
|
. = ALIGN(4);
|
||||||
|
KEEP(*(.init))
|
||||||
|
. = ALIGN(4);
|
||||||
|
__preinit_array_start = .;
|
||||||
|
KEEP (*(.preinit_array))
|
||||||
|
__preinit_array_end = .;
|
||||||
|
|
||||||
|
. = ALIGN(4);
|
||||||
|
__init_array_start = .;
|
||||||
|
KEEP (*(SORT(.init_array.*)))
|
||||||
|
KEEP (*(.init_array))
|
||||||
|
__init_array_end = .;
|
||||||
|
|
||||||
|
. = ALIGN(0x4);
|
||||||
|
KEEP (*crtbegin.o(.ctors))
|
||||||
|
KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
|
||||||
|
KEEP (*(SORT(.ctors.*)))
|
||||||
|
KEEP (*crtend.o(.ctors))
|
||||||
|
|
||||||
|
. = ALIGN(4);
|
||||||
|
KEEP(*(.fini))
|
||||||
|
|
||||||
|
. = ALIGN(4);
|
||||||
|
__fini_array_start = .;
|
||||||
|
KEEP (*(.fini_array))
|
||||||
|
KEEP (*(SORT(.fini_array.*)))
|
||||||
|
__fini_array_end = .;
|
||||||
|
|
||||||
|
KEEP (*crtbegin.o(.dtors))
|
||||||
|
KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
|
||||||
|
KEEP (*(SORT(.dtors.*)))
|
||||||
|
KEEP (*crtend.o(.dtors))
|
||||||
|
|
||||||
|
. = ALIGN(4);
|
||||||
|
_efixed = .; /* End of text section */
|
||||||
|
} > ram
|
||||||
|
|
||||||
|
. = ALIGN(4);
|
||||||
|
_etext = .;
|
||||||
|
|
||||||
|
.relocate : AT (_etext)
|
||||||
|
{
|
||||||
|
. = ALIGN(4);
|
||||||
|
_srelocate = .;
|
||||||
|
*(.ramfunc .ramfunc.*);
|
||||||
|
*(.data .data.*);
|
||||||
|
. = ALIGN(4);
|
||||||
|
_erelocate = .;
|
||||||
|
} > ram
|
||||||
|
|
||||||
|
/* .bss section which is used for uninitialized data */
|
||||||
|
.bss (NOLOAD) :
|
||||||
|
{
|
||||||
|
. = ALIGN(4);
|
||||||
|
_sbss = . ;
|
||||||
|
_szero = .;
|
||||||
|
*(.bss .bss.*)
|
||||||
|
*(COMMON)
|
||||||
|
. = ALIGN(4);
|
||||||
|
_ebss = . ;
|
||||||
|
_ezero = .;
|
||||||
|
} > ram
|
||||||
|
|
||||||
|
/* stack section */
|
||||||
|
.stack (NOLOAD):
|
||||||
|
{
|
||||||
|
. = ALIGN(8);
|
||||||
|
*(.stack .stack.*)
|
||||||
|
} > ram
|
||||||
|
|
||||||
|
/* .ARM.exidx is sorted, so has to go in its own output section. */
|
||||||
|
PROVIDE_HIDDEN (__exidx_start = .);
|
||||||
|
.ARM.exidx :
|
||||||
|
{
|
||||||
|
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
|
||||||
|
} > ram
|
||||||
|
PROVIDE_HIDDEN (__exidx_end = .);
|
||||||
|
|
||||||
|
. = ALIGN(4);
|
||||||
|
_end = . ;
|
||||||
|
}
|
||||||
91
firmware/libboard/common/resources/sam3s4/sram_samba.lds
Normal file
91
firmware/libboard/common/resources/sam3s4/sram_samba.lds
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
/* ----------------------------------------------------------------------------
|
||||||
|
* ATMEL Microcontroller Software Support
|
||||||
|
* ----------------------------------------------------------------------------
|
||||||
|
* Copyright (c) 2009, Atmel Corporation
|
||||||
|
*
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* - Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the disclaimer below.
|
||||||
|
*
|
||||||
|
* Atmel's name may not be used to endorse or promote products derived from
|
||||||
|
* this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
|
||||||
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||||||
|
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
|
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||||
|
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
* ----------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------------
|
||||||
|
* Linker script for running in internal SRAM on the AT91SAM3S4
|
||||||
|
*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
|
||||||
|
OUTPUT_ARCH(arm)
|
||||||
|
ENTRY(entry)
|
||||||
|
|
||||||
|
/* Memory Spaces Definitions */
|
||||||
|
MEMORY
|
||||||
|
{
|
||||||
|
romcodesram (W!RX) : ORIGIN = 0x20000000, LENGTH = 0x01000
|
||||||
|
sram (W!RX) : ORIGIN = 0x20001000, LENGTH = 0x0000B000 /* sram, 48K - sizeof(romcodesram) */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Entry point */
|
||||||
|
/*ENTRY (ResetException)*/
|
||||||
|
|
||||||
|
SECTIONS
|
||||||
|
{
|
||||||
|
/* startup code in the .isr_vector */
|
||||||
|
.text :
|
||||||
|
{
|
||||||
|
. = ALIGN(4);
|
||||||
|
_stext = .;
|
||||||
|
KEEP(*(.isr_vector .isr_vector.*))
|
||||||
|
*(.mailbox)
|
||||||
|
*(.text .text.*)
|
||||||
|
*(.rodata .rodata.*)
|
||||||
|
*(.glue_7)
|
||||||
|
*(.glue_7t)
|
||||||
|
*(.gcc_except_table)
|
||||||
|
*(.rodata .rodata*)
|
||||||
|
*(.gnu.linkonce.r.*)
|
||||||
|
. = ALIGN(4);
|
||||||
|
_etext = .;
|
||||||
|
} > sram
|
||||||
|
|
||||||
|
/* data */
|
||||||
|
.data :
|
||||||
|
{
|
||||||
|
. = ALIGN(4);
|
||||||
|
_sidata = .;
|
||||||
|
_sdata = .;
|
||||||
|
|
||||||
|
*(.data)
|
||||||
|
*(.data.*)
|
||||||
|
. = ALIGN(4);
|
||||||
|
_edata = .;
|
||||||
|
} > sram
|
||||||
|
|
||||||
|
.bss (NOLOAD) : {
|
||||||
|
_szero = .;
|
||||||
|
*(.bss)
|
||||||
|
. = ALIGN(4);
|
||||||
|
_ezero = .;
|
||||||
|
} >sram
|
||||||
|
|
||||||
|
/* Stack in SRAM */
|
||||||
|
_sstack = 0x2000BFFC;
|
||||||
|
}
|
||||||
|
end = .;
|
||||||
31
firmware/libboard/common/resources/sam3s_ek_flash.gdb
Normal file
31
firmware/libboard/common/resources/sam3s_ek_flash.gdb
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
#*******************************************************
|
||||||
|
#
|
||||||
|
# Connect to J-Link and debug application in flash.
|
||||||
|
#
|
||||||
|
|
||||||
|
# define 'reset' command
|
||||||
|
define reset
|
||||||
|
|
||||||
|
# Connect to the J-Link gdb server
|
||||||
|
target remote localhost:2331
|
||||||
|
# Reset the chip to get to a known state
|
||||||
|
monitor reset
|
||||||
|
|
||||||
|
# Select flash device
|
||||||
|
monitor flash device = AT91SAM3S4C
|
||||||
|
# Enable flash download and flash breakpoints
|
||||||
|
monitor flash download = 1
|
||||||
|
# Load the program
|
||||||
|
load
|
||||||
|
|
||||||
|
# Reset peripheral (RSTC_CR)
|
||||||
|
set *0x400e1400 = 0xA5000004
|
||||||
|
|
||||||
|
# Initializing PC and stack pointer
|
||||||
|
mon reg sp=(0x400000)
|
||||||
|
set *0x400004 = *0x400004 & 0xFFFFFFFE
|
||||||
|
mon reg pc=(0x400004)
|
||||||
|
info reg
|
||||||
|
|
||||||
|
# end of 'reset' command
|
||||||
|
end
|
||||||
27
firmware/libboard/common/resources/sam3s_ek_sram.gdb
Normal file
27
firmware/libboard/common/resources/sam3s_ek_sram.gdb
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
#*************************************************
|
||||||
|
#
|
||||||
|
# Connect to J-Link and debug application in sram on SAM3S
|
||||||
|
#
|
||||||
|
# Note:
|
||||||
|
# First, users should modify Step1 and Step2 according to their project,
|
||||||
|
# then do Step3.
|
||||||
|
|
||||||
|
# Step1: Connect to the J-Link gdb server
|
||||||
|
define reset
|
||||||
|
target remote localhost:2331
|
||||||
|
monitor reset
|
||||||
|
|
||||||
|
# Step2: Load file(eg. getting-started project)
|
||||||
|
load
|
||||||
|
|
||||||
|
# Step3: Reset peripheral (RSTC_CR)
|
||||||
|
set *0x400e1400 = 0xA5000004
|
||||||
|
|
||||||
|
# Step4: Initializing PC and stack pointer
|
||||||
|
# Modify pc value to even before writing pc register
|
||||||
|
mon reg sp=(0x20000000)
|
||||||
|
set *0x20000004 = *0x20000004 & 0xFFFFFFFE
|
||||||
|
mon reg pc=(0x20000004)
|
||||||
|
info reg
|
||||||
|
|
||||||
|
end
|
||||||
27
firmware/libboard/common/resources/sam3s_vb_sram.gdb
Normal file
27
firmware/libboard/common/resources/sam3s_vb_sram.gdb
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
#*************************************************
|
||||||
|
#
|
||||||
|
# Connect to J-Link and debug application in sram on SAM3S
|
||||||
|
#
|
||||||
|
# Note:
|
||||||
|
# First, users should modify Step1 and Step2 according to their project,
|
||||||
|
# then do Step3.
|
||||||
|
|
||||||
|
# Step1: Connect to the J-Link gdb server
|
||||||
|
define reset
|
||||||
|
target remote localhost:2331
|
||||||
|
monitor reset
|
||||||
|
|
||||||
|
# Step2: Load file(eg. getting-started project)
|
||||||
|
load
|
||||||
|
|
||||||
|
# Step3: Reset peripheral (RSTC_CR)
|
||||||
|
set *0x400e1400 = 0xA5000004
|
||||||
|
|
||||||
|
# Step4: Initializing PC and stack pointer
|
||||||
|
# Modify pc value to even before writing pc register
|
||||||
|
mon reg sp=(0x20000000)
|
||||||
|
set *0x20000004 = *0x20000004 & 0xFFFFFFFE
|
||||||
|
mon reg pc=(0x20000004)
|
||||||
|
info reg
|
||||||
|
|
||||||
|
end
|
||||||
@@ -61,7 +61,6 @@ extern uint32_t _ezero;
|
|||||||
extern int main( void ) ;
|
extern int main( void ) ;
|
||||||
/** \endcond */
|
/** \endcond */
|
||||||
void ResetException( void ) ;
|
void ResetException( void ) ;
|
||||||
extern void __libc_init_array( void ) ;
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
/*------------------------------------------------------------------------------
|
||||||
* Exception Table
|
* Exception Table
|
||||||
@@ -125,6 +124,23 @@ IntFunc exception_table[] = {
|
|||||||
IrqHandlerNotUsed /* 35 not used */
|
IrqHandlerNotUsed /* 35 not used */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#if defined(BOARD_USB_DFU) && defined(APPLICATION_dfu)
|
||||||
|
#include "usb/device/dfu/dfu.h"
|
||||||
|
static void BootIntoApp(void)
|
||||||
|
{
|
||||||
|
unsigned int *pSrc;
|
||||||
|
void (*appReset)(void);
|
||||||
|
|
||||||
|
pSrc = (unsigned int *) ((unsigned char *)IFLASH_ADDR + BOARD_DFU_BOOT_SIZE);
|
||||||
|
SCB->VTOR = ((unsigned int)(pSrc)) | (0x0 << 7);
|
||||||
|
appReset = pSrc[1];
|
||||||
|
|
||||||
|
g_dfu->state = DFU_STATE_appIDLE;
|
||||||
|
|
||||||
|
appReset();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief This is the code that gets called on processor reset.
|
* \brief This is the code that gets called on processor reset.
|
||||||
* To initialize the device, and call the main() routine.
|
* To initialize the device, and call the main() routine.
|
||||||
@@ -136,6 +152,18 @@ void ResetException( void )
|
|||||||
/* Low level Initialize */
|
/* Low level Initialize */
|
||||||
LowLevelInit() ;
|
LowLevelInit() ;
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(BOARD_USB_DFU) && defined(APPLICATION_dfu)
|
||||||
|
/* we are before the text segment has been relocated, so g_dfu is
|
||||||
|
* not initialized yet */
|
||||||
|
g_dfu = &_g_dfu;
|
||||||
|
if (g_dfu->magic != USB_DFU_MAGIC) {
|
||||||
|
BootIntoApp();
|
||||||
|
/* Infinite loop */
|
||||||
|
while ( 1 ) ;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Initialize the relocate segment */
|
/* Initialize the relocate segment */
|
||||||
pSrc = &_etext ;
|
pSrc = &_etext ;
|
||||||
pDest = &_srelocate ;
|
pDest = &_srelocate ;
|
||||||
@@ -163,8 +191,8 @@ void ResetException( void )
|
|||||||
SCB->VTOR |= 1 << SCB_VTOR_TBLBASE_Pos ;
|
SCB->VTOR |= 1 << SCB_VTOR_TBLBASE_Pos ;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Initialize the C library */
|
/* App should have disabled interrupts during the transition */
|
||||||
__libc_init_array() ;
|
__enable_irq();
|
||||||
|
|
||||||
/* Branch to main function */
|
/* Branch to main function */
|
||||||
main() ;
|
main() ;
|
||||||
@@ -43,31 +43,69 @@
|
|||||||
* Local definitions
|
* Local definitions
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
/* Clock settings at 48MHz for 18 MHz crystal */
|
#define BOARD_OSCOUNT (CKGR_MOR_MOSCXTST(0x8))
|
||||||
|
#define BOARD_MCKR (PMC_MCKR_PRES_CLK | PMC_MCKR_CSS_PLLA_CLK)
|
||||||
|
|
||||||
#if (BOARD_MCK == 48000000)
|
#if (BOARD_MCK == 48000000)
|
||||||
#define BOARD_OSCOUNT (CKGR_MOR_MOSCXTST(0x8))
|
#if (BOARD_MAINOSC == 18432000)
|
||||||
|
/* Clock settings at 48MHz for 18 MHz crystal */
|
||||||
#define BOARD_PLLAR (CKGR_PLLAR_STUCKTO1 \
|
#define BOARD_PLLAR (CKGR_PLLAR_STUCKTO1 \
|
||||||
| CKGR_PLLAR_MULA(0xc) \
|
| CKGR_PLLAR_MULA(13-1) \
|
||||||
| CKGR_PLLAR_PLLACOUNT(0x1) \
|
| CKGR_PLLAR_PLLACOUNT(0x1) \
|
||||||
| CKGR_PLLAR_DIVA(0x5))
|
| CKGR_PLLAR_DIVA(5))
|
||||||
#define BOARD_MCKR (PMC_MCKR_PRES_CLK | PMC_MCKR_CSS_PLLA_CLK)
|
#elif (BOARD_MAINOSC == 12000000)
|
||||||
|
/* QMod has 12 MHz clock, so multply by 8 (96 MHz) and divide by 2 */
|
||||||
/* Clock settings at 64MHz for 18 MHz crystal */
|
|
||||||
#elif (BOARD_MCK == 64000000)
|
|
||||||
#define BOARD_OSCOUNT (CKGR_MOR_MOSCXTST(0x8))
|
|
||||||
#define BOARD_PLLAR (CKGR_PLLAR_STUCKTO1 \
|
#define BOARD_PLLAR (CKGR_PLLAR_STUCKTO1 \
|
||||||
| CKGR_PLLAR_MULA(0x06) \
|
| CKGR_PLLAR_MULA(8-1) \
|
||||||
| CKGR_PLLAR_PLLACOUNT(0x1) \
|
| CKGR_PLLAR_PLLACOUNT(0x1) \
|
||||||
| CKGR_PLLAR_DIVA(0x2))
|
| CKGR_PLLAR_DIVA(2))
|
||||||
#define BOARD_MCKR (PMC_MCKR_PRES_CLK | PMC_MCKR_CSS_PLLA_CLK)
|
|
||||||
|
|
||||||
#else
|
#else
|
||||||
#error "No settings for current BOARD_MCK."
|
#error "Please define PLLA config for your MAINOSC frequency"
|
||||||
|
#endif /* MAINOSC */
|
||||||
|
#elif (BOARD_MCK == 64000000)
|
||||||
|
#if (BOARD_MAINOSC == 18432000)
|
||||||
|
/* Clock settings at 64MHz for 18 MHz crystal: 64.512 MHz */
|
||||||
|
#define BOARD_PLLAR (CKGR_PLLAR_STUCKTO1 \
|
||||||
|
| CKGR_PLLAR_MULA(7-1) \
|
||||||
|
| CKGR_PLLAR_PLLACOUNT(0x1) \
|
||||||
|
| CKGR_PLLAR_DIVA(2))
|
||||||
|
#elif (BOARD_MAINOSC == 12000000)
|
||||||
|
/* QMod has 12 MHz clock, so multply by 10 / div by 2: 60 MHz */
|
||||||
|
#define BOARD_PLLAR (CKGR_PLLAR_STUCKTO1 \
|
||||||
|
| CKGR_PLLAR_MULA(10-1) \
|
||||||
|
| CKGR_PLLAR_PLLACOUNT(0x1) \
|
||||||
|
| CKGR_PLLAR_DIVA(2))
|
||||||
|
#error "Please define PLLA config for your MAINOSC frequency"
|
||||||
|
#endif /* MAINOSC */
|
||||||
|
#else
|
||||||
|
#error "No PLL settings for current BOARD_MCK."
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (BOARD_MAINOSC == 12000000)
|
||||||
|
#define PLLB_CFG (CKGR_PLLBR_DIVB(2)|CKGR_PLLBR_MULB(8-1)|CKGR_PLLBR_PLLBCOUNT_Msk)
|
||||||
|
#elif (BOARD_MAINOSC == 18432000)
|
||||||
|
#define PLLB_CFG (CKGR_PLLBR_DIVB(5)|CKGR_PLLBR_MULB(13-1)|CKGR_PLLBR_PLLBCOUNT_Msk)
|
||||||
|
#else
|
||||||
|
#error "Please configure PLLB for your MAINOSC freq"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Define clock timeout */
|
/* Define clock timeout */
|
||||||
#define CLOCK_TIMEOUT 0xFFFFFFFF
|
#define CLOCK_TIMEOUT 0xFFFFFFFF
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Configure 48MHz Clock for USB
|
||||||
|
*/
|
||||||
|
static void _ConfigureUsbClock(void)
|
||||||
|
{
|
||||||
|
/* Enable PLLB for USB */
|
||||||
|
PMC->CKGR_PLLBR = PLLB_CFG;
|
||||||
|
while ((PMC->PMC_SR & PMC_SR_LOCKB) == 0) ;
|
||||||
|
|
||||||
|
/* USB Clock uses PLLB */
|
||||||
|
PMC->PMC_USB = PMC_USB_USBDIV(0) /* /1 (no divider) */
|
||||||
|
| PMC_USB_USBS; /* PLLB */
|
||||||
|
}
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
* Exported functions
|
* Exported functions
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
@@ -81,6 +119,11 @@ extern WEAK void LowLevelInit( void )
|
|||||||
{
|
{
|
||||||
uint32_t timeout = 0;
|
uint32_t timeout = 0;
|
||||||
|
|
||||||
|
/* enable both LED and green LED */
|
||||||
|
PIOA->PIO_PER |= LED_RED | LED_GREEN;
|
||||||
|
PIOA->PIO_OER |= LED_RED | LED_GREEN;
|
||||||
|
PIOA->PIO_CODR |= LED_RED | LED_GREEN;
|
||||||
|
|
||||||
/* Set 3 FWS for Embedded Flash Access */
|
/* Set 3 FWS for Embedded Flash Access */
|
||||||
EFC->EEFC_FMR = EEFC_FMR_FWS(3);
|
EFC->EEFC_FMR = EEFC_FMR_FWS(3);
|
||||||
|
|
||||||
@@ -93,30 +136,74 @@ extern WEAK void LowLevelInit( void )
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifndef qmod
|
||||||
/* Initialize main oscillator */
|
/* Initialize main oscillator */
|
||||||
/* if ( !(PMC->CKGR_MOR & CKGR_MOR_MOSCSEL) )
|
if ( !(PMC->CKGR_MOR & CKGR_MOR_MOSCSEL) )
|
||||||
{
|
{
|
||||||
PMC->CKGR_MOR = CKGR_MOR_KEY(0x37) | BOARD_OSCOUNT | CKGR_MOR_MOSCRCEN | CKGR_MOR_MOSCXTEN;
|
PMC->CKGR_MOR = CKGR_MOR_KEY(0x37) | BOARD_OSCOUNT | CKGR_MOR_MOSCRCEN | CKGR_MOR_MOSCXTEN;
|
||||||
timeout = 0;
|
timeout = 0;
|
||||||
while (!(PMC->PMC_SR & PMC_SR_MOSCXTS) && (timeout++ < CLOCK_TIMEOUT));
|
while (!(PMC->PMC_SR & PMC_SR_MOSCXTS) && (timeout++ < CLOCK_TIMEOUT));
|
||||||
}*/
|
}
|
||||||
|
|
||||||
/* Switch to 3-20MHz Xtal oscillator */
|
/* Switch to 3-20MHz Xtal oscillator */
|
||||||
|
PIOB->PIO_PDR = (1 << 8) | (1 << 9);
|
||||||
|
PIOB->PIO_PUDR = (1 << 8) | (1 << 9);
|
||||||
|
PIOB->PIO_PPDDR = (1 << 8) | (1 << 9);
|
||||||
PMC->CKGR_MOR = CKGR_MOR_KEY(0x37) | BOARD_OSCOUNT | CKGR_MOR_MOSCRCEN | CKGR_MOR_MOSCXTEN | CKGR_MOR_MOSCSEL;
|
PMC->CKGR_MOR = CKGR_MOR_KEY(0x37) | BOARD_OSCOUNT | CKGR_MOR_MOSCRCEN | CKGR_MOR_MOSCXTEN | CKGR_MOR_MOSCSEL;
|
||||||
|
/* wait for Main XTAL oscillator stabilization */
|
||||||
timeout = 0;
|
timeout = 0;
|
||||||
while (!(PMC->PMC_SR & PMC_SR_MOSCSELS) && (timeout++ < CLOCK_TIMEOUT));
|
while (!(PMC->PMC_SR & PMC_SR_MOSCSELS) && (timeout++ < CLOCK_TIMEOUT));
|
||||||
|
#else
|
||||||
|
/* QMOD has external 12MHz clock source */
|
||||||
|
PIOB->PIO_PDR = (1 << 9);
|
||||||
|
PIOB->PIO_PUDR = (1 << 9);
|
||||||
|
PIOB->PIO_PPDDR = (1 << 9);
|
||||||
|
PMC->CKGR_MOR = CKGR_MOR_KEY(0x37) | CKGR_MOR_MOSCRCEN | CKGR_MOR_MOSCXTBY| CKGR_MOR_MOSCSEL;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* disable the red LED after main clock initialization */
|
||||||
|
PIOA->PIO_SODR = LED_RED;
|
||||||
|
|
||||||
|
/* "switch" to main clock as master clock source (should already be the case */
|
||||||
PMC->PMC_MCKR = (PMC->PMC_MCKR & ~(uint32_t)PMC_MCKR_CSS_Msk) | PMC_MCKR_CSS_MAIN_CLK;
|
PMC->PMC_MCKR = (PMC->PMC_MCKR & ~(uint32_t)PMC_MCKR_CSS_Msk) | PMC_MCKR_CSS_MAIN_CLK;
|
||||||
|
/* wait for master clock to be ready */
|
||||||
for ( timeout = 0; !(PMC->PMC_SR & PMC_SR_MCKRDY) && (timeout++ < CLOCK_TIMEOUT) ; );
|
for ( timeout = 0; !(PMC->PMC_SR & PMC_SR_MCKRDY) && (timeout++ < CLOCK_TIMEOUT) ; );
|
||||||
|
|
||||||
/* Initialize PLLA */
|
/* Initialize PLLA */
|
||||||
PMC->CKGR_PLLAR = BOARD_PLLAR;
|
PMC->CKGR_PLLAR = BOARD_PLLAR;
|
||||||
|
/* Wait for PLLA to lock */
|
||||||
timeout = 0;
|
timeout = 0;
|
||||||
while (!(PMC->PMC_SR & PMC_SR_LOCKA) && (timeout++ < CLOCK_TIMEOUT));
|
while (!(PMC->PMC_SR & PMC_SR_LOCKA) && (timeout++ < CLOCK_TIMEOUT));
|
||||||
|
|
||||||
/* Switch to main clock */
|
/* Switch to main clock (again ?!?) */
|
||||||
PMC->PMC_MCKR = (BOARD_MCKR & ~PMC_MCKR_CSS_Msk) | PMC_MCKR_CSS_MAIN_CLK;
|
PMC->PMC_MCKR = (BOARD_MCKR & ~PMC_MCKR_CSS_Msk) | PMC_MCKR_CSS_MAIN_CLK;
|
||||||
|
/* wait for master clock to be ready */
|
||||||
for ( timeout = 0; !(PMC->PMC_SR & PMC_SR_MCKRDY) && (timeout++ < CLOCK_TIMEOUT) ; );
|
for ( timeout = 0; !(PMC->PMC_SR & PMC_SR_MCKRDY) && (timeout++ < CLOCK_TIMEOUT) ; );
|
||||||
|
|
||||||
|
/* switch to PLLA as master clock source */
|
||||||
PMC->PMC_MCKR = BOARD_MCKR ;
|
PMC->PMC_MCKR = BOARD_MCKR ;
|
||||||
|
/* wait for master clock to be ready */
|
||||||
for ( timeout = 0; !(PMC->PMC_SR & PMC_SR_MCKRDY) && (timeout++ < CLOCK_TIMEOUT) ; );
|
for ( timeout = 0; !(PMC->PMC_SR & PMC_SR_MCKRDY) && (timeout++ < CLOCK_TIMEOUT) ; );
|
||||||
|
|
||||||
|
/* Configure SysTick for 1ms */
|
||||||
|
SysTick_Config(BOARD_MCK/1000);
|
||||||
|
|
||||||
|
_ConfigureUsbClock();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* SysTick based delay function */
|
||||||
|
|
||||||
|
volatile uint32_t jiffies;
|
||||||
|
|
||||||
|
/* Interrupt handler for SysTick interrupt */
|
||||||
|
void SysTick_Handler(void)
|
||||||
|
{
|
||||||
|
jiffies++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void mdelay(unsigned int msecs)
|
||||||
|
{
|
||||||
|
uint32_t jiffies_start = jiffies;
|
||||||
|
do {
|
||||||
|
} while ((jiffies - jiffies_start) < msecs);
|
||||||
}
|
}
|
||||||
83
firmware/libboard/common/source/boardver_adc.c
Normal file
83
firmware/libboard/common/source/boardver_adc.c
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
#include "board.h"
|
||||||
|
#include "boardver_adc.h"
|
||||||
|
|
||||||
|
/* FIXME: share this with mode_cardemu.c */
|
||||||
|
#define UV_PER_LSB ((3300 * 1000) / 4096)
|
||||||
|
static uint32_t adc2uv(uint16_t adc)
|
||||||
|
{
|
||||||
|
uint32_t uv = (uint32_t) adc * UV_PER_LSB;
|
||||||
|
return uv;
|
||||||
|
}
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* ADC for board version detection
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
#ifdef PIN_VERSION_DET
|
||||||
|
|
||||||
|
static int adc_sam3s_reva_errata = 0;
|
||||||
|
|
||||||
|
static const Pin pin_version_det = PIN_VERSION_DET;
|
||||||
|
|
||||||
|
/* Warning: Don't call this while other code (like the SIM VCC voltage
|
||||||
|
* reading) is running. The idea is you call this once during board
|
||||||
|
* startup and cache the result in a (global) variable if you need it
|
||||||
|
* later throughout the code */
|
||||||
|
int get_board_version_adc(void)
|
||||||
|
{
|
||||||
|
uint32_t chip_arch = CHIPID->CHIPID_CIDR & CHIPID_CIDR_ARCH_Msk;
|
||||||
|
uint32_t chip_ver = CHIPID->CHIPID_CIDR & CHIPID_CIDR_VERSION_Msk;
|
||||||
|
uint16_t sample;
|
||||||
|
uint32_t uv;
|
||||||
|
|
||||||
|
PIO_Configure(&pin_version_det, 1);
|
||||||
|
|
||||||
|
PMC_EnablePeripheral(ID_ADC);
|
||||||
|
|
||||||
|
ADC->ADC_CR |= ADC_CR_SWRST;
|
||||||
|
if (chip_ver == 0 &&
|
||||||
|
(chip_arch == CHIPID_CIDR_ARCH_SAM3SxA ||
|
||||||
|
chip_arch == CHIPID_CIDR_ARCH_SAM3SxB ||
|
||||||
|
chip_arch == CHIPID_CIDR_ARCH_SAM3SxC)) {
|
||||||
|
TRACE_INFO("Enabling Rev.A ADC Errata work-around\r\n");
|
||||||
|
adc_sam3s_reva_errata = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (adc_sam3s_reva_errata) {
|
||||||
|
/* Errata Work-Around to clear EOCx flags */
|
||||||
|
volatile uint32_t foo;
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < 16; i++)
|
||||||
|
foo = ADC->ADC_CDR[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Initialize ADC for AD2, fADC=48/24=2MHz */
|
||||||
|
ADC->ADC_MR = ADC_MR_TRGEN_DIS | ADC_MR_LOWRES_BITS_12 |
|
||||||
|
ADC_MR_SLEEP_NORMAL | ADC_MR_FWUP_OFF |
|
||||||
|
ADC_MR_FREERUN_OFF | ADC_MR_PRESCAL(23) |
|
||||||
|
ADC_MR_STARTUP_SUT8 | ADC_MR_SETTLING(3) |
|
||||||
|
ADC_MR_ANACH_NONE | ADC_MR_TRACKTIM(4) |
|
||||||
|
ADC_MR_TRANSFER(1) | ADC_MR_USEQ_NUM_ORDER;
|
||||||
|
/* enable AD2 channel only */
|
||||||
|
ADC->ADC_CHER = ADC_CHER_CH2;
|
||||||
|
|
||||||
|
/* Make sure we don't use interrupts as that's what the SIM card
|
||||||
|
* VCC ADC code is using */
|
||||||
|
ADC->ADC_IER = 0;
|
||||||
|
NVIC_DisableIRQ(ADC_IRQn);
|
||||||
|
|
||||||
|
ADC->ADC_CR |= ADC_CR_START;
|
||||||
|
|
||||||
|
/* busy-wait, actually read the value */
|
||||||
|
do { } while (!(ADC->ADC_ISR & ADC_ISR_EOC2));
|
||||||
|
/* convert to voltage */
|
||||||
|
sample = ADC->ADC_CDR[2];
|
||||||
|
uv = adc2uv(sample);
|
||||||
|
TRACE_INFO("VERSION_DET ADC=%u => %u uV\r\n", sample, uv);
|
||||||
|
|
||||||
|
/* FIXME: convert to board version based on thresholds */
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* PIN_VERSION_DET */
|
||||||
7
firmware/libboard/common/source/manifest.c
Normal file
7
firmware/libboard/common/source/manifest.c
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
|
||||||
|
#include "manifest.h"
|
||||||
|
|
||||||
|
const char *manifest_application = APPLICATION;
|
||||||
|
const char *manifest_revision = GIT_VERSION;
|
||||||
|
const char *manifest_board = BOARD;
|
||||||
|
const char *manifest_environment = ENVIRONMENT;
|
||||||
@@ -47,15 +47,6 @@
|
|||||||
* Definitions
|
* Definitions
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
/** Console baudrate always using 115200. */
|
|
||||||
#define CONSOLE_BAUDRATE 115200
|
|
||||||
/** Usart Hw interface used by the console (UART0). */
|
|
||||||
#define CONSOLE_USART UART0
|
|
||||||
/** Usart Hw ID used by the console (UART0). */
|
|
||||||
#define CONSOLE_ID ID_UART0
|
|
||||||
/** Pins description corresponding to Rxd,Txd, (UART pins) */
|
|
||||||
#define CONSOLE_PINS {PINS_UART}
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
* Variables
|
* Variables
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
53
firmware/libboard/owhw/include/board.h
Normal file
53
firmware/libboard/owhw/include/board.h
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "board_common.h"
|
||||||
|
|
||||||
|
/** Name of the board */
|
||||||
|
#define BOARD_NAME "OWHW"
|
||||||
|
/** Board definition */
|
||||||
|
#define owhw
|
||||||
|
|
||||||
|
#define BOARD_MAINOSC 18432000
|
||||||
|
|
||||||
|
/* USIM 2 interface (USART) */
|
||||||
|
#define PIN_USIM2_CLK {PIO_PA2, PIOA, ID_PIOA, PIO_PERIPH_B, PIO_DEFAULT}
|
||||||
|
#define PIN_USIM2_IO {PIO_PA6, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
|
||||||
|
#define PINS_ISO7816_USIM2 PIN_USIM2_CLK, PIN_USIM2_IO
|
||||||
|
|
||||||
|
/* USIM 2 interface (TC) */
|
||||||
|
#define PIN_USIM2_IO_TC {PIO_PA1, PIOA, ID_PIOA, PIO_PERIPH_B, PIO_DEFAULT}
|
||||||
|
#define PIN_USIM2_CLK_TC {PIO_PA4, PIOA, ID_PIOA, PIO_PERIPH_B, PIO_DEFAULT}
|
||||||
|
#define PINS_TC_USIM2 PIN_USIM2_IO_TC, PIN_USIM2_CLK_TC
|
||||||
|
|
||||||
|
/* USIM 1 interface (USART) */
|
||||||
|
#define PIN_USIM1_IO {PIO_PA22, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
|
||||||
|
#define PIN_USIM1_CLK {PIO_PA23, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
|
||||||
|
#define PINS_ISO7816_USIM1 PIN_USIM1_CLK, PIN_USIM1_IO
|
||||||
|
|
||||||
|
/* USIM 1 interface (TC) */
|
||||||
|
#define PIN_USIM1_IO_TC {PIO_PA27, PIOA, ID_PIOA, PIO_PERIPH_B, PIO_DEFAULT}
|
||||||
|
#define PIN_USIM1_CLK_TC {PIO_PA29, PIOA, ID_PIOA, PIO_PERIPH_B, PIO_DEFAULT}
|
||||||
|
#define PINS_TC_USIM1 PIN_USIM1_IO_TC, PIN_USIM1_CLK_TC
|
||||||
|
|
||||||
|
#define PIN_SET_USIM1_PRES {PIO_PA12, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT}
|
||||||
|
#define PIN_USIM1_nRST {PIO_PA24, PIOA, ID_PIOA, PIO_INPUT, PIO_DEFAULT}
|
||||||
|
#define PIN_USIM1_VCC {PIO_PB3, PIOB, ID_PIOB, PIO_INPUT, PIO_DEFAULT}
|
||||||
|
|
||||||
|
#define PIN_SET_USIM2_PRES {PIO_PA14, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT}
|
||||||
|
#define PIN_USIM2_nRST {PIO_PA7, PIOA, ID_PIOA, PIO_INPUT, PIO_DEFAULT}
|
||||||
|
#define PIN_USIM2_VCC {PIO_PB2, PIOB, ID_PIOB, PIO_INPUT, PIO_DEFAULT}
|
||||||
|
|
||||||
|
#define PINS_USIM1 PINS_TC_USIM1, PINS_ISO7816_USIM1, PIN_USIM1_nRST, PIN_SET_USIM1_PRES
|
||||||
|
#define PINS_USIM2 PINS_TC_USIM2, PINS_ISO7816_USIM2, PIN_USIM2_nRST, PIN_SET_USIM2_PRES
|
||||||
|
|
||||||
|
#define PINS_CARDSIM { PIN_SET_USIM1_PRES, PIN_SET_USIM2_PRES }
|
||||||
|
|
||||||
|
#define SIMTRACE_VENDOR_ID 0x1d50
|
||||||
|
#define SIMTRACE_PRODUCT_ID 0x60e3 /* FIXME */
|
||||||
|
#define USB_VENDOR_ID SIMTRACE_VENDOR_ID
|
||||||
|
#define USB_PRODUCT_ID SIMTRACE_PRODUCT_ID
|
||||||
|
|
||||||
|
#define CARDEMU_SECOND_UART
|
||||||
|
/* Disable VCC/ADC detection, as OWHWv2 has no ADCVREF */
|
||||||
|
//#define DETECT_VCC_BY_ADC
|
||||||
|
|
||||||
|
#define HAVE_CARDEM
|
||||||
40
firmware/libboard/owhw/source/owhw.c
Normal file
40
firmware/libboard/owhw/source/owhw.c
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
/* Card simulator specific functions */
|
||||||
|
/* (C) 2015 by Harald Welte <hwelte@hmw-consulting.de>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "chip.h"
|
||||||
|
#include "board.h"
|
||||||
|
#include "utils.h"
|
||||||
|
|
||||||
|
static const Pin pins_cardsim[] = PINS_CARDSIM;
|
||||||
|
|
||||||
|
void cardsim_set_simpres(uint8_t slot, int present)
|
||||||
|
{
|
||||||
|
if (slot > 1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (present)
|
||||||
|
PIO_Set(&pins_cardsim[slot]);
|
||||||
|
else
|
||||||
|
PIO_Clear(&pins_cardsim[slot]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void cardsim_gpio_init(void)
|
||||||
|
{
|
||||||
|
PIO_Configure(&pins_cardsim, ARRAY_SIZE(pins_cardsim));
|
||||||
|
}
|
||||||
66
firmware/libboard/qmod/include/board.h
Normal file
66
firmware/libboard/qmod/include/board.h
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "board_common.h"
|
||||||
|
|
||||||
|
/** Name of the board */
|
||||||
|
#define BOARD_NAME "QMOD"
|
||||||
|
/** Board definition */
|
||||||
|
#define qmod
|
||||||
|
|
||||||
|
#define BOARD_MAINOSC 12000000
|
||||||
|
|
||||||
|
/* USIM 2 interface (USART) */
|
||||||
|
#define PIN_USIM2_CLK {PIO_PA2, PIOA, ID_PIOA, PIO_PERIPH_B, PIO_DEFAULT}
|
||||||
|
#define PIN_USIM2_IO {PIO_PA6, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
|
||||||
|
#define PINS_ISO7816_USIM2 PIN_USIM2_CLK, PIN_USIM2_IO
|
||||||
|
|
||||||
|
/* USIM 2 interface (TC) */
|
||||||
|
#define PIN_USIM2_IO_TC {PIO_PA1, PIOA, ID_PIOA, PIO_PERIPH_B, PIO_DEFAULT}
|
||||||
|
#define PIN_USIM2_CLK_TC {PIO_PA4, PIOA, ID_PIOA, PIO_PERIPH_B, PIO_DEFAULT}
|
||||||
|
#define PINS_TC_USIM2 PIN_USIM2_IO_TC, PIN_USIM2_CLK_TC
|
||||||
|
|
||||||
|
/* USIM 1 interface (USART) */
|
||||||
|
#define PIN_USIM1_IO {PIO_PA22, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
|
||||||
|
#define PIN_USIM1_CLK {PIO_PA23, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
|
||||||
|
#define PINS_ISO7816_USIM1 PIN_USIM1_CLK, PIN_USIM1_IO
|
||||||
|
|
||||||
|
/* USIM 1 interface (TC) */
|
||||||
|
#define PIN_USIM1_IO_TC {PIO_PA27, PIOA, ID_PIOA, PIO_PERIPH_B, PIO_DEFAULT}
|
||||||
|
#define PIN_USIM1_CLK_TC {PIO_PA29, PIOA, ID_PIOA, PIO_PERIPH_B, PIO_DEFAULT}
|
||||||
|
#define PINS_TC_USIM1 PIN_USIM1_IO_TC, PIN_USIM1_CLK_TC
|
||||||
|
|
||||||
|
#define PIN_SET_USIM1_PRES {PIO_PA12, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT}
|
||||||
|
#define PIN_USIM1_nRST {PIO_PA24, PIOA, ID_PIOA, PIO_INPUT, PIO_DEFAULT}
|
||||||
|
#define PIN_USIM1_VCC {PIO_PB3, PIOB, ID_PIOB, PIO_INPUT, PIO_DEFAULT}
|
||||||
|
|
||||||
|
#define PIN_SET_USIM2_PRES {PIO_PA14, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT}
|
||||||
|
#define PIN_USIM2_nRST {PIO_PA7, PIOA, ID_PIOA, PIO_INPUT, PIO_DEFAULT}
|
||||||
|
#define PIN_USIM2_VCC {PIO_PB2, PIOB, ID_PIOB, PIO_INPUT, PIO_DEFAULT}
|
||||||
|
|
||||||
|
#define PINS_USIM1 PINS_TC_USIM1, PINS_ISO7816_USIM1, PIN_USIM1_nRST, PIN_SET_USIM1_PRES
|
||||||
|
#define PINS_USIM2 PINS_TC_USIM2, PINS_ISO7816_USIM2, PIN_USIM2_nRST, PIN_SET_USIM2_PRES
|
||||||
|
|
||||||
|
#define PINS_CARDSIM { PIN_SET_USIM1_PRES, PIN_SET_USIM2_PRES }
|
||||||
|
|
||||||
|
#define PIN_PRTPWR_OVERRIDE {PIO_PA8, PIOA, ID_PIOA, PIO_OUTPUT_1, PIO_DEFAULT}
|
||||||
|
|
||||||
|
/* inputs reading the WWAN LED level */
|
||||||
|
#define PIN_WWAN1 {PIO_PA15, PIOA, ID_PIOA, PIO_INPUT, PIO_PULLUP | PIO_DEGLITCH | PIO_IT_EDGE}
|
||||||
|
#define PIN_WWAN2 {PIO_PA16, PIOA, ID_PIOA, PIO_INPUT, PIO_PULLUP | PIO_DEGLITCH | PIO_IT_EDGE}
|
||||||
|
#define PINS_WWAN_IN { PIN_WWAN1, PIN_WWAN2 }
|
||||||
|
|
||||||
|
/* outputs controlling RESET input of modems */
|
||||||
|
#define PIN_PERST1 {PIO_PA25, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_PULLUP}
|
||||||
|
#define PIN_PERST2 {PIO_PA26, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_PULLUP}
|
||||||
|
#define PINS_PERST { PIN_PERST1, PIN_PERST2 }
|
||||||
|
|
||||||
|
#define PIN_VERSION_DET {PIO_PA19, PIOA, ID_PIOA, PIO_PERIPH_D, PIO_DEFAULT}
|
||||||
|
|
||||||
|
#define SIMTRACE_VENDOR_ID 0x1d50
|
||||||
|
#define SIMTRACE_PRODUCT_ID 0x60e3 /* FIXME */
|
||||||
|
#define USB_VENDOR_ID SIMTRACE_VENDOR_ID
|
||||||
|
#define USB_PRODUCT_ID SIMTRACE_PRODUCT_ID
|
||||||
|
|
||||||
|
#define CARDEMU_SECOND_UART
|
||||||
|
#define DETECT_VCC_BY_ADC
|
||||||
|
|
||||||
|
#define HAVE_CARDEM
|
||||||
5
firmware/libboard/qmod/include/i2c.h
Normal file
5
firmware/libboard/qmod/include/i2c.h
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
void i2c_pin_init(void);
|
||||||
|
int eeprom_write_byte(uint8_t slave, uint8_t addr, uint8_t byte);
|
||||||
|
int eeprom_read_byte(uint8_t slave, uint8_t addr);
|
||||||
4
firmware/libboard/qmod/include/wwan_led.h
Normal file
4
firmware/libboard/qmod/include/wwan_led.h
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
int wwan_led_active(int wwan);
|
||||||
|
int wwan_led_init(void);
|
||||||
4
firmware/libboard/qmod/include/wwan_perst.h
Normal file
4
firmware/libboard/qmod/include/wwan_perst.h
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
int wwan_perst_do_reset(int modem_nr);
|
||||||
|
int wwan_perst_init(void);
|
||||||
201
firmware/libboard/qmod/source/board_qmod.c
Normal file
201
firmware/libboard/qmod/source/board_qmod.c
Normal file
@@ -0,0 +1,201 @@
|
|||||||
|
/* Quad-modem speciic application code */
|
||||||
|
/* (C) 2016-2016 by Harald Welte <laforge@gnumonks.org> */
|
||||||
|
|
||||||
|
#include "board.h"
|
||||||
|
#include "simtrace.h"
|
||||||
|
#include "utils.h"
|
||||||
|
#include "req_ctx.h"
|
||||||
|
#include "wwan_led.h"
|
||||||
|
#include "wwan_perst.h"
|
||||||
|
#include "boardver_adc.h"
|
||||||
|
#include "osmocom/core/timer.h"
|
||||||
|
|
||||||
|
static const Pin pin_hubpwr_override = PIN_PRTPWR_OVERRIDE;
|
||||||
|
static const Pin pin_hub_rst = {PIO_PA13, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT};
|
||||||
|
static const Pin pin_1234_detect = {PIO_PA14, PIOA, ID_PIOA, PIO_INPUT, PIO_PULLUP};
|
||||||
|
static const Pin pin_peer_rst = {PIO_PA0, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT};
|
||||||
|
static const Pin pin_peer_erase = {PIO_PA11, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT};
|
||||||
|
|
||||||
|
|
||||||
|
static int qmod_sam3_is_12(void)
|
||||||
|
{
|
||||||
|
if (PIO_Get(&pin_1234_detect) == 0)
|
||||||
|
return 1;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const unsigned char __eeprom_bin[256] = {
|
||||||
|
0x23, 0x42, 0x17, 0x25, 0x00, 0x00, 0x9b, 0x20, 0x01, 0x00, 0x00, 0x00, 0x32, 0x32, 0x32, 0x32, /* 0x00 - 0x0f */
|
||||||
|
0x32, 0x04, 0x09, 0x18, 0x0d, 0x00, 0x73, 0x00, 0x79, 0x00, 0x73, 0x00, 0x6d, 0x00, 0x6f, 0x00, /* 0x10 - 0x1f */
|
||||||
|
0x63, 0x00, 0x6f, 0x00, 0x6d, 0x00, 0x20, 0x00, 0x2d, 0x00, 0x20, 0x00, 0x73, 0x00, 0x2e, 0x00, /* 0x20 - 0x2f */
|
||||||
|
0x66, 0x00, 0x2e, 0x00, 0x6d, 0x00, 0x2e, 0x00, 0x63, 0x00, 0x2e, 0x00, 0x20, 0x00, 0x47, 0x00, /* 0x30 - 0x3f */
|
||||||
|
0x6d, 0x00, 0x62, 0x00, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40 - 0x4f */
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x71, 0x00, 0x75, 0x00, 0x61, 0x00, 0x64, 0x00, 0x20, 0x00, 0x6d, 0x00, /* 0x50 - 0x5f */
|
||||||
|
0x6f, 0x00, 0x64, 0x00, 0x65, 0x00, 0x6d, 0x00, 0x20, 0x00, 0x76, 0x00, 0x32, 0x00, 0x00, 0x00, /* 0x60 - 0x6f */
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70 - 0x7f */
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80 - 0x8f */
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90 - 0x9f */
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0 - 0xaf */
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0 - 0xbf */
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0 - 0xcf */
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0 - 0xdf */
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0 - 0xef */
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA0, 0x56, 0x23, 0x71, 0x04, 0x00, /* 0xf0 - 0xff */
|
||||||
|
};
|
||||||
|
|
||||||
|
#include "i2c.h"
|
||||||
|
static int write_hub_eeprom(void)
|
||||||
|
{
|
||||||
|
const unsigned int __eeprom_bin_len = 256;
|
||||||
|
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/* wait */
|
||||||
|
volatile int v;
|
||||||
|
/* 440ns per cycle here */
|
||||||
|
for (i = 0; i < 1000000; i++) {
|
||||||
|
v = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
TRACE_INFO("Writing EEPROM...\r\n");
|
||||||
|
/* write the EEPROM once */
|
||||||
|
for (i = 0; i < 256; i++) {
|
||||||
|
int rc = eeprom_write_byte(0x50, i, __eeprom_bin[i]);
|
||||||
|
/* if the result was negative, repeat that write */
|
||||||
|
if (rc < 0)
|
||||||
|
i--;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* then pursue re-reading it again and again */
|
||||||
|
TRACE_INFO("Verifying EEPROM...\r\n");
|
||||||
|
for (i = 0; i < 256; i++) {
|
||||||
|
int byte = eeprom_read_byte(0x50, i);
|
||||||
|
TRACE_INFO("0x%02x: %02x\r\n", i, byte);
|
||||||
|
if (byte != __eeprom_bin[i])
|
||||||
|
TRACE_ERROR("Byte %u is wrong, expected 0x%02x, found 0x%02x\r\n",
|
||||||
|
i, __eeprom_bin[i], byte);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* FIXME: Release PIN_PRTPWR_OVERRIDE after we know the hub is
|
||||||
|
* again powering us up */
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* returns '1' in case we should break any endless loop */
|
||||||
|
void board_exec_dbg_cmd(int ch)
|
||||||
|
{
|
||||||
|
uint32_t addr, val;
|
||||||
|
|
||||||
|
switch (ch) {
|
||||||
|
case '?':
|
||||||
|
printf("\t?\thelp\r\n");
|
||||||
|
printf("\tE\tprogram EEPROM\r\n");
|
||||||
|
printf("\tR\treset SAM3\r\n");
|
||||||
|
printf("\tO\tEnable PRTPWR_OVERRIDE\r\n");
|
||||||
|
printf("\to\tDisable PRTPWR_OVERRIDE\r\n");
|
||||||
|
printf("\tH\tRelease HUB RESET (high)\r\n");
|
||||||
|
printf("\th\tAssert HUB RESET (low)\r\n");
|
||||||
|
printf("\tw\tWrite single byte in EEPROM\r\n");
|
||||||
|
printf("\tr\tRead single byte from EEPROM\r\n");
|
||||||
|
printf("\tX\tRelease peer SAM3 from reset\r\n");
|
||||||
|
printf("\tx\tAssert peer SAM3 reset\r\n");
|
||||||
|
printf("\tY\tRelease peer SAM3 ERASE signal\r\n");
|
||||||
|
printf("\ty\tAssert peer SAM3 ERASE signal\r\n");
|
||||||
|
printf("\tU\tProceed to USB Initialization\r\n");
|
||||||
|
printf("\t1\tGenerate 1ms reset pulse on WWAN1\r\n");
|
||||||
|
printf("\t2\tGenerate 1ms reset pulse on WWAN2\r\n");
|
||||||
|
break;
|
||||||
|
case 'E':
|
||||||
|
write_hub_eeprom();
|
||||||
|
break;
|
||||||
|
case 'R':
|
||||||
|
printf("Asking NVIC to reset us\r\n");
|
||||||
|
NVIC_SystemReset();
|
||||||
|
break;
|
||||||
|
case 'O':
|
||||||
|
printf("Setting PRTPWR_OVERRIDE\r\n");
|
||||||
|
PIO_Set(&pin_hubpwr_override);
|
||||||
|
break;
|
||||||
|
case 'o':
|
||||||
|
printf("Clearing PRTPWR_OVERRIDE\r\n");
|
||||||
|
PIO_Clear(&pin_hubpwr_override);
|
||||||
|
break;
|
||||||
|
case 'H':
|
||||||
|
printf("Clearing _HUB_RESET -> HUB_RESET high (inactive)\r\n");
|
||||||
|
PIO_Clear(&pin_hub_rst);
|
||||||
|
break;
|
||||||
|
case 'h':
|
||||||
|
/* high level drives transistor -> HUB_RESET low */
|
||||||
|
printf("Asserting _HUB_RESET -> HUB_RESET low (active)\r\n");
|
||||||
|
PIO_Set(&pin_hub_rst);
|
||||||
|
break;
|
||||||
|
case 'w':
|
||||||
|
if (PIO_GetOutputDataStatus(&pin_hub_rst) == 0)
|
||||||
|
printf("WARNING: attempting EEPROM access while HUB not in reset\r\n");
|
||||||
|
printf("Please enter EEPROM offset:\r\n");
|
||||||
|
UART_GetIntegerMinMax(&addr, 0, 255);
|
||||||
|
printf("Please enter EEPROM value:\r\n");
|
||||||
|
UART_GetIntegerMinMax(&val, 0, 255);
|
||||||
|
printf("Writing value 0x%02x to EEPROM offset 0x%02x\r\n", val, addr);
|
||||||
|
eeprom_write_byte(0x50, addr, val);
|
||||||
|
break;
|
||||||
|
case 'r':
|
||||||
|
printf("Please enter EEPROM offset:\r\n");
|
||||||
|
UART_GetIntegerMinMax(&addr, 0, 255);
|
||||||
|
printf("EEPROM[0x%02x] = 0x%02x\r\n", addr, eeprom_read_byte(0x50, addr));
|
||||||
|
break;
|
||||||
|
case 'X':
|
||||||
|
printf("Clearing _SIMTRACExx_RST -> SIMTRACExx_RST high (inactive)\r\n");
|
||||||
|
PIO_Clear(&pin_peer_rst);
|
||||||
|
break;
|
||||||
|
case 'x':
|
||||||
|
printf("Setting _SIMTRACExx_RST -> SIMTRACExx_RST low (active)\r\n");
|
||||||
|
PIO_Set(&pin_peer_rst);
|
||||||
|
break;
|
||||||
|
case 'Y':
|
||||||
|
printf("Clearing SIMTRACExx_ERASE (inactive)\r\n");
|
||||||
|
PIO_Clear(&pin_peer_erase);
|
||||||
|
break;
|
||||||
|
case 'y':
|
||||||
|
printf("Seetting SIMTRACExx_ERASE (active)\r\n");
|
||||||
|
PIO_Set(&pin_peer_erase);
|
||||||
|
break;
|
||||||
|
case '1':
|
||||||
|
printf("Resetting Modem 1 (of this SAM3)\r\n");
|
||||||
|
wwan_perst_do_reset(1);
|
||||||
|
break;
|
||||||
|
case '2':
|
||||||
|
printf("Resetting Modem 2 (of this SAM3)\r\n");
|
||||||
|
wwan_perst_do_reset(2);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
printf("Unknown command '%c'\r\n", ch);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void board_main_top(void)
|
||||||
|
{
|
||||||
|
wwan_led_init();
|
||||||
|
wwan_perst_init();
|
||||||
|
|
||||||
|
/* set PIN_PRTPWR_OVERRIDE to output-low to avoid the internal
|
||||||
|
* pull-up on the input to keep SIMTRACE12 alive */
|
||||||
|
PIO_Configure(&pin_hubpwr_override, 1);
|
||||||
|
PIO_Configure(&pin_hub_rst, 1);
|
||||||
|
PIO_Configure(&pin_1234_detect, 1);
|
||||||
|
PIO_Configure(&pin_peer_rst, 1);
|
||||||
|
PIO_Configure(&pin_peer_erase, 1);
|
||||||
|
i2c_pin_init();
|
||||||
|
|
||||||
|
if (qmod_sam3_is_12()) {
|
||||||
|
TRACE_INFO("Detected Quad-Modem ST12\r\n");
|
||||||
|
} else {
|
||||||
|
TRACE_INFO("Detected Quad-Modem ST34\r\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Obtain the circuit board version (currently just prints voltage */
|
||||||
|
get_board_version_adc();
|
||||||
|
}
|
||||||
203
firmware/libboard/qmod/source/i2c.c
Normal file
203
firmware/libboard/qmod/source/i2c.c
Normal file
@@ -0,0 +1,203 @@
|
|||||||
|
#include "board.h"
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
/* Low-Level I2C Routines */
|
||||||
|
|
||||||
|
static const Pin pin_sda = {PIO_PA30, PIOA, ID_PIOA, PIO_OUTPUT_1, PIO_OPENDRAIN };
|
||||||
|
static const Pin pin_sda_in = {PIO_PA30, PIOA, ID_PIOA, PIO_INPUT, PIO_DEFAULT };
|
||||||
|
static const Pin pin_scl = {PIO_PA31, PIOA, ID_PIOA, PIO_OUTPUT_1, PIO_OPENDRAIN };
|
||||||
|
|
||||||
|
static void i2c_delay()
|
||||||
|
{
|
||||||
|
volatile int v;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/* 100 cycles results in SCL peak length of 44us, so it's about
|
||||||
|
* 440ns per cycle here */
|
||||||
|
for (i = 0; i < 14; i++) {
|
||||||
|
v = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void i2c_pin_init(void)
|
||||||
|
{
|
||||||
|
PIO_Configure(&pin_scl, PIO_LISTSIZE(pin_scl));
|
||||||
|
PIO_Configure(&pin_sda, PIO_LISTSIZE(pin_sda));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void set_scl(void)
|
||||||
|
{
|
||||||
|
PIO_Set(&pin_scl);
|
||||||
|
i2c_delay();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void set_sda(void)
|
||||||
|
{
|
||||||
|
PIO_Set(&pin_sda);
|
||||||
|
i2c_delay();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void clear_scl(void)
|
||||||
|
{
|
||||||
|
PIO_Clear(&pin_scl);
|
||||||
|
i2c_delay();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void clear_sda(void)
|
||||||
|
{
|
||||||
|
PIO_Clear(&pin_sda);
|
||||||
|
i2c_delay();
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool read_sda(void)
|
||||||
|
{
|
||||||
|
bool ret;
|
||||||
|
|
||||||
|
PIO_Configure(&pin_sda_in, PIO_LISTSIZE(pin_sda_in));
|
||||||
|
if (PIO_Get(&pin_sda_in))
|
||||||
|
ret = true;
|
||||||
|
else
|
||||||
|
ret = false;
|
||||||
|
PIO_Configure(&pin_sda, PIO_LISTSIZE(pin_sda));
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Core I2C Routines */
|
||||||
|
|
||||||
|
static bool i2c_started = false;
|
||||||
|
|
||||||
|
static void i2c_start_cond(void)
|
||||||
|
{
|
||||||
|
if (i2c_started) {
|
||||||
|
set_sda();
|
||||||
|
set_scl();
|
||||||
|
}
|
||||||
|
|
||||||
|
clear_sda();
|
||||||
|
i2c_delay();
|
||||||
|
clear_scl();
|
||||||
|
i2c_started = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void i2c_stop_cond(void)
|
||||||
|
{
|
||||||
|
clear_sda();
|
||||||
|
set_scl();
|
||||||
|
set_sda();
|
||||||
|
i2c_delay();
|
||||||
|
i2c_started = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void i2c_write_bit(bool bit)
|
||||||
|
{
|
||||||
|
if (bit)
|
||||||
|
set_sda();
|
||||||
|
else
|
||||||
|
clear_sda();
|
||||||
|
i2c_delay(); // ?
|
||||||
|
set_scl();
|
||||||
|
clear_scl();
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool i2c_read_bit(void)
|
||||||
|
{
|
||||||
|
bool bit;
|
||||||
|
|
||||||
|
set_sda();
|
||||||
|
set_scl();
|
||||||
|
bit = read_sda();
|
||||||
|
clear_scl();
|
||||||
|
|
||||||
|
return bit;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool i2c_write_byte(bool send_start, bool send_stop, uint8_t byte)
|
||||||
|
{
|
||||||
|
uint8_t bit;
|
||||||
|
bool nack;
|
||||||
|
|
||||||
|
if (send_start)
|
||||||
|
i2c_start_cond();
|
||||||
|
|
||||||
|
for (bit = 0; bit < 8; bit++) {
|
||||||
|
i2c_write_bit((byte & 0x80) != 0);
|
||||||
|
byte <<= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
nack = i2c_read_bit();
|
||||||
|
|
||||||
|
if (send_stop)
|
||||||
|
i2c_stop_cond();
|
||||||
|
|
||||||
|
return nack;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t i2c_read_byte(bool nack, bool send_stop)
|
||||||
|
{
|
||||||
|
uint8_t byte = 0;
|
||||||
|
uint8_t bit;
|
||||||
|
|
||||||
|
for (bit = 0; bit < 8; bit++) {
|
||||||
|
byte = (byte << 1) | i2c_read_bit();
|
||||||
|
}
|
||||||
|
|
||||||
|
i2c_write_bit(nack);
|
||||||
|
|
||||||
|
if (send_stop)
|
||||||
|
i2c_stop_cond();
|
||||||
|
|
||||||
|
return byte;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* EEPROM related code */
|
||||||
|
|
||||||
|
int eeprom_write_byte(uint8_t slave, uint8_t addr, uint8_t byte)
|
||||||
|
{
|
||||||
|
bool nack;
|
||||||
|
|
||||||
|
/* Write slave address */
|
||||||
|
nack = i2c_write_byte(true, false, slave << 1);
|
||||||
|
if (nack)
|
||||||
|
goto out_stop;
|
||||||
|
nack = i2c_write_byte(false, false, addr);
|
||||||
|
if (nack)
|
||||||
|
goto out_stop;
|
||||||
|
nack = i2c_write_byte(false, true, byte);
|
||||||
|
if (nack)
|
||||||
|
goto out_stop;
|
||||||
|
|
||||||
|
out_stop:
|
||||||
|
i2c_stop_cond();
|
||||||
|
if (nack)
|
||||||
|
return -1;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int eeprom_read_byte(uint8_t slave, uint8_t addr)
|
||||||
|
{
|
||||||
|
bool nack;
|
||||||
|
|
||||||
|
/* dummy write cycle */
|
||||||
|
nack = i2c_write_byte(true, false, slave << 1);
|
||||||
|
if (nack)
|
||||||
|
goto out_stop;
|
||||||
|
nack = i2c_write_byte(false, false, addr);
|
||||||
|
if (nack)
|
||||||
|
goto out_stop;
|
||||||
|
/* Re-start with read */
|
||||||
|
nack = i2c_write_byte(true, false, (slave << 1) | 1);
|
||||||
|
if (nack)
|
||||||
|
goto out_stop;
|
||||||
|
|
||||||
|
return i2c_read_byte(true, true);
|
||||||
|
|
||||||
|
out_stop:
|
||||||
|
i2c_stop_cond();
|
||||||
|
if (nack)
|
||||||
|
return -1;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
80
firmware/libboard/qmod/source/wwan_led.c
Normal file
80
firmware/libboard/qmod/source/wwan_led.c
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
/* Code to read/track the status of the WWAN LEDs of attached modems
|
||||||
|
*
|
||||||
|
* Depending on the board this is running on, it might be possible
|
||||||
|
* for the controller to read the status of the WWAN LED output lines of
|
||||||
|
* the cellular modem. If the board supports this, it sets the
|
||||||
|
* PIN_WWAN1 and/or PIN_WWAN2 defines in its board.h file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "board.h"
|
||||||
|
#include "wwan_led.h"
|
||||||
|
|
||||||
|
#ifdef PIN_WWAN1
|
||||||
|
static const Pin pin_wwan1 = PIN_WWAN1;
|
||||||
|
|
||||||
|
static void wwan1_irqhandler(const Pin *pPin)
|
||||||
|
{
|
||||||
|
int active = wwan_led_active(1);
|
||||||
|
|
||||||
|
TRACE_INFO("WWAN1 LED %u\r\n", active);
|
||||||
|
|
||||||
|
/* TODO: notify host via USB */
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef PIN_WWAN2
|
||||||
|
static const Pin pin_wwan2 = PIN_WWAN2;
|
||||||
|
|
||||||
|
static void wwan2_irqhandler(const Pin *pPin)
|
||||||
|
{
|
||||||
|
int active = wwan_led_active(2);
|
||||||
|
TRACE_INFO("WWAN2 LED %u\r\n", active);
|
||||||
|
|
||||||
|
/* TODO: notify host via USB */
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* determine if a tiven WWAN led is currently active or not */
|
||||||
|
int wwan_led_active(int wwan)
|
||||||
|
{
|
||||||
|
const Pin *pin;
|
||||||
|
int active;
|
||||||
|
|
||||||
|
switch (wwan) {
|
||||||
|
#ifdef PIN_WWAN1
|
||||||
|
case 1:
|
||||||
|
pin = &pin_wwan1;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
#ifdef PIN_WWAN2
|
||||||
|
case 2:
|
||||||
|
pin = &pin_wwan2;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
active = PIO_Get(&pin_wwan1) ? 0 : 1;
|
||||||
|
return active;
|
||||||
|
}
|
||||||
|
|
||||||
|
int wwan_led_init(void)
|
||||||
|
{
|
||||||
|
int num_leds = 0;
|
||||||
|
|
||||||
|
#ifdef PIN_WWAN1
|
||||||
|
PIO_Configure(&pin_wwan1, 1);
|
||||||
|
PIO_ConfigureIt(&pin_wwan1, wwan1_irqhandler);
|
||||||
|
PIO_EnableIt(&pin_wwan1);
|
||||||
|
num_leds++;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef PIN_WWAN2
|
||||||
|
PIO_Configure(&pin_wwan2, 1);
|
||||||
|
PIO_ConfigureIt(&pin_wwan2, wwan2_irqhandler);
|
||||||
|
PIO_EnableIt(&pin_wwan2);
|
||||||
|
num_leds++;
|
||||||
|
#endif
|
||||||
|
return num_leds;
|
||||||
|
}
|
||||||
76
firmware/libboard/qmod/source/wwan_perst.c
Normal file
76
firmware/libboard/qmod/source/wwan_perst.c
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
/* Code to control the PERST lines of attached modems
|
||||||
|
*
|
||||||
|
* Depending on the board this is running on, it might be possible
|
||||||
|
* for the controller to set the status of the PERST input line of
|
||||||
|
* the cellular modem. If the board supports this, it sets the
|
||||||
|
* PIN_PERST1 and/or PIN_PERST2 defines in its board.h file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "board.h"
|
||||||
|
#include "wwan_perst.h"
|
||||||
|
#include "osmocom/core/timer.h"
|
||||||
|
|
||||||
|
#define PERST_DURATION_MS 300
|
||||||
|
|
||||||
|
#ifdef PIN_PERST1
|
||||||
|
static const Pin pin_perst1 = PIN_PERST1;
|
||||||
|
static struct osmo_timer_list perst1_timer;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef PIN_PERST2
|
||||||
|
static const Pin pin_perst2 = PIN_PERST2;
|
||||||
|
static struct osmo_timer_list perst2_timer;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static void perst_tmr_cb(void *data)
|
||||||
|
{
|
||||||
|
const Pin *pin = data;
|
||||||
|
/* release the (low-active) reset */
|
||||||
|
PIO_Clear(pin);
|
||||||
|
}
|
||||||
|
|
||||||
|
int wwan_perst_do_reset(int modem_nr)
|
||||||
|
{
|
||||||
|
const Pin *pin;
|
||||||
|
struct osmo_timer_list *tmr;
|
||||||
|
|
||||||
|
switch (modem_nr) {
|
||||||
|
#ifdef PIN_PERST1
|
||||||
|
case 1:
|
||||||
|
pin = &pin_perst1;
|
||||||
|
tmr = &perst1_timer;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
#ifdef PIN_PERST2
|
||||||
|
case 2:
|
||||||
|
pin = &pin_perst2;
|
||||||
|
tmr = &perst2_timer;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
PIO_Set(pin);
|
||||||
|
osmo_timer_schedule(tmr, PERST_DURATION_MS/1000, (PERST_DURATION_MS%1000)*1000);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int wwan_perst_init(void)
|
||||||
|
{
|
||||||
|
int num_perst = 0;
|
||||||
|
#ifdef PIN_PERST1
|
||||||
|
PIO_Configure(&pin_perst1, 1);
|
||||||
|
perst1_timer.cb = perst_tmr_cb;
|
||||||
|
perst1_timer.data = (void *) &pin_perst1;
|
||||||
|
num_perst++;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef PIN_PERST2
|
||||||
|
PIO_Configure(&pin_perst2, 1);
|
||||||
|
perst2_timer.cb = perst_tmr_cb;
|
||||||
|
perst2_timer.data = (void *) &pin_perst2;
|
||||||
|
num_perst++;
|
||||||
|
#endif
|
||||||
|
return num_perst;
|
||||||
|
}
|
||||||
@@ -1,59 +1,12 @@
|
|||||||
#ifndef _BOARD_
|
#pragma once
|
||||||
#define _BOARD_
|
#include "board_common.h"
|
||||||
|
|
||||||
/** Headers */
|
|
||||||
#include "chip.h"
|
|
||||||
/* We need this for a nop instruction in USB_HAL.c */
|
|
||||||
#define __CC_ARM
|
|
||||||
|
|
||||||
/** Board */
|
|
||||||
#include "board_lowlevel.h"
|
|
||||||
#include "uart_console.h"
|
|
||||||
#include "iso7816_4.h"
|
|
||||||
#include "led.h"
|
|
||||||
#include "cciddriver.h"
|
|
||||||
#include "usart.h"
|
|
||||||
#include "USBD.h"
|
|
||||||
|
|
||||||
#include "USBD_Config.h"
|
|
||||||
#include "USBDDriver.h"
|
|
||||||
|
|
||||||
/** Highlevel */
|
|
||||||
#include "trace.h"
|
|
||||||
#include "stdio.h"
|
|
||||||
#include "stdlib.h"
|
|
||||||
#include "string.h"
|
|
||||||
#include "inttypes.h"
|
|
||||||
|
|
||||||
#include "simtrace.h"
|
|
||||||
|
|
||||||
#define MIN(a, b) ((a < b) ? a : b)
|
|
||||||
|
|
||||||
#ifdef __GNUC__
|
|
||||||
#undef __GNUC__
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/** Name of the board */
|
/** Name of the board */
|
||||||
#define BOARD_NAME "SAM3S-SIMTRACE"
|
#define BOARD_NAME "SAM3S-SIMTRACE"
|
||||||
/** Board definition */
|
/** Board definition */
|
||||||
#define simtrace
|
#define simtrace
|
||||||
/** Family definition (already defined) */
|
|
||||||
#define sam3s
|
|
||||||
/** Core definition */
|
|
||||||
#define cortexm3
|
|
||||||
|
|
||||||
#define BOARD_MAINOSC 18432000
|
#define BOARD_MAINOSC 18432000
|
||||||
#define BOARD_MCK 48000000
|
|
||||||
|
|
||||||
#define LED_RED PIO_PA17
|
|
||||||
#define LED_GREEN PIO_PA18
|
|
||||||
|
|
||||||
#define PIN_LED_RED {LED_RED, PIOA, ID_PIOA, PIO_OUTPUT_1, PIO_DEFAULT}
|
|
||||||
#define PIN_LED_GREEN {LED_GREEN, PIOA, ID_PIOA, PIO_OUTPUT_1, PIO_DEFAULT}
|
|
||||||
#define PINS_LEDS PIN_LED_RED, PIN_LED_GREEN
|
|
||||||
|
|
||||||
#define LED_NUM_RED 0
|
|
||||||
#define LED_NUM_GREEN 1
|
|
||||||
|
|
||||||
/** Phone (SIM card emulator)/CCID Reader/MITM configuration **/
|
/** Phone (SIM card emulator)/CCID Reader/MITM configuration **/
|
||||||
/* Normally the communication lines between phone and SIM card are disconnected */
|
/* Normally the communication lines between phone and SIM card are disconnected */
|
||||||
@@ -72,44 +25,6 @@
|
|||||||
|
|
||||||
#define PINS_SIM_SNIFF_SIM PIN_PHONE_IO, PIN_PHONE_CLK
|
#define PINS_SIM_SNIFF_SIM PIN_PHONE_IO, PIN_PHONE_CLK
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/** USART0 pin RX */
|
|
||||||
#define PIN_USART0_RXD {PIO_PA9A_URXD0, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
|
|
||||||
/** USART0 pin TX */
|
|
||||||
#define PIN_USART0_TXD {PIO_PA10A_UTXD0, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
|
|
||||||
|
|
||||||
#define BOARD_PIN_USART_RXD PIN_USART0_RXD
|
|
||||||
#define BOARD_PIN_USART_TXD PIN_USART0_TXD
|
|
||||||
|
|
||||||
#define BOARD_ID_USART ID_USART0
|
|
||||||
#define BOARD_USART_BASE USART0
|
|
||||||
|
|
||||||
#define PINS_UART { PIO_PA9A_URXD0|PIO_PA10A_UTXD0, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
|
|
||||||
|
|
||||||
/** UART0 */
|
|
||||||
/** Console baudrate always using 115200. */
|
|
||||||
#define CONSOLE_BAUDRATE 115200
|
|
||||||
/** Usart Hw interface used by the console (UART0). */
|
|
||||||
#define CONSOLE_USART UART0
|
|
||||||
/** Usart Hw ID used by the console (UART0). */
|
|
||||||
#define CONSOLE_ID ID_UART0
|
|
||||||
/** Pins description corresponding to Rxd,Txd, (UART pins) */
|
|
||||||
#define CONSOLE_PINS {PINS_UART}
|
|
||||||
|
|
||||||
/// Smartcard detection pin
|
|
||||||
// FIXME: add connect pin as iso pin...should it be periph b or interrupt oder input?
|
|
||||||
#define BOARD_ISO7816_BASE_USART USART0
|
|
||||||
#define BOARD_ISO7816_ID_USART ID_USART0
|
|
||||||
|
|
||||||
#define USART_SIM USART0
|
|
||||||
#define ID_USART_SIM ID_USART0
|
|
||||||
#define USART_PHONE USART1
|
|
||||||
#define ID_USART_PHONE ID_USART1
|
|
||||||
|
|
||||||
#define SIM_PWEN PIO_PA5
|
|
||||||
#define VCC_FWD PIO_PA26
|
|
||||||
|
|
||||||
#define SIM_PWEN_PIN {PIO_PA5, PIOA, ID_PIOA, PIO_OUTPUT_1, PIO_DEFAULT}
|
#define SIM_PWEN_PIN {PIO_PA5, PIOA, ID_PIOA, PIO_OUTPUT_1, PIO_DEFAULT}
|
||||||
|
|
||||||
#define PWR_PINS \
|
#define PWR_PINS \
|
||||||
@@ -118,7 +33,6 @@
|
|||||||
/* Enable second power converter: VCC_PHONE to VCC_SIM; high: on */ \
|
/* Enable second power converter: VCC_PHONE to VCC_SIM; high: on */ \
|
||||||
{VCC_FWD, PIOA, ID_PIOA, PIO_OUTPUT_1, PIO_DEFAULT}
|
{VCC_FWD, PIOA, ID_PIOA, PIO_OUTPUT_1, PIO_DEFAULT}
|
||||||
|
|
||||||
|
|
||||||
#define SW_SIM PIO_PA8
|
#define SW_SIM PIO_PA8
|
||||||
#define SMARTCARD_CONNECT_PIN {SW_SIM, PIOA, ID_PIOA, PIO_INPUT, PIO_PULLUP | PIO_DEBOUNCE | PIO_DEGLITCH | PIO_IT_EDGE }
|
#define SMARTCARD_CONNECT_PIN {SW_SIM, PIOA, ID_PIOA, PIO_INPUT, PIO_PULLUP | PIO_DEBOUNCE | PIO_DEGLITCH | PIO_IT_EDGE }
|
||||||
//#define SMARTCARD_CONNECT_PIN {SW_SIM, PIOB, ID_PIOB, PIO_INPUT, PIO_PULLUP | PIO_DEBOUNCE | PIO_IT_EDGE}
|
//#define SMARTCARD_CONNECT_PIN {SW_SIM, PIOB, ID_PIOB, PIO_INPUT, PIO_PULLUP | PIO_DEBOUNCE | PIO_IT_EDGE}
|
||||||
@@ -160,31 +74,12 @@
|
|||||||
/// SPI chip select 0 pin definition (PA11).
|
/// SPI chip select 0 pin definition (PA11).
|
||||||
#define PIN_SPI_NPCS0 {1 << 11, PIOA, PIOA, PIO_PERIPH_A, PIO_DEFAULT}
|
#define PIN_SPI_NPCS0 {1 << 11, PIOA, PIOA, PIO_PERIPH_A, PIO_DEFAULT}
|
||||||
|
|
||||||
//** USB **/
|
#define SIMTRACE_VENDOR_ID 0x1d50
|
||||||
// USB pull-up control pin definition (PA16).
|
#define SIMTRACE_PRODUCT_ID 0x60e3
|
||||||
// Default: 1 (USB Pullup deactivated)
|
#define USB_VENDOR_ID SIMTRACE_VENDOR_ID
|
||||||
#define PIN_USB_PULLUP {1 << 16, PIOA, ID_PIOA, PIO_OUTPUT_1, PIO_DEFAULT}
|
|
||||||
|
|
||||||
// Board has UDP controller
|
|
||||||
#define BOARD_USB_UDP
|
|
||||||
// D+ has external pull-up
|
|
||||||
#define BOARD_USB_PULLUP_EXTERNAL
|
|
||||||
|
|
||||||
#define BOARD_USB_NUMENDPOINTS 8
|
|
||||||
|
|
||||||
// FIXME: in all other cases return 0?
|
|
||||||
#define BOARD_USB_ENDPOINTS_MAXPACKETSIZE(i) (((i == 4) || (i == 5))? 512 : 64)
|
|
||||||
#define BOARD_USB_ENDPOINTS_BANKS(i) (((i == 0) || (i == 3)) ? 1 : 2)
|
|
||||||
|
|
||||||
/// USB attributes configuration descriptor (bus or self powered, remote wakeup)
|
|
||||||
//#define BOARD_USB_BMATTRIBUTES USBConfigurationDescriptor_SELFPOWERED_NORWAKEUP
|
|
||||||
#define BOARD_USB_BMATTRIBUTES USBConfigurationDescriptor_BUSPOWERED_NORWAKEUP
|
|
||||||
//#define BOARD_USB_BMATTRIBUTES USBConfigurationDescriptor_SELFPOWERED_RWAKEUP
|
|
||||||
|
|
||||||
#define SIMTRACE_VENDOR_ID 0x16c0
|
|
||||||
#define SIMTRACE_PRODUCT_ID 0x0762
|
|
||||||
#define USB_VENDOR_ID OPENPCD_VENDOR_ID
|
|
||||||
#define USB_PRODUCT_ID SIMTRACE_PRODUCT_ID
|
#define USB_PRODUCT_ID SIMTRACE_PRODUCT_ID
|
||||||
|
|
||||||
|
#define HAVE_SNIFFER
|
||||||
#endif
|
#define HAVE_CCID
|
||||||
|
#define HAVE_CARDEM
|
||||||
|
#define HAVE_MITM
|
||||||
115
firmware/libcommon/include/assert.h
Normal file
115
firmware/libcommon/include/assert.h
Normal file
@@ -0,0 +1,115 @@
|
|||||||
|
/* ----------------------------------------------------------------------------
|
||||||
|
* ATMEL Microcontroller Software Support
|
||||||
|
* ----------------------------------------------------------------------------
|
||||||
|
* Copyright (c) 2008, Atmel Corporation
|
||||||
|
*
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* - Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the disclaimer below.
|
||||||
|
*
|
||||||
|
* Atmel's name may not be used to endorse or promote products derived from
|
||||||
|
* this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
|
||||||
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||||||
|
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
|
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||||
|
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
* ----------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
/// \unit
|
||||||
|
///
|
||||||
|
/// !Purpose
|
||||||
|
///
|
||||||
|
/// Definition of the ASSERT() and SANITY_CHECK() macros, which are used for
|
||||||
|
/// runtime condition & parameter verifying.
|
||||||
|
///
|
||||||
|
/// !Usage
|
||||||
|
///
|
||||||
|
/// -# Use ASSERT() in your code to check the value of function parameters,
|
||||||
|
/// return values, etc. *Warning:* the ASSERT() condition must not have
|
||||||
|
/// any side-effect; otherwise, the program may not work properly
|
||||||
|
/// anymore when assertions are disabled.
|
||||||
|
/// -# Use SANITY_CHECK() to perform checks with a default error message
|
||||||
|
/// (outputs the file and line number where the error occured). This
|
||||||
|
/// reduces memory overhead caused by assertion error strings.
|
||||||
|
/// -# Initialize the dbgu to see failed assertions at run-time.
|
||||||
|
/// -# Assertions can be entirely disabled by defining the NOASSERT symbol
|
||||||
|
/// at compilation time.
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#ifndef ASSERT_H
|
||||||
|
#define ASSERT_H
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// Headers
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "trace.h"
|
||||||
|
|
||||||
|
#define assert ASSERT
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// Definitions
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
#if defined(NOASSERT)
|
||||||
|
#define ASSERT(...)
|
||||||
|
#define SANITY_CHECK(...)
|
||||||
|
#else
|
||||||
|
|
||||||
|
#if (TRACE_LEVEL == 0)
|
||||||
|
/// Checks that the given condition is true,
|
||||||
|
/// otherwise stops the program execution.
|
||||||
|
/// \param condition Condition to verify.
|
||||||
|
#define ASSERT(condition) { \
|
||||||
|
if (!(condition)) { \
|
||||||
|
while (1); \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Performs the same duty as the ASSERT() macro
|
||||||
|
/// \param condition Condition to verify.
|
||||||
|
#define SANITY_CHECK(condition) ASSERT(condition, ...)
|
||||||
|
|
||||||
|
#else
|
||||||
|
/// Checks that the given condition is true, otherwise displays an error
|
||||||
|
/// message and stops the program execution.
|
||||||
|
/// \param condition Condition to verify.
|
||||||
|
#define ASSERT(condition) { \
|
||||||
|
if (!(condition)) { \
|
||||||
|
printf("-F- ASSERT: %s %s:%d\r\n", #condition, __BASE_FILE__, __LINE__); \
|
||||||
|
while (1); \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
#define SANITY_ERROR "Sanity check failed at %s:%d\n\r"
|
||||||
|
|
||||||
|
/// Performs the same duty as the ASSERT() macro, except a default error
|
||||||
|
/// message is output if the condition is false.
|
||||||
|
/// \param condition Condition to verify.
|
||||||
|
#define SANITY_CHECK(condition) ASSERT(condition, SANITY_ERROR, __FILE__, __LINE__)
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif //#ifndef ASSERT_H
|
||||||
|
|
||||||
38
firmware/libcommon/include/card_emu.h
Normal file
38
firmware/libcommon/include/card_emu.h
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
struct card_handle;
|
||||||
|
|
||||||
|
enum card_io {
|
||||||
|
CARD_IO_VCC,
|
||||||
|
CARD_IO_RST,
|
||||||
|
CARD_IO_CLK,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct card_handle *card_emu_init(uint8_t slot_num, uint8_t tc_chan, uint8_t uart_chan);
|
||||||
|
|
||||||
|
/* process a single byte received from the reader */
|
||||||
|
void card_emu_process_rx_byte(struct card_handle *ch, uint8_t byte);
|
||||||
|
|
||||||
|
/* transmit a single byte to the reader */
|
||||||
|
int card_emu_tx_byte(struct card_handle *ch);
|
||||||
|
|
||||||
|
/* hardware driver informs us that a card I/O signal has changed */
|
||||||
|
void card_emu_io_statechg(struct card_handle *ch, enum card_io io, int active);
|
||||||
|
|
||||||
|
/* User sets a new ATR to be returned during next card reset */
|
||||||
|
int card_emu_set_atr(struct card_handle *ch, const uint8_t *atr, uint8_t len);
|
||||||
|
|
||||||
|
struct llist_head *card_emu_get_uart_tx_queue(struct card_handle *ch);
|
||||||
|
struct llist_head *card_emu_get_usb_tx_queue(struct card_handle *ch);
|
||||||
|
void card_emu_have_new_uart_tx(struct card_handle *ch);
|
||||||
|
void card_emu_report_status(struct card_handle *ch);
|
||||||
|
|
||||||
|
#define ENABLE_TX 0x01
|
||||||
|
#define ENABLE_RX 0x02
|
||||||
|
|
||||||
|
int card_emu_uart_update_fidi(uint8_t uart_chan, unsigned int fidi);
|
||||||
|
int card_emu_uart_tx(uint8_t uart_chan, uint8_t byte);
|
||||||
|
void card_emu_uart_enable(uint8_t uart_chan, uint8_t rxtx);
|
||||||
|
void card_emu_uart_wait_tx_idle(uint8_t uart_chan);
|
||||||
135
firmware/libcommon/include/cardemu_prot.h
Normal file
135
firmware/libcommon/include/cardemu_prot.h
Normal file
@@ -0,0 +1,135 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
/* Smart Card Emulation USB protocol */
|
||||||
|
|
||||||
|
/* (C) 2015 by Harald Welte <hwelte@hmw-consulting.de>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
/* DT = Device Terminated. DO = Device Originated */
|
||||||
|
enum cardemu_usb_msg_type {
|
||||||
|
/* Bulk out pipe */
|
||||||
|
CEMU_USB_MSGT_DT_TX_DATA, /* TPDU Date */
|
||||||
|
CEMU_USB_MSGT_DT_SET_ATR, /* Set the ATR stored in simulator */
|
||||||
|
CEMU_USB_MSGT_DT_GET_STATS, /* request DO_STATS */
|
||||||
|
CEMU_USB_MSGT_DT_GET_STATUS, /* request DO_STATUS */
|
||||||
|
CEMU_USB_MSGT_DT_CARDINSERT, /* insert/remove card */
|
||||||
|
|
||||||
|
/* Bulk in pipe */
|
||||||
|
CEMU_USB_MSGT_DO_RX_DATA, /* TPDU data */
|
||||||
|
CEMU_USB_MSGT_DO_STATUS, /* Status information */
|
||||||
|
CEMU_USB_MSGT_DO_STATS, /* Statistics */
|
||||||
|
CEMU_USB_MSGT_DO_PTS, /* Information about PTS */
|
||||||
|
CEMU_USB_MSGT_DO_ERROR, /* Error message */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* generic header, shared by all messages */
|
||||||
|
struct cardemu_usb_msg_hdr {
|
||||||
|
uint8_t msg_type; /* enum cardemu_usb_msg_type */
|
||||||
|
uint8_t seq_nr; /* sequence number */
|
||||||
|
uint16_t msg_len; /* length of message including hdr */
|
||||||
|
uint8_t data[0];
|
||||||
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
|
/* indicates a TPDU header is present in this message */
|
||||||
|
#define CEMU_DATA_F_TPDU_HDR 0x00000001
|
||||||
|
/* indicates last part of transmission in this direction */
|
||||||
|
#define CEMU_DATA_F_FINAL 0x00000002
|
||||||
|
/* incdicates a PB is present and we should continue with TX */
|
||||||
|
#define CEMU_DATA_F_PB_AND_TX 0x00000004
|
||||||
|
/* incdicates a PB is present and we should continue with RX */
|
||||||
|
#define CEMU_DATA_F_PB_AND_RX 0x00000008
|
||||||
|
|
||||||
|
/* CEMU_USB_MSGT_DT_CARDINSERT */
|
||||||
|
struct cardemu_usb_msg_cardinsert {
|
||||||
|
struct cardemu_usb_msg_hdr hdr;
|
||||||
|
uint8_t card_insert;
|
||||||
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
|
/* CEMU_USB_MSGT_DT_SET_ATR */
|
||||||
|
struct cardemu_usb_msg_set_atr {
|
||||||
|
struct cardemu_usb_msg_hdr hdr;
|
||||||
|
uint8_t atr_len;
|
||||||
|
/* variable-length ATR data */
|
||||||
|
uint8_t atr[0];
|
||||||
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
|
/* CEMU_USB_MSGT_DT_TX_DATA */
|
||||||
|
struct cardemu_usb_msg_tx_data {
|
||||||
|
struct cardemu_usb_msg_hdr hdr;
|
||||||
|
uint32_t flags;
|
||||||
|
uint16_t data_len;
|
||||||
|
/* variable-length TPDU data */
|
||||||
|
uint8_t data[0];
|
||||||
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
|
/* CEMU_USB_MSGT_DO_RX_DATA */
|
||||||
|
struct cardemu_usb_msg_rx_data {
|
||||||
|
struct cardemu_usb_msg_hdr hdr;
|
||||||
|
uint32_t flags;
|
||||||
|
uint16_t data_len;
|
||||||
|
/* variable-length TPDU data */
|
||||||
|
uint8_t data[0];
|
||||||
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
|
#define CEMU_STATUS_F_VCC_PRESENT 0x00000001
|
||||||
|
#define CEMU_STATUS_F_CLK_ACTIVE 0x00000002
|
||||||
|
#define CEMU_STATUS_F_RCEMU_ACTIVE 0x00000004
|
||||||
|
#define CEMU_STATUS_F_CARD_INSERT 0x00000008
|
||||||
|
#define CEMU_STATUS_F_RESET_ACTIVE 0x00000010
|
||||||
|
|
||||||
|
/* CEMU_USB_MSGT_DO_STATUS */
|
||||||
|
struct cardemu_usb_msg_status {
|
||||||
|
struct cardemu_usb_msg_hdr hdr;
|
||||||
|
uint32_t flags;
|
||||||
|
/* phone-applied target voltage in mV */
|
||||||
|
uint16_t voltage_mv;
|
||||||
|
/* Fi/Di related information */
|
||||||
|
uint8_t fi;
|
||||||
|
uint8_t di;
|
||||||
|
uint8_t wi;
|
||||||
|
uint32_t waiting_time;
|
||||||
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
|
/* CEMU_USB_MSGT_DO_PTS */
|
||||||
|
struct cardemu_usb_msg_pts_info {
|
||||||
|
struct cardemu_usb_msg_hdr hdr;
|
||||||
|
uint8_t pts_len;
|
||||||
|
/* PTS request as sent from reader */
|
||||||
|
uint8_t req[6];
|
||||||
|
/* PTS response as sent by card */
|
||||||
|
uint8_t resp[6];
|
||||||
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
|
/* CEMU_USB_MSGT_DO_ERROR */
|
||||||
|
struct cardemu_usb_msg_error {
|
||||||
|
struct cardemu_usb_msg_hdr hdr;
|
||||||
|
uint8_t severity;
|
||||||
|
uint8_t subsystem;
|
||||||
|
uint16_t code;
|
||||||
|
uint8_t msg_len;
|
||||||
|
/* human-readable error message */
|
||||||
|
uint8_t msg[0];
|
||||||
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
|
static inline void cardemu_hdr_set(struct cardemu_usb_msg_hdr *hdr, uint16_t msgt)
|
||||||
|
{
|
||||||
|
memset(hdr, 0, sizeof(*hdr));
|
||||||
|
hdr->msg_type = msgt;
|
||||||
|
}
|
||||||
6
firmware/libcommon/include/iso7816_fidi.h
Normal file
6
firmware/libcommon/include/iso7816_fidi.h
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
/* compute the F/D ratio based on Fi and Di values */
|
||||||
|
int compute_fidi_ratio(uint8_t fi, uint8_t di);
|
||||||
27
firmware/libcommon/include/llist_irqsafe.h
Normal file
27
firmware/libcommon/include/llist_irqsafe.h
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "osmocom/core/linuxlist.h"
|
||||||
|
|
||||||
|
static inline void llist_add_tail_irqsafe(struct llist_head *_new,
|
||||||
|
struct llist_head *head)
|
||||||
|
{
|
||||||
|
__disable_irq();
|
||||||
|
llist_add_tail(_new, head);
|
||||||
|
__enable_irq();
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline struct llist_head *llist_head_dequeue_irqsafe(struct llist_head *head)
|
||||||
|
{
|
||||||
|
struct llist_head *lh;
|
||||||
|
|
||||||
|
__disable_irq();
|
||||||
|
if (llist_empty(head)) {
|
||||||
|
lh = NULL;
|
||||||
|
} else {
|
||||||
|
lh = head->next;
|
||||||
|
llist_del(lh);
|
||||||
|
}
|
||||||
|
__enable_irq();
|
||||||
|
|
||||||
|
return lh;
|
||||||
|
}
|
||||||
61
firmware/libcommon/include/req_ctx.h
Normal file
61
firmware/libcommon/include/req_ctx.h
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#define RCTX_SIZE_LARGE 960
|
||||||
|
#define RCTX_SIZE_SMALL 320
|
||||||
|
#define MAX_HDRSIZE sizeof(struct openpcd_hdr)
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "osmocom/core/linuxlist.h"
|
||||||
|
|
||||||
|
#define __ramfunc
|
||||||
|
|
||||||
|
enum req_ctx_state {
|
||||||
|
/* free to be allocated */
|
||||||
|
RCTX_S_FREE,
|
||||||
|
|
||||||
|
/* USB -> UART */
|
||||||
|
/* In USB driver, waiting for data from host */
|
||||||
|
RCTX_S_USB_RX_BUSY,
|
||||||
|
/* somewhere in the main loop */
|
||||||
|
RCTX_S_MAIN_PROCESSING,
|
||||||
|
/* pending (in queue) for transmission on UART */
|
||||||
|
RCTX_S_UART_TX_PENDING,
|
||||||
|
/* currently in active transmission on UART */
|
||||||
|
RCTX_S_UART_TX_BUSY,
|
||||||
|
|
||||||
|
/* UART -> USB */
|
||||||
|
/* currently in active reception on UART */
|
||||||
|
RCTX_S_UART_RX_BUSY,
|
||||||
|
/* pending (in queue) for transmission over USB to host */
|
||||||
|
RCTX_S_USB_TX_PENDING,
|
||||||
|
/* currently in transmission over USB to host */
|
||||||
|
RCTX_S_USB_TX_BUSY,
|
||||||
|
|
||||||
|
/* number of states */
|
||||||
|
RCTX_STATE_COUNT
|
||||||
|
};
|
||||||
|
|
||||||
|
struct req_ctx {
|
||||||
|
/* if this req_ctx is on a queue... */
|
||||||
|
struct llist_head list;
|
||||||
|
uint32_t ep;
|
||||||
|
|
||||||
|
/* enum req_ctx_state */
|
||||||
|
volatile uint32_t state;
|
||||||
|
/* size of th 'data' buffer */
|
||||||
|
uint16_t size;
|
||||||
|
/* total number of used bytes in buffer */
|
||||||
|
uint16_t tot_len;
|
||||||
|
/* index into the buffer, user specific */
|
||||||
|
uint16_t idx;
|
||||||
|
/* actual data buffer */
|
||||||
|
uint8_t *data;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern void req_ctx_init(void);
|
||||||
|
extern struct req_ctx __ramfunc *req_ctx_find_get(int large, uint32_t old_state, uint32_t new_state);
|
||||||
|
extern struct req_ctx *req_ctx_find_busy(void);
|
||||||
|
extern void req_ctx_set_state(struct req_ctx *ctx, uint32_t new_state);
|
||||||
|
extern void req_ctx_put(struct req_ctx *ctx);
|
||||||
|
extern uint8_t req_ctx_num(struct req_ctx *ctx);
|
||||||
|
unsigned int req_ctx_count(uint32_t state);
|
||||||
23
firmware/libcommon/include/ringbuffer.h
Normal file
23
firmware/libcommon/include/ringbuffer.h
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
#ifndef SIMTRACE_RINGBUF_H
|
||||||
|
#define SIMTRACE_RINGBUF_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#define RING_BUFLEN 128
|
||||||
|
|
||||||
|
typedef struct ringbuf {
|
||||||
|
uint8_t buf[RING_BUFLEN];
|
||||||
|
size_t ird;
|
||||||
|
size_t iwr;
|
||||||
|
} ringbuf;
|
||||||
|
|
||||||
|
void rbuf_reset(volatile ringbuf * rb);
|
||||||
|
uint8_t rbuf_read(volatile ringbuf * rb);
|
||||||
|
uint8_t rbuf_peek(volatile ringbuf * rb);
|
||||||
|
void rbuf_write(volatile ringbuf * rb, uint8_t item);
|
||||||
|
bool rbuf_is_empty(volatile ringbuf * rb);
|
||||||
|
bool rbuf_is_full(volatile ringbuf * rb);
|
||||||
|
|
||||||
|
#endif /* end of include guard: SIMTRACE_RINGBUF_H */
|
||||||
@@ -2,6 +2,7 @@
|
|||||||
#define SIMTRACE_H
|
#define SIMTRACE_H
|
||||||
|
|
||||||
#include "ringbuffer.h"
|
#include "ringbuffer.h"
|
||||||
|
#include "board.h"
|
||||||
|
|
||||||
/* Endpoint numbers */
|
/* Endpoint numbers */
|
||||||
#define DATAOUT 1
|
#define DATAOUT 1
|
||||||
@@ -14,6 +15,10 @@
|
|||||||
#define PHONE_DATAIN 5
|
#define PHONE_DATAIN 5
|
||||||
#define PHONE_INT 6
|
#define PHONE_INT 6
|
||||||
|
|
||||||
|
#define CARDEM_USIM2_DATAOUT DATAOUT
|
||||||
|
#define CARDEM_USIM2_DATAIN DATAIN
|
||||||
|
#define CARDEM_USIM2_INT INT
|
||||||
|
|
||||||
#define CLK_MASTER true
|
#define CLK_MASTER true
|
||||||
#define CLK_SLAVE false
|
#define CLK_SLAVE false
|
||||||
|
|
||||||
@@ -29,12 +34,24 @@ extern volatile ringbuf sim_rcv_buf;
|
|||||||
|
|
||||||
extern volatile bool rcvdChar;
|
extern volatile bool rcvdChar;
|
||||||
extern volatile uint32_t char_stat;
|
extern volatile uint32_t char_stat;
|
||||||
extern volatile enum confNum simtrace_config;
|
|
||||||
|
|
||||||
extern const Pin pinPhoneRST;
|
extern const Pin pinPhoneRST;
|
||||||
|
|
||||||
enum confNum {
|
enum confNum {
|
||||||
CFG_NUM_SNIFF = 1, CFG_NUM_CCID, CFG_NUM_PHONE, CFG_NUM_MITM, NUM_CONF
|
CFG_NUM_NONE = 0,
|
||||||
|
#ifdef HAVE_SNIFFER
|
||||||
|
CFG_NUM_SNIFF,
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_CCID
|
||||||
|
CFG_NUM_CCID,
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_CARDEM
|
||||||
|
CFG_NUM_PHONE,
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_MITM
|
||||||
|
CFG_NUM_MITM,
|
||||||
|
#endif
|
||||||
|
NUM_CONF
|
||||||
};
|
};
|
||||||
|
|
||||||
/// CCIDDriverConfiguration Descriptors
|
/// CCIDDriverConfiguration Descriptors
|
||||||
@@ -66,13 +83,13 @@ void ISR_PhoneRST( const Pin *pPin);
|
|||||||
/* Configure functions */
|
/* Configure functions */
|
||||||
extern void Sniffer_configure( void );
|
extern void Sniffer_configure( void );
|
||||||
extern void CCID_configure( void );
|
extern void CCID_configure( void );
|
||||||
extern void Phone_configure( void );
|
extern void mode_cardemu_configure(void);
|
||||||
extern void MITM_configure( void );
|
extern void MITM_configure( void );
|
||||||
|
|
||||||
/* Init functions */
|
/* Init functions */
|
||||||
extern void Sniffer_init( void );
|
extern void Sniffer_init( void );
|
||||||
extern void CCID_init( void );
|
extern void CCID_init( void );
|
||||||
extern void Phone_init( void );
|
extern void mode_cardemu_init(void);
|
||||||
extern void MITM_init( void );
|
extern void MITM_init( void );
|
||||||
|
|
||||||
extern void SIMtrace_USB_Initialize( void );
|
extern void SIMtrace_USB_Initialize( void );
|
||||||
@@ -80,17 +97,24 @@ extern void SIMtrace_USB_Initialize( void );
|
|||||||
/* Exit functions */
|
/* Exit functions */
|
||||||
extern void Sniffer_exit( void );
|
extern void Sniffer_exit( void );
|
||||||
extern void CCID_exit( void );
|
extern void CCID_exit( void );
|
||||||
extern void Phone_exit( void );
|
extern void mode_cardemu_exit(void);
|
||||||
extern void MITM_exit( void );
|
extern void MITM_exit( void );
|
||||||
|
|
||||||
/* Run functions */
|
/* Run functions */
|
||||||
extern void Sniffer_run( void );
|
extern void Sniffer_run( void );
|
||||||
extern void CCID_run( void );
|
extern void CCID_run( void );
|
||||||
extern void Phone_run( void );
|
extern void mode_cardemu_run(void);
|
||||||
extern void MITM_run( void );
|
extern void MITM_run( void );
|
||||||
|
|
||||||
|
extern void mode_cardemu_usart0_irq(void);
|
||||||
|
extern void mode_cardemu_usart1_irq(void);
|
||||||
|
|
||||||
/* Timer helper function */
|
/* Timer helper function */
|
||||||
void Timer_Init( void );
|
void Timer_Init( void );
|
||||||
void TC0_Counter_Reset( void );
|
void TC0_Counter_Reset( void );
|
||||||
|
|
||||||
|
struct llist_head;
|
||||||
|
int usb_refill_to_host(struct llist_head *queue, uint32_t ep);
|
||||||
|
int usb_refill_from_host(struct llist_head *queue, int ep);
|
||||||
|
|
||||||
#endif /* SIMTRACE_H */
|
#endif /* SIMTRACE_H */
|
||||||
32
firmware/libcommon/include/stdio.h
Normal file
32
firmware/libcommon/include/stdio.h
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef EOF
|
||||||
|
#define EOF (-1)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct File;
|
||||||
|
typedef struct File FILE;
|
||||||
|
|
||||||
|
extern FILE* const stdin;
|
||||||
|
extern FILE* const stdout;
|
||||||
|
extern FILE* const stderr;
|
||||||
|
|
||||||
|
signed int vsnprintf(char *pStr, size_t length, const char *pFormat, va_list ap);
|
||||||
|
signed int snprintf(char *pString, size_t length, const char *pFormat, ...);
|
||||||
|
signed int vsprintf(char *pString, const char *pFormat, va_list ap);
|
||||||
|
signed int vfprintf(FILE *pStream, const char *pFormat, va_list ap);
|
||||||
|
signed int vprintf(const char *pFormat, va_list ap);
|
||||||
|
signed int fprintf(FILE *pStream, const char *pFormat, ...);
|
||||||
|
signed int printf(const char *pFormat, ...);
|
||||||
|
signed int sprintf(char *pStr, const char *pFormat, ...);
|
||||||
|
signed int puts(const char *pStr);
|
||||||
|
|
||||||
|
|
||||||
|
int fputc(int c, FILE *stream);
|
||||||
|
int fputs(const char *s, FILE *stream);
|
||||||
|
|
||||||
|
#define putc(c, stream) fputc(c, stream)
|
||||||
|
#define putchar(c) fputc(c, stdout)
|
||||||
@@ -50,8 +50,6 @@
|
|||||||
|
|
||||||
extern caddr_t _sbrk ( int incr ) ;
|
extern caddr_t _sbrk ( int incr ) ;
|
||||||
|
|
||||||
extern int link( char *old, char *new ) ;
|
|
||||||
|
|
||||||
extern int _close( int file ) ;
|
extern int _close( int file ) ;
|
||||||
|
|
||||||
extern int _fstat( int file, struct stat *st ) ;
|
extern int _fstat( int file, struct stat *st ) ;
|
||||||
@@ -63,3 +61,5 @@ extern int _lseek( int file, int ptr, int dir ) ;
|
|||||||
extern int _read(int file, char *ptr, int len) ;
|
extern int _read(int file, char *ptr, int len) ;
|
||||||
|
|
||||||
extern int _write( int file, char *ptr, int len ) ;
|
extern int _write( int file, char *ptr, int len ) ;
|
||||||
|
|
||||||
|
extern void mdelay(unsigned int msecs);
|
||||||
11
firmware/libcommon/include/tc_etu.h
Normal file
11
firmware/libcommon/include/tc_etu.h
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
void tc_etu_set_wtime(uint8_t chan_nr, uint16_t wtime);
|
||||||
|
void tc_etu_set_etu(uint8_t chan_nr, uint16_t etu);
|
||||||
|
void tc_etu_init(uint8_t chan_nr, void *handle);
|
||||||
|
void tc_etu_enable(uint8_t chan_nr);
|
||||||
|
void tc_etu_disable(uint8_t chan_nr);
|
||||||
|
|
||||||
|
extern void tc_etu_wtime_half_expired(void *handle);
|
||||||
|
extern void tc_etu_wtime_expired(void *handle);
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user