aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--demos/ARM7-AT91SAM7X-GCC/Makefile25
-rw-r--r--demos/ARM7-AT91SAM7X-WEB-GCC/Makefile31
-rw-r--r--demos/ARM7-LPC214x-G++/Makefile31
-rw-r--r--demos/ARM7-LPC214x-GCC-minimal/Makefile28
-rw-r--r--demos/ARM7-LPC214x-GCC/Makefile34
-rw-r--r--demos/ARMCM3-STM32F103-GCC/Makefile32
-rw-r--r--demos/AVR-AT90CANx-GCC/Makefile14
-rw-r--r--demos/AVR-ATmega128-GCC/Makefile14
-rw-r--r--demos/MSP430-MSP430x1611-GCC/Makefile22
-rw-r--r--demos/Win32-MinGW/Makefile14
-rw-r--r--os/io/pal.c94
-rw-r--r--os/io/pal.h460
-rw-r--r--os/io/readme.txt1
-rw-r--r--os/kernel/include/ch.h89
-rw-r--r--os/kernel/include/channels.h292
-rw-r--r--os/kernel/include/condvars.h80
-rw-r--r--os/kernel/include/debug.h149
-rw-r--r--os/kernel/include/events.h145
-rw-r--r--os/kernel/include/heap.h43
-rw-r--r--os/kernel/include/inline.h72
-rw-r--r--os/kernel/include/lists.h92
-rw-r--r--os/kernel/include/mailboxes.h126
-rw-r--r--os/kernel/include/mempools.h82
-rw-r--r--os/kernel/include/messages.h59
-rw-r--r--os/kernel/include/mutexes.h84
-rw-r--r--os/kernel/include/queues.h218
-rw-r--r--os/kernel/include/scheduler.h110
-rw-r--r--os/kernel/include/semaphores.h99
-rw-r--r--os/kernel/include/serial.h217
-rw-r--r--os/kernel/include/sys.h184
-rw-r--r--os/kernel/include/threads.h269
-rw-r--r--os/kernel/include/vt.h125
-rw-r--r--os/kernel/kernel.mk13
-rw-r--r--os/kernel/readme.txt1
-rw-r--r--os/kernel/src/chcond.c227
-rw-r--r--os/kernel/src/chdebug.c81
-rw-r--r--os/kernel/src/chevents.c392
-rw-r--r--os/kernel/src/chheap.c276
-rw-r--r--os/kernel/src/chlists.c111
-rw-r--r--os/kernel/src/chmboxes.c244
-rw-r--r--os/kernel/src/chmempools.c112
-rw-r--r--os/kernel/src/chmsg.c125
-rw-r--r--os/kernel/src/chmtx.c299
-rw-r--r--os/kernel/src/chqueues.c304
-rw-r--r--os/kernel/src/chschd.c242
-rw-r--r--os/kernel/src/chsem.c257
-rw-r--r--os/kernel/src/chserial.c168
-rw-r--r--os/kernel/src/chsys.c129
-rw-r--r--os/kernel/src/chthreads.c381
-rw-r--r--os/kernel/src/chvt.c116
-rw-r--r--os/ports/GCC/ARM/rules.mk136
-rw-r--r--os/ports/GCC/ARM7/AT91SAM7X/mii.h156
-rw-r--r--os/ports/GCC/ARM7/AT91SAM7X/pal_lld.c116
-rw-r--r--os/ports/GCC/ARM7/AT91SAM7X/pal_lld.h245
-rw-r--r--os/ports/GCC/ARM7/AT91SAM7X/port.dox73
-rw-r--r--os/ports/GCC/ARM7/AT91SAM7X/sam7x_emac.c418
-rw-r--r--os/ports/GCC/ARM7/AT91SAM7X/sam7x_emac.h93
-rw-r--r--os/ports/GCC/ARM7/AT91SAM7X/sam7x_serial.c224
-rw-r--r--os/ports/GCC/ARM7/AT91SAM7X/sam7x_serial.h86
-rw-r--r--os/ports/GCC/ARM7/AT91SAM7X/vectors.s74
-rw-r--r--os/ports/GCC/ARM7/AT91SAM7X/wfi.h35
-rw-r--r--os/ports/GCC/ARM7/LPC214x/lpc214x.h523
-rw-r--r--os/ports/GCC/ARM7/LPC214x/lpc214x_serial.c268
-rw-r--r--os/ports/GCC/ARM7/LPC214x/lpc214x_serial.h102
-rw-r--r--os/ports/GCC/ARM7/LPC214x/lpc214x_ssp.c133
-rw-r--r--os/ports/GCC/ARM7/LPC214x/lpc214x_ssp.h54
-rw-r--r--os/ports/GCC/ARM7/LPC214x/pal_lld.c89
-rw-r--r--os/ports/GCC/ARM7/LPC214x/pal_lld.h252
-rw-r--r--os/ports/GCC/ARM7/LPC214x/port.dox83
-rw-r--r--os/ports/GCC/ARM7/LPC214x/vectors.s71
-rw-r--r--os/ports/GCC/ARM7/LPC214x/vic.c63
-rw-r--r--os/ports/GCC/ARM7/LPC214x/vic.h41
-rw-r--r--os/ports/GCC/ARM7/LPC214x/wfi.h35
-rw-r--r--os/ports/GCC/ARM7/chcore.c42
-rw-r--r--os/ports/GCC/ARM7/chcore.h331
-rw-r--r--os/ports/GCC/ARM7/chcore.lst48
-rw-r--r--os/ports/GCC/ARM7/chcoreasm.s234
-rw-r--r--os/ports/GCC/ARM7/chtypes.h56
-rw-r--r--os/ports/GCC/ARM7/crt0.lst218
-rw-r--r--os/ports/GCC/ARM7/crt0.s181
-rw-r--r--os/ports/GCC/ARM7/port.dox200
-rw-r--r--os/ports/GCC/ARM7/port.mk7
-rw-r--r--os/ports/GCC/ARMCM3/STM32F103/pal_lld.c158
-rw-r--r--os/ports/GCC/ARMCM3/STM32F103/pal_lld.h307
-rw-r--r--os/ports/GCC/ARMCM3/STM32F103/port.dox72
-rw-r--r--os/ports/GCC/ARMCM3/STM32F103/stm32_can.c27
-rw-r--r--os/ports/GCC/ARMCM3/STM32F103/stm32_can.h48
-rw-r--r--os/ports/GCC/ARMCM3/STM32F103/stm32_serial.c222
-rw-r--r--os/ports/GCC/ARMCM3/STM32F103/stm32_serial.h122
-rw-r--r--os/ports/GCC/ARMCM3/STM32F103/stm32f10x.h7851
-rw-r--r--os/ports/GCC/ARMCM3/STM32F103/vectors.s256
-rw-r--r--os/ports/GCC/ARMCM3/chcore.c177
-rw-r--r--os/ports/GCC/ARMCM3/chcore.h333
-rw-r--r--os/ports/GCC/ARMCM3/chtypes.h56
-rw-r--r--os/ports/GCC/ARMCM3/cmsis/core_cm3.c829
-rw-r--r--os/ports/GCC/ARMCM3/cmsis/core_cm3.h1374
-rw-r--r--os/ports/GCC/ARMCM3/crt0.s128
-rw-r--r--os/ports/GCC/ARMCM3/nvic.c57
-rw-r--r--os/ports/GCC/ARMCM3/nvic.h190
-rw-r--r--os/ports/GCC/ARMCM3/port.dox170
-rw-r--r--os/ports/GCC/ARMCM3/port.mk9
-rw-r--r--os/ports/GCC/AVR/avr_serial.c185
-rw-r--r--os/ports/GCC/AVR/avr_serial.h92
-rw-r--r--os/ports/GCC/AVR/chcore.c125
-rw-r--r--os/ports/GCC/AVR/chcore.h267
-rw-r--r--os/ports/GCC/AVR/chtypes.h56
-rw-r--r--os/ports/GCC/AVR/port.dox95
-rw-r--r--os/ports/GCC/AVR/port.mk6
-rw-r--r--os/ports/GCC/MSP430/chcore.c90
-rw-r--r--os/ports/GCC/MSP430/chcore.h238
-rw-r--r--os/ports/GCC/MSP430/chtypes.h56
-rw-r--r--os/ports/GCC/MSP430/msp430_serial.c216
-rw-r--r--os/ports/GCC/MSP430/msp430_serial.h91
-rw-r--r--os/ports/GCC/MSP430/pal_lld.c115
-rw-r--r--os/ports/GCC/MSP430/pal_lld.h292
-rw-r--r--os/ports/GCC/MSP430/port.dox124
-rw-r--r--os/ports/GCC/MSP430/port.mk6
-rw-r--r--os/ports/GCC/MSP430/rules.mk87
-rw-r--r--os/ports/GCC/Win32/simcom.c227
-rw-r--r--os/ports/GCC/Win32/simio.c201
-rw-r--r--os/templates/chconf.h388
-rw-r--r--os/templates/chcore.c133
-rw-r--r--os/templates/chcore.h159
-rw-r--r--os/templates/chtypes.h79
-rw-r--r--os/templates/pal_lld.h322
-rw-r--r--os/various/ch.cpp335
-rw-r--r--os/various/ch.hpp618
-rw-r--r--os/various/evtimer.c70
-rw-r--r--os/various/evtimer.h62
-rw-r--r--readme.txt3
-rw-r--r--test/coverage/Makefile12
131 files changed, 28513 insertions, 123 deletions
diff --git a/demos/ARM7-AT91SAM7X-GCC/Makefile b/demos/ARM7-AT91SAM7X-GCC/Makefile
index db19978c8..4622e181f 100644
--- a/demos/ARM7-AT91SAM7X-GCC/Makefile
+++ b/demos/ARM7-AT91SAM7X-GCC/Makefile
@@ -43,16 +43,18 @@ PROJECT = ch
LDSCRIPT= ch.ld
# Imported source files
-include ../../src/kernel.mk
+include ../../os/ports/GCC/ARM7/port.mk
+include ../../os/kernel/kernel.mk
include ../../test/test.mk
# C sources that can be compiled in ARM or THUMB mode depending on the global
# setting.
-CSRC = ../../ports/ARM7/chcore.c \
- ../../ports/ARM7-AT91SAM7X/pal_lld.c \
- ../../ports/ARM7-AT91SAM7X/sam7x_serial.c \
+CSRC = ${PORTSRC} \
${KERNSRC} \
${TESTSRC} \
+ ../../os/io/pal.c \
+ ../../os/ports/GCC/ARM7/AT91SAM7X/pal_lld.c \
+ ../../os/ports/GCC/ARM7/AT91SAM7X/sam7x_serial.c \
at91lib/aic.c \
board.c main.c
@@ -81,14 +83,13 @@ TCSRC =
TCPPSRC =
# List ASM source files here
-ASMSRC = ../../ports/ARM7/crt0.s \
- ../../ports/ARM7-AT91SAM7X/vectors.s \
- ../../ports/ARM7/chcoreasm.s
+ASMSRC = $(PORTASM) \
+ ../../os/ports/GCC/ARM7/AT91SAM7X/vectors.s
-INCDIR = $(KERNINC) $(TESTINC) \
- ../../src/lib \
- ../../ports/ARM7 \
- ../../ports/ARM7-AT91SAM7X
+INCDIR = $(PORTINC) $(KERNINC) $(TESTINC) \
+ ../../os/io \
+ ../../os/ports/GCC/ARM7/AT91SAM7X \
+ ../../os/various
#
# Project, sources and paths
@@ -176,4 +177,4 @@ ULIBS =
# End of user defines
##############################################################################
-include ../../ports/ARM/rules.mk
+include ../../os/ports/GCC/ARM/rules.mk
diff --git a/demos/ARM7-AT91SAM7X-WEB-GCC/Makefile b/demos/ARM7-AT91SAM7X-WEB-GCC/Makefile
index 4b0aad5a1..0e881c364 100644
--- a/demos/ARM7-AT91SAM7X-WEB-GCC/Makefile
+++ b/demos/ARM7-AT91SAM7X-WEB-GCC/Makefile
@@ -43,7 +43,8 @@ PROJECT = ch
LDSCRIPT= ch.ld
# Imported source files
-include ../../src/kernel.mk
+include ../../os/ports/GCC/ARM7/port.mk
+include ../../os/kernel/kernel.mk
include ../../test/test.mk
# List of the required uIP source files.
@@ -57,14 +58,15 @@ USRC = ../../ext/uip-1.0/uip/uip_arp.c \
# C sources that can be compiled in ARM or THUMB mode depending on the global
# setting.
-CSRC = ../../ports/ARM7/chcore.c \
- ../../ports/ARM7-AT91SAM7X/pal_lld.c \
- ../../ports/ARM7-AT91SAM7X/sam7x_serial.c \
- ../../ports/ARM7-AT91SAM7X/sam7x_emac.c \
+CSRC = ${PORTSRC} \
${KERNSRC} \
${TESTSRC} \
${USRC} \
- ../../src/lib/evtimer.c \
+ ../../os/io/pal.c \
+ ../../os/ports/GCC/ARM7/AT91SAM7X/pal_lld.c \
+ ../../os/ports/GCC/ARM7/AT91SAM7X/sam7x_serial.c \
+ ../../os/ports/GCC/ARM7/AT91SAM7X/sam7x_emac.c \
+ ../../os/various/evtimer.c \
at91lib/aic.c \
web/webthread.c \
board.c main.c
@@ -94,14 +96,13 @@ TCSRC =
TCPPSRC =
# List ASM source files here
-ASMSRC = ../../ports/ARM7/crt0.s \
- ../../ports/ARM7-AT91SAM7X/vectors.s \
- ../../ports/ARM7/chcoreasm.s
-
-INCDIR = $(KERNINC) $(TESTINC) \
- ../../src/lib \
- ../../ports/ARM7 \
- ../../ports/ARM7-AT91SAM7X \
+ASMSRC = $(PORTASM) \
+ ../../os/ports/GCC/ARM7/AT91SAM7X/vectors.s
+
+INCDIR = $(PORTINC) $(KERNINC) $(TESTINC) \
+ ../../os/io \
+ ../../os/ports/GCC/ARM7/AT91SAM7X \
+ ../../os/various \
./web ../../ext/uip-1.0/uip ../../ext/uip-1.0/apps/webserver
#
@@ -190,4 +191,4 @@ ULIBS =
# End of user defines
##############################################################################
-include ../../ports/ARM/rules.mk
+include ../../os/ports/GCC/ARM/rules.mk
diff --git a/demos/ARM7-LPC214x-G++/Makefile b/demos/ARM7-LPC214x-G++/Makefile
index 894a37e61..5709a5dd3 100644
--- a/demos/ARM7-LPC214x-G++/Makefile
+++ b/demos/ARM7-LPC214x-G++/Makefile
@@ -40,21 +40,23 @@ endif
PROJECT = ch
# Define linker script file here
-LDSCRIPT= ch.ld
+LDSCRIPT = ch.ld
# Imported source files
-include ../../src/kernel.mk
+include ../../os/ports/GCC/ARM7/port.mk
+include ../../os/kernel/kernel.mk
include ../../test/test.mk
# C sources that can be compiled in ARM or THUMB mode depending on the global
# setting.
-CSRC = ../../ports/ARM7/chcore.c \
- ../../ports/ARM7-LPC214x/vic.c \
- ../../ports/ARM7-LPC214x/pal_lld.c \
- ../../ports/ARM7-LPC214x/lpc214x_serial.c \
+CSRC = ${PORTSRC} \
${KERNSRC} \
${TESTSRC} \
- ../../src/lib/evtimer.c \
+ ../../os/io/pal.c \
+ ../../os/ports/GCC//ARM7/LPC214x/vic.c \
+ ../../os/ports/GCC/ARM7/LPC214x/pal_lld.c \
+ ../../os/ports/GCC/ARM7/LPC214x/lpc214x_serial.c \
+ ../../os/various/evtimer.c \
board.c
# C++ sources that can be compiled in ARM or THUMB mode depending on the global
@@ -82,14 +84,13 @@ TCSRC =
TCPPSRC =
# List ASM source files here
-ASMSRC = ../../ports/ARM7/crt0.s \
- ../../ports/ARM7-LPC214x/vectors.s \
- ../../ports/ARM7/chcoreasm.s
+ASMSRC = $(PORTASM) \
+ ../../os/ports/GCC/ARM7/LPC214x/vectors.s
-INCDIR = $(KERNINC) $(TESTINC) \
- ../../src/lib \
- ../../ports/ARM7 \
- ../../ports/ARM7-LPC214x
+INCDIR = $(PORTINC) $(KERNINC) $(TESTINC) \
+ ../../os/io \
+ ../../os/ports/GCC/ARM7/LPC214x \
+ ../../os/various
#
# Project, sources and paths
@@ -177,4 +178,4 @@ ULIBS =
# End of user defines
##############################################################################
-include ../../ports/ARM/rules.mk
+include ../../os/ports/GCC/ARM/rules.mk
diff --git a/demos/ARM7-LPC214x-GCC-minimal/Makefile b/demos/ARM7-LPC214x-GCC-minimal/Makefile
index a00eb9c65..358b12597 100644
--- a/demos/ARM7-LPC214x-GCC-minimal/Makefile
+++ b/demos/ARM7-LPC214x-GCC-minimal/Makefile
@@ -40,18 +40,21 @@ endif
PROJECT = ch
# Define linker script file here
-LDSCRIPT= ch.ld
+LDSCRIPT = ch.ld
# Imported source files
-include ../../src/kernel.mk
+include ../../os/ports/GCC/ARM7/port.mk
+include ../../os/kernel/kernel.mk
#include ../../test/test.mk
# C sources that can be compiled in ARM or THUMB mode depending on the global
# setting.
-CSRC = ../../ports/ARM7/chcore.c \
- ../../ports/ARM7-LPC214x/vic.c \
- ../../ports/ARM7-LPC214x/pal_lld.c \
+CSRC = ${PORTSRC} \
${KERNSRC} \
+ ${TESTSRC} \
+ ../../os/io/pal.c \
+ ../../os/ports/GCC//ARM7/LPC214x/vic.c \
+ ../../os/ports/GCC/ARM7/LPC214x/pal_lld.c \
board.c main.c
# C++ sources that can be compiled in ARM or THUMB mode depending on the global
@@ -79,14 +82,13 @@ TCSRC =
TCPPSRC =
# List ASM source files here
-ASMSRC = ../../ports/ARM7/crt0.s \
- ../../ports/ARM7-LPC214x/vectors.s \
- ../../ports/ARM7/chcoreasm.s
+ASMSRC = $(PORTASM) \
+ ../../os/ports/GCC/ARM7/LPC214x/vectors.s
-INCDIR = $(KERNINC) $(TESTINC) \
- ../../src/lib \
- ../../ports/ARM7 \
- ../../ports/ARM7-LPC214x
+INCDIR = $(PORTINC) $(KERNINC) $(TESTINC) \
+ ../../os/io \
+ ../../os/ports/GCC/ARM7/LPC214x \
+ ../../os/various
#
# Project, sources and paths
@@ -174,4 +176,4 @@ ULIBS =
# End of user defines
##############################################################################
-include ../../ports/ARM/rules.mk
+include ../../os/ports/GCC/ARM/rules.mk
diff --git a/demos/ARM7-LPC214x-GCC/Makefile b/demos/ARM7-LPC214x-GCC/Makefile
index 2185bbe94..0b36edb4a 100644
--- a/demos/ARM7-LPC214x-GCC/Makefile
+++ b/demos/ARM7-LPC214x-GCC/Makefile
@@ -40,23 +40,24 @@ endif
PROJECT = ch
# Define linker script file here
-LDSCRIPT= ch.ld
+LDSCRIPT = ch.ld
# Imported source files
-include ../../src/kernel.mk
+include ../../os/ports/GCC/ARM7/port.mk
+include ../../os/kernel/kernel.mk
include ../../test/test.mk
# C sources that can be compiled in ARM or THUMB mode depending on the global
# setting.
-CSRC = ../../ports/ARM7/chcore.c \
- ../../ports/ARM7-LPC214x/vic.c \
- ../../ports/ARM7-LPC214x/pal_lld.c \
- ../../ports/ARM7-LPC214x/lpc214x_serial.c \
- ../../ports/ARM7-LPC214x/lpc214x_ssp.c \
+CSRC = ${PORTSRC} \
${KERNSRC} \
${TESTSRC} \
- ../../src/lib/evtimer.c \
- ../../src/lib/pal.c \
+ ../../os/io/pal.c \
+ ../../os/ports/GCC//ARM7/LPC214x/vic.c \
+ ../../os/ports/GCC/ARM7/LPC214x/pal_lld.c \
+ ../../os/ports/GCC/ARM7/LPC214x/lpc214x_serial.c \
+ ../../os/ports/GCC/ARM7/LPC214x/lpc214x_ssp.c \
+ ../../os/various/evtimer.c \
board.c buzzer.c mmcsd.c main.c
# C++ sources that can be compiled in ARM or THUMB mode depending on the global
@@ -84,14 +85,13 @@ TCSRC =
TCPPSRC =
# List ASM source files here
-ASMSRC = ../../ports/ARM7/crt0.s \
- ../../ports/ARM7-LPC214x/vectors.s \
- ../../ports/ARM7/chcoreasm.s
+ASMSRC = $(PORTASM) \
+ ../../os/ports/GCC/ARM7/LPC214x/vectors.s
-INCDIR = $(KERNINC) $(TESTINC) \
- ../../src/lib \
- ../../ports/ARM7 \
- ../../ports/ARM7-LPC214x
+INCDIR = $(PORTINC) $(KERNINC) $(TESTINC) \
+ ../../os/io \
+ ../../os/ports/GCC/ARM7/LPC214x \
+ ../../os/various
#
# Project, sources and paths
@@ -179,4 +179,4 @@ ULIBS =
# End of user defines
##############################################################################
-include ../../ports/ARM/rules.mk
+include ../../os/ports/GCC/ARM/rules.mk
diff --git a/demos/ARMCM3-STM32F103-GCC/Makefile b/demos/ARMCM3-STM32F103-GCC/Makefile
index 3ffda1a1c..59e1fc544 100644
--- a/demos/ARMCM3-STM32F103-GCC/Makefile
+++ b/demos/ARMCM3-STM32F103-GCC/Makefile
@@ -56,20 +56,19 @@ PROJECT = ch
LDSCRIPT= ch.ld
# Imported source files
-include ../../src/kernel.mk
+include ../../os/ports/GCC/ARMCM3/port.mk
+include ../../os/kernel/kernel.mk
include ../../test/test.mk
# C sources that can be compiled in ARM or THUMB mode depending on the global
# setting.
-CSRC = ../../ports/ARMCM3/cmsis/core_cm3.c \
- ../../ports/ARMCM3/chcore.c \
- ../../ports/ARMCM3/nvic.c \
- ../../ports/ARMCM3-STM32F103/stm32_serial.c \
- ../../ports/ARMCM3-STM32F103/pal_lld.c \
+CSRC = ${PORTSRC} \
${KERNSRC} \
${TESTSRC} \
- ../../src/lib/pal.c \
- ../../src/lib/evtimer.c \
+ ../../os/io/pal.c \
+ ../../os/ports/GCC/ARMCM3/STM32F103/pal_lld.c \
+ ../../os/ports/GCC/ARMCM3/STM32F103/stm32_serial.c \
+ ../../os/various/evtimer.c \
board.c main.c
# C++ sources that can be compiled in ARM or THUMB mode depending on the global
@@ -97,14 +96,13 @@ TCSRC =
TCPPSRC =
# List ASM source files here
-ASMSRC = ../../ports/ARMCM3/crt0.s \
- ../../ports/ARMCM3-STM32F103/vectors.s
-
-INCDIR = $(KERNINC) $(TESTINC) \
- ../../src/lib \
- ../../ports/ARMCM3 \
- ../../ports/ARMCM3/cmsis \
- ../../ports/ARMCM3-STM32F103 \
+ASMSRC = $(PORTASM) \
+ ../../ports/ARMCM3-STM32F103/vectors.s
+
+INCDIR = $(PORTINC) $(KERNINC) $(TESTINC) \
+ ../../os/io \
+ ../../os/ports/GCC/ARMCM3/STM32F103 \
+ ../../os/various \
./stm32lib/inc
#
@@ -199,4 +197,4 @@ ifeq ($(USE_FWLIB),yes)
USE_OPT += -DUSE_STDPERIPH_DRIVER
endif
-include ../../ports/ARM/rules.mk
+include ../../os/ports/GCC/ARM/rules.mk
diff --git a/demos/AVR-AT90CANx-GCC/Makefile b/demos/AVR-AT90CANx-GCC/Makefile
index a72f1f913..7b880f6d9 100644
--- a/demos/AVR-AT90CANx-GCC/Makefile
+++ b/demos/AVR-AT90CANx-GCC/Makefile
@@ -80,15 +80,17 @@ OBJDIR = .
# Imported source files
-include ../../src/kernel.mk
+include ../../os/ports/GCC/AVR/port.mk
+include ../../os/kernel/kernel.mk
include ../../test/test.mk
# List C source files here. (C dependencies are automatically generated.)
-SRC = ../../ports/AVR/chcore.c ../../ports/AVR/avr_serial.c \
- ${KERNSRC} \
- ${TESTSRC} \
- ../../src/lib/evtimer.c \
+SRC = ${PORTSRC} \
+ ${KERNSRC} \
+ ${TESTSRC} \
+ ../../os/ports/GCC/AVR/avr_serial.c \
+ ../../os/various/evtimer.c \
board.c main.c
@@ -123,7 +125,7 @@ DEBUG = dwarf-2
# Each directory must be seperated by a space.
# Use forward slashes for directory separators.
# For a directory that has spaces, enclose it in quotes.
-EXTRAINCDIRS = ../../src/include ../../src/lib ../../ports/AVR
+EXTRAINCDIRS = $(PORTINC) $(KERNINC) $(TESTINC)e ../../os/various
# Compiler flag to set the C Standard level.
diff --git a/demos/AVR-ATmega128-GCC/Makefile b/demos/AVR-ATmega128-GCC/Makefile
index f291af1fb..c13d60ef9 100644
--- a/demos/AVR-ATmega128-GCC/Makefile
+++ b/demos/AVR-ATmega128-GCC/Makefile
@@ -80,15 +80,17 @@ OBJDIR = .
# Imported source files
-include ../../src/kernel.mk
+include ../../os/ports/GCC/AVR/port.mk
+include ../../os/kernel/kernel.mk
include ../../test/test.mk
# List C source files here. (C dependencies are automatically generated.)
-SRC = ../../ports/AVR/chcore.c ../../ports/AVR/avr_serial.c \
- ${KERNSRC} \
- ${TESTSRC} \
- ../../src/lib/evtimer.c \
+SRC = ${PORTSRC} \
+ ${KERNSRC} \
+ ${TESTSRC} \
+ ../../os/ports/GCC/AVR/avr_serial.c \
+ ../../os/various/evtimer.c \
board.c lcd.c main.c
@@ -123,7 +125,7 @@ DEBUG = dwarf-2
# Each directory must be seperated by a space.
# Use forward slashes for directory separators.
# For a directory that has spaces, enclose it in quotes.
-EXTRAINCDIRS = ../../src/include ../../src/lib ../../ports/AVR
+EXTRAINCDIRS = $(PORTINC) $(KERNINC) $(TESTINC)e ../../os/various
# Compiler flag to set the C Standard level.
diff --git a/demos/MSP430-MSP430x1611-GCC/Makefile b/demos/MSP430-MSP430x1611-GCC/Makefile
index 8cf693eb1..e316c3fa9 100644
--- a/demos/MSP430-MSP430x1611-GCC/Makefile
+++ b/demos/MSP430-MSP430x1611-GCC/Makefile
@@ -36,30 +36,32 @@ endif
PROJECT = ch
# Define linker script file here
-LDSCRIPT= mspgcc/msp430x1611.x
+LDSCRIPT = mspgcc/msp430x1611.x
# Imported source files
-include ../../src/kernel.mk
+include ../../os/ports/GCC/MSP430/port.mk
+include ../../os/kernel/kernel.mk
include ../../test/test.mk
# C sources here.
-CSRC = ../../ports/MSP430/chcore.c \
- ../../ports/MSP430/msp430_serial.c \
- ../../ports/MSP430/pal_lld.c \
+CSRC = ${PORTSRC} \
${KERNSRC} \
${TESTSRC} \
- ../../src/lib/evtimer.c \
+ ../../os/io/pal.c \
+ ../../os/ports/GCC/MSP430/pal_lld.c \
+ ../../os/ports/GCC/MSP430/msp430_serial.c \
+ ../../os/various/evtimer.c \
board.c main.c
# C++ sources here.
CPPSRC =
# List ASM source files here
-ASMSRC =
+ASMSRC = $(PORTASM)
-INCDIR = $(KERNINC) $(TESTINC) \
- ../../src/lib \
- ../../ports/MSP430
+INCDIR = $(PORTINC) $(KERNINC) $(TESTINC) \
+ ../../os/io \
+ ../../os/various
#
# Project, sources and paths
diff --git a/demos/Win32-MinGW/Makefile b/demos/Win32-MinGW/Makefile
index ed66e51fd..616b46015 100644
--- a/demos/Win32-MinGW/Makefile
+++ b/demos/Win32-MinGW/Makefile
@@ -47,7 +47,7 @@ DLIBS = -lws2_32
PROJECT = ch
# Define linker script file here
-LDSCRIPT=
+LDSCRIPT =
# List all user C define here, like -D_DEBUG=1
UDEFS =
@@ -56,19 +56,21 @@ UDEFS =
UADEFS =
# Imported source files
-include ../../src/kernel.mk
+include ../../os/kernel/kernel.mk
include ../../test/test.mk
# List C source files here
-SRC = chcore.c main.c ../../ports/win32/simcom.c \
- ${KERNSRC} \
- ${TESTSRC}
+SRC = ${KERNSRC} \
+ ${TESTSRC} \
+ chcore.c \
+ ../../os/ports/GCC/win32/simcom.c \
+ main.c
# List ASM source files here
ASRC =
# List all user directories here
-UINCDIR = ../../src/include
+UINCDIR = $(KERNINC) $(TESTINC)
# List the user directory to look for the libraries here
ULIBDIR =
diff --git a/os/io/pal.c b/os/io/pal.c
new file mode 100644
index 000000000..f7645f621
--- /dev/null
+++ b/os/io/pal.c
@@ -0,0 +1,94 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT 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 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT 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, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file pal.c
+ * @brief I/O Ports Abstraction Layer code
+ * @addtogroup PAL
+ * @{
+ */
+
+#include <ch.h>
+#include <pal.h>
+
+/**
+ * @brief Read from an I/O bus.
+ *
+ * @param[in] bus the I/O bus, pointer to a @p IOBus structure
+ * @return The bus logical states.
+ *
+ * @note The operation is not guaranteed to be atomic on all the architectures,
+ * for atomicity and/or portability reasons you may need to enclose port
+ * I/O operations between @p chSysLock() and @p chSysUnlock().
+ * @note The function internally uses the @p palReadGroup() macro. The use of
+ * this function is preferred when you value code size, readability and
+ * error checking over speed.
+ */
+ioportmask_t palReadBus(IOBus *bus) {
+
+ chDbgCheck((bus != NULL) &&
+ (bus->bus_offset > PAL_IOPORTS_WIDTH), "palReadBus");
+
+ return palReadGroup(bus->bus_portid, bus->bus_mask, bus->bus_offset);
+}
+
+/**
+ * @brief Write to an I/O bus.
+ *
+ * @param[in] bus the I/O bus, pointer to a @p IOBus structure
+ * @param[in] bits the bits to be written on the I/O bus. Values exceeding
+ * the bus width are masked so most significant bits are lost.
+ *
+ * @note The operation is not guaranteed to be atomic on all the architectures,
+ * for atomicity and/or portability reasons you may need to enclose port
+ * I/O operations between @p chSysLock() and @p chSysUnlock().
+ * @note The default implementation is non atomic and not necessarily
+ * optimal. Low level drivers may optimize the function by using
+ * specific hardware or coding.
+ */
+void palWriteBus(IOBus *bus, ioportmask_t bits) {
+
+ chDbgCheck((bus != NULL) &&
+ (bus->bus_offset > PAL_IOPORTS_WIDTH), "palWriteBus");
+
+ palWriteGroup(bus->bus_portid, bus->bus_mask, bus->bus_offset, bits);
+}
+
+/**
+ * @brief Programs a bus with the specified mode.
+ *
+ * @param[in] bus the I/O bus, pointer to a @p IOBus structure
+ * @param[in] mode the mode
+ *
+ * @note The operation is not guaranteed to be atomic on all the architectures,
+ * for atomicity and/or portability reasons you may need to enclose port
+ * I/O operations between @p chSysLock() and @p chSysUnlock().
+ * @note The default implementation is non atomic and not necessarily
+ * optimal. Low level drivers may optimize the function by using
+ * specific hardware or coding.
+ */
+void palSetBusMode(IOBus *bus, uint_fast8_t mode) {
+
+ chDbgCheck((bus != NULL) &&
+ (bus->bus_offset > PAL_IOPORTS_WIDTH), "palSetBusMode");
+
+ palSetGroupMode(bus->bus_portid, bus->bus_mask, mode);
+}
+
+/** @} */
diff --git a/os/io/pal.h b/os/io/pal.h
new file mode 100644
index 000000000..b75582ee1
--- /dev/null
+++ b/os/io/pal.h
@@ -0,0 +1,460 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT 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 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT 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, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file pal.h
+ * @brief I/O Ports Abstraction Layer macros, types and structures
+ * @addtogroup PAL
+ * @{
+ */
+
+#ifndef _PAL_H_
+#define _PAL_H_
+
+/**
+ * @brief Bits in a mode word dedicated as mode selector.
+ * @details The other bits are not defined and may be used as device-specific
+ * option bits.
+ */
+#define PAL_MODE_MASK 0xF
+
+/**
+ * @brief After reset state.
+ * @details The state itself is not specified and is architecture dependent,
+ * it is guaranteed to be equal to the after-reset state. It is
+ * usually an input state.
+ */
+#define PAL_MODE_RESET 0
+
+/**
+ * @brief Safe state for <b>unconnected</b> pads.
+ * @details The state itself is not specified and is architecture dependent,
+ * it may be mapped on @p PAL_MODE_INPUT_PULLUP,
+ * @p PAL_MODE_INPUT_PULLDOWN or @p PAL_MODE_OUTPUT_PUSHPULL as
+ * example.
+ */
+#define PAL_MODE_UNCONNECTED 1
+
+/**
+ * @brief Regular input high-Z pad.
+ */
+#define PAL_MODE_INPUT 2
+
+/**
+ * @brief Input pad with weak pull up resistor.
+ */
+#define PAL_MODE_INPUT_PULLUP 3
+
+/**
+ * @brief Input pad with weak pull down resistor.
+ */
+#define PAL_MODE_INPUT_PULLDOWN 4
+
+/**
+ * @brief Push-pull output pad.
+ */
+#define PAL_MODE_OUTPUT_PUSHPULL 5
+
+/**
+ * @brief Open-drain output pad.
+ */
+#define PAL_MODE_OUTPUT_OPENDRAIN 6
+
+#ifndef _PAL_LLD_H_
+#include "pal_lld.h"
+#endif
+
+/**
+ * @brief Logical low state.
+ */
+#define PAL_LOW 0
+
+/**
+ * @brief Logical high state.
+ */
+#define PAL_HIGH 1
+
+/**
+ * @brief Port bit helper macro.
+ * @details This macro calculates the mask of a bit within a port.
+ *
+ * @param[in] n the bit position within the port
+ * @return The bit mask.
+ */
+#define PAL_PORT_BIT(n) ((ioportmask_t)(1 << (n)))
+
+
+/**
+ * @brief Bits group mask helper.
+ * @details This macro calculates the mask of a bits group.
+ *
+ * @param[in] width the group width
+ * @return The group mask.
+ */
+#define PAL_GROUP_MASK(width) ((ioportmask_t)(1 << (width)) - 1)
+
+/**
+ * @brief Data part of a static I/O bus initializer.
+ * @details This macro should be used when statically initializing an I/O bus
+ * that is part of a bigger structure.
+ *
+ * @param name the name of the IOBus variable
+ * @param port the I/O port descriptor
+ * @param width the bus width in bits
+ * @param offset the bus bit offset within the port
+ */
+#define _IOBUS_DATA(name, port, width, offset) \
+ {port, PAL_GROUP_MASK(width), offset}
+
+/**
+ * @brief Static I/O bus initializer.
+ *
+ * @param name the name of the IOBus variable
+ * @param port the I/O port descriptor
+ * @param width the bus width in bits
+ * @param offset the bus bit offset within the port
+ */
+#define IOBUS_DECL(name, port, width, offset) \
+ IOBus name = _IOBUS_DATA(name, port, width, offset)
+
+/**
+ * @brief I/O bus descriptor.
+ * @details This structure describes a group of contiguous digital I/O lines
+ * that have to be handled as bus.
+ * @note I/O operations on a bus do not affect I/O lines on the same port but
+ * not belonging to the bus.
+ */
+typedef struct {
+ /** Port identifier. */
+ ioportid_t bus_portid;
+ /** Bus mask aligned to port bit 0. The bus mask implicitly define the bus
+ * width. */
+ ioportmask_t bus_mask;
+ /** Offset, within the port, of the least significant bit of the bus. */
+ uint_fast8_t bus_offset;
+} IOBus;
+
+/**
+ * @brief PAL subsystem initialization.
+ *
+ * @param[in] config pointer to an architecture specific configuration
+ * structure. This structure is defined in the low level driver
+ * header.
+ */
+#define palInit(config) pal_lld_init(config)
+
+/**
+ * @brief Reads the physical I/O port states.
+ *
+ * @param[in] port the port identifier
+ * @return The port logical states.
+ *
+ * @note The default implementation always return zero and computes the
+ * parameter eventual side effects.
+ */
+#if !defined(pal_lld_readport) || defined(__DOXYGEN__)
+#define palReadPort(port) ((void)(port), 0)
+#else
+#define palReadPort(port) pal_lld_readport(port)
+#endif
+
+/**
+ * @brief Reads the output latch.
+ * @details The purpose of this function is to read back the latched output
+ * value.
+ *
+ * @param[in] port the port identifier
+ * @return The latched logical states.
+ *
+ * @note The default implementation always return zero and computes the
+ * parameter eventual side effects.
+ */
+#if !defined(pal_lld_readlatch) || defined(__DOXYGEN__)
+#define palReadLatch(port) ((void)(port), 0)
+#else
+#define palReadLatch(port) pal_lld_readlatch(port)
+#endif
+
+/**
+ * @brief Writes a bits mask on a I/O port.
+ *
+ * @param[in] port the port identifier
+ * @param[in] bits the bits to be written on the specified port
+ *
+ * @note The default implementation does nothing except computing the
+ * parameters eventual side effects.
+ */
+#if !defined(pal_lld_writeport) || defined(__DOXYGEN__)
+#define palWritePort(port, bits) ((void)(port), (void)(bits))
+#else
+#define palWritePort(port, bits) pal_lld_writeport(port, bits)
+#endif
+
+/**
+ * @brief Sets a bits mask on a I/O port.
+ *
+ * @param[in] port the port identifier
+ * @param[in] bits the bits to be ORed on the specified port
+ *
+ * @note The operation is not guaranteed to be atomic on all the architectures,
+ * for atomicity and/or portability reasons you may need to enclose port
+ * I/O operations between @p chSysLock() and @p chSysUnlock().
+ * @note The default implementation is non atomic and not necessarily
+ * optimal. Low level drivers may optimize the function by using
+ * specific hardware or coding.
+ */
+#if !defined(pal_lld_setport) || defined(__DOXYGEN__)
+#define palSetPort(port, bits) { \
+ palWritePort(port, palReadLatch(port) | (bits)); \
+}
+#else
+#define palSetPort(port, bits) pal_lld_setport(port, bits)
+#endif
+
+/**
+ * @brief Clears a bits mask on a I/O port.
+ *
+ * @param[in] port the port identifier
+ * @param[in] bits the bits to be cleared on the specified port
+ *
+ * @note The operation is not guaranteed to be atomic on all the architectures,
+ * for atomicity and/or portability reasons you may need to enclose port
+ * I/O operations between @p chSysLock() and @p chSysUnlock().
+ * @note The default implementation is non atomic and not necessarily
+ * optimal. Low level drivers may optimize the function by using
+ * specific hardware or coding.
+ */
+#if !defined(pal_lld_clearport) || defined(__DOXYGEN__)
+#define palClearPort(port, bits) { \
+ palWritePort(port, palReadLatch(port) & ~(bits)); \
+}
+#else
+#define palClearPort(port, bits) pal_lld_clearport(port, bits)
+#endif
+
+/**
+ * @brief Toggles a bits mask on a I/O port.
+ *
+ * @param[in] port the port identifier
+ * @param[in] bits the bits to be XORed on the specified port
+ *
+ * @note The operation is not guaranteed to be atomic on all the architectures,
+ * for atomicity and/or portability reasons you may need to enclose port
+ * I/O operations between @p chSysLock() and @p chSysUnlock().
+ * @note The default implementation is non atomic and not necessarily
+ * optimal. Low level drivers may optimize the function by using
+ * specific hardware or coding.
+ */
+#if !defined(pal_lld_toggleport) || defined(__DOXYGEN__)
+#define palTogglePort(port, bits) { \
+ palWritePort(port, palReadLatch(port) ^ (bits)); \
+}
+#else
+#define palTogglePort(port, bits) pal_lld_toggleport(port, bits)
+#endif
+
+/**
+ * @brief Reads a group of bits.
+ *
+ * @param[in] port the port identifier
+ * @param[in] mask the group mask
+ * @param[in] offset the group bit offset within the port
+ * @return The group logical states.
+ */
+#if !defined(pal_lld_readgroup) || defined(__DOXYGEN__)
+#define palReadGroup(port, mask, offset) \
+ ((palReadPort(port) >> (offset)) & (mask))
+#else
+#define palReadGroup(port, mask, offset) pal_lld_readgroup(port, mask, offset)
+#endif
+
+/**
+ * @brief Writes a group of bits.
+ *
+ * @param[in] port the port identifier
+ * @param[in] mask the group mask
+ * @param[in] offset the group bit offset within the port
+ * @param[in] bits the bits to be written. Values exceeding the group width
+ * are masked.
+ */
+#if !defined(pal_lld_writegroup) || defined(__DOXYGEN__)
+#define palWriteGroup(port, mask, offset, bits) { \
+ palWritePort(port, (palReadLatch(port) & ~((mask) << (offset))) | \
+ (((bits) & (mask)) << (offset))); \
+}
+#else
+#define palWriteGroup(port, mask, offset, bits) \
+ pal_lld_writegroup(port, mask, offset, bits)
+#endif
+
+
+/**
+ * @brief Pads group mode setup.
+ * @details This function programs a pads group belonging to the same port
+ * with the specified mode.
+ *
+ * @param[in] port the port identifier
+ * @param[in] mask the group mask
+ * @param[in] mode the setup mode
+ *
+ * @note Programming an unknown or unsupported mode is silently ignored.
+ */
+#if !defined(pal_lld_setgroupmode) || defined(__DOXYGEN__)
+#define palSetGroupMode(port, mask, mode)
+#else
+#define palSetGroupMode(port, mask, mode) pal_lld_setgroupmode(port, mask, mode)
+#endif
+
+/**
+ * @brief Reads an input pad logical state.
+ *
+ * @param[in] port the port identifier
+ * @param[in] pad the pad number within the port
+ * @return The logical state.
+ * @retval 0 low logical state.
+ * @retval 1 high logical state.
+ *
+ * @note The default implementation not necessarily optimal. Low level drivers
+ * may optimize the function by using specific hardware or coding.
+ * @note The default implementation internally uses the @p palReadPort().
+ */
+#if !defined(pal_lld_readpad) || defined(__DOXYGEN__)
+#define palReadPad(port, pad) ((palReadPort(port) >> (pad)) & 1)
+#else
+#define palReadPad(port, pad) pal_lld_readpad(port, pad)
+#endif
+
+/**
+ * @brief Writes a logical state on an output pad.
+ *
+ * @param[in] port the port identifier
+ * @param[in] pad the pad number within the port
+ * @param[out] bit the logical value, the value must be @p 0 or @p 1
+ *
+ * @note The operation is not guaranteed to be atomic on all the architectures,
+ * for atomicity and/or portability reasons you may need to enclose port
+ * I/O operations between @p chSysLock() and @p chSysUnlock().
+ * @note The default implementation is non atomic and not necessarily
+ * optimal. Low level drivers may optimize the function by using
+ * specific hardware or coding.
+ * @note The default implementation internally uses the @p palReadLatch() and
+ * @p palWritePort().
+ */
+#if !defined(pal_lld_writepad) || defined(__DOXYGEN__)
+#define palWritePad(port, pad, bit) { \
+ palWritePort(port, (palReadLatch(port) & ~PAL_PORT_BIT(pad)) | \
+ (((bit) & 1) << pad)); \
+}
+#else
+#define palWritePad(port, pad, bit) pal_lld_writepad(port, pad, bit)
+#endif
+
+/**
+ * @brief Sets a pad logical state to @p 1.
+ *
+ * @param[in] port the port identifier
+ * @param[in] pad the pad number within the port
+ *
+ * @note The operation is not guaranteed to be atomic on all the architectures,
+ * for atomicity and/or portability reasons you may need to enclose port
+ * I/O operations between @p chSysLock() and @p chSysUnlock().
+ * @note The default implementation is non atomic and not necessarily
+ * optimal. Low level drivers may optimize the function by using
+ * specific hardware or coding.
+ * @note The default implementation internally uses the @p palSetPort().
+ */
+#if !defined(pal_lld_setpad) || defined(__DOXYGEN__)
+#define palSetPad(port, pad) palSetPort(port, PAL_PORT_BIT(pad))
+#else
+#define palSetPad(port, pad) pal_lld_setpad(port, pad)
+#endif
+
+/**
+ * @brief Clears a pad logical state to @p 0.
+ *
+ * @param[in] port the port identifier
+ * @param[in] pad the pad number within the port
+ *
+ * @note The operation is not guaranteed to be atomic on all the architectures,
+ * for atomicity and/or portability reasons you may need to enclose port
+ * I/O operations between @p chSysLock() and @p chSysUnlock().
+ * @note The default implementation is non atomic and not necessarily
+ * optimal. Low level drivers may optimize the function by using
+ * specific hardware or coding.
+ * @note The default implementation internally uses the @p palClearPort().
+ */
+#if !defined(pal_lld_clearpad) || defined(__DOXYGEN__)
+#define palClearPad(port, pad) palClearPort(port, PAL_PORT_BIT(pad))
+#else
+#define palClearPad(port, pad) pal_lld_clearpad(port, pad)
+#endif
+
+/**
+ * @brief Toggles a pad logical state.
+ *
+ * @param[in] port the port identifier
+ * @param[in] pad the pad number within the port
+ *
+ * @note The operation is not guaranteed to be atomic on all the architectures,
+ * for atomicity and/or portability reasons you may need to enclose port
+ * I/O operations between @p chSysLock() and @p chSysUnlock().
+ * @note The default implementation is non atomic and not necessarily
+ * optimal. Low level drivers may optimize the function by using
+ * specific hardware or coding.
+ * @note The default implementation internally uses the @p palTogglePort().
+ */
+#if !defined(pal_lld_togglepad) || defined(__DOXYGEN__)
+#define palTogglePad(port, pad) palTogglePort(port, PAL_PORT_BIT(pad))
+#else
+#define palTogglePad(port, pad) pal_lld_togglepad(port, pad)
+#endif
+
+
+/**
+ * @brief Pad mode setup.
+ * @details This function programs a pad with the specified mode.
+ *
+ * @param[in] port the port identifier
+ * @param[in] pad the pad number within the port
+ * @param[in] mode the setup mode
+ *
+ * @note The default implementation not necessarily optimal. Low level drivers
+ * may optimize the function by using specific hardware or coding.
+ * @note Programming an unknown or unsupported mode is silently ignored.
+ */
+#if !defined(pal_lld_setpadmode) || defined(__DOXYGEN__)
+#define palSetPadMode(port, pad, mode) \
+ palSetGroupMode(port, PAL_PORT_BIT(pad), mode)
+#else
+#define palSetPadMode(port, pad, mode) pal_lld_setpadmode(port, pad, mode)
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ ioportmask_t palReadBus(IOBus *bus);
+ void palWriteBus(IOBus *bus, ioportmask_t bits);
+ void palSetBusMode(IOBus *bus, uint_fast8_t mode);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _PAL_H_ */
+
+/** @} */
diff --git a/os/io/readme.txt b/os/io/readme.txt
new file mode 100644
index 000000000..18bd93b20
--- /dev/null
+++ b/os/io/readme.txt
@@ -0,0 +1 @@
+ChibiOS/RT I/O abstraction code \ No newline at end of file
diff --git a/os/kernel/include/ch.h b/os/kernel/include/ch.h
new file mode 100644
index 000000000..0584b167e
--- /dev/null
+++ b/os/kernel/include/ch.h
@@ -0,0 +1,89 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT 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 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT 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, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file ch.h
+ * @brief ChibiOS/RT main include file, it includes everything else.
+ * @addtogroup Kernel
+ * @{
+ */
+
+#ifndef _CH_H_
+#define _CH_H_
+
+/**
+ * ChibiOS/RT identification macro.
+ */
+#define _CHIBIOS_RT_
+
+/**
+ * Kernel version string.
+ */
+#define CH_KERNEL_VERSION "1.3.2unstable"
+
+/**
+ * Kernel version major number.
+ */
+#define CH_KERNEL_MAJOR 1
+
+/**
+ * Kernel version minor number.
+ */
+#define CH_KERNEL_MINOR 3
+
+/**
+ * Kernel version patch number.
+ */
+#define CH_KERNEL_PATCH 2
+
+/*
+ * Common values.
+ */
+#ifndef FALSE
+#define FALSE 0
+#endif
+#ifndef TRUE
+#define TRUE (!FALSE)
+#endif
+
+#include <chconf.h>
+#include <chtypes.h>
+#include "lists.h"
+#include <chcore.h>
+#include "sys.h"
+#include "vt.h"
+#include "scheduler.h"
+#include "semaphores.h"
+#include "mutexes.h"
+#include "condvars.h"
+#include "events.h"
+#include "messages.h"
+#include "mailboxes.h"
+#include "heap.h"
+#include "mempools.h"
+#include "threads.h"
+#include "inline.h"
+#include "queues.h"
+#include "channels.h"
+#include "serial.h"
+#include "debug.h"
+
+#endif /* _CH_H_ */
+
+/** @} */
diff --git a/os/kernel/include/channels.h b/os/kernel/include/channels.h
new file mode 100644
index 000000000..a1c538f62
--- /dev/null
+++ b/os/kernel/include/channels.h
@@ -0,0 +1,292 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT 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 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT 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, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file channels.h
+ * @brief I/O channels
+ * @addtogroup Channels
+ * @{
+ */
+
+#ifndef _CHANNELS_H_
+#define _CHANNELS_H_
+
+/**
+ * @brief @p BaseChannel specific methods.
+ */
+struct _base_channel_methods {
+ /**
+ * @brief Channel output check.
+ * @see chIOPutWouldBlock()
+ */
+ bool_t (*putwouldblock)(void *instance);
+ /**
+ * @brief Channel input check.
+ * @see chIOGetWouldBlock()
+ */
+ bool_t (*getwouldblock)(void *instance);
+ /**
+ * @brief Channel put method with timeout specification.
+ * @see chIOPut()
+ */
+ msg_t (*put)(void *instance, uint8_t b, systime_t timeout);
+ /**
+ * @brief Channel get method with timeout specification.
+ * @see chIOGet()
+ */
+ msg_t (*get)(void *instance, systime_t timeout);
+};
+
+/**
+ * @brief @p BaseChannel specific data.
+ * @note It is empty because @p BaseChannel is only an interface without
+ * implementation.
+ */
+struct _base_channel_data {
+};
+
+/**
+ * @brief @p BaseChannel virtual methods table.
+ */
+struct BaseChannelVMT {
+ /**
+ * @p BaseChannel class specific methods.
+ */
+ struct _base_channel_methods m0;
+};
+
+/**
+ * @brief Base channel class.
+ * @details This class represents a generic, byte-wide, I/O channel.
+ */
+typedef struct {
+ /**
+ * Virtual Methods Table.
+ */
+ const struct BaseChannelVMT *vmt;
+ /**
+ * @p BaseChannel class specific data.
+ */
+ struct _base_channel_data d0;
+} BaseChannel;
+
+/**
+ * @brief Channel output check.
+ * @details This function verifies if a subsequent @p chIOPut() would block.
+ *
+ * @param[in] ip pointer to a @p BaseChannel or derived class
+ * @return The output queue status:
+ * @retval FALSE if the output queue has space and would not block a write
+ * operation.
+ * @retval TRUE if the output queue is full and would block a write operation.
+ */
+#define chIOPutWouldBlock(ip) ((ip)->vmt->m0.putwouldblock(ip))
+
+/**
+ * @brief Channel input check.
+ * @details This function verifies if a subsequent @p chIOGett() would block.
+ *
+ * @param[in] ip pointer to a @p BaseChannel or derived class
+ * @return The input queue status:
+ * @retval FALSE if the input queue contains data and would not block a read
+ * operation.
+ * @retval TRUE if the input queue is empty and would block a read operation.
+ */
+#define chIOGetWouldBlock(ip) ((ip)->vmt->m0.getwouldblock(ip))
+
+/**
+ * @brief Channel blocking byte write.
+ * @details This function writes a byte value to a channel. If the channel
+ * is not ready to accept data then the calling thread is suspended.
+ *
+ * @param[in] ip pointer to a @p BaseChannel or derived class
+ * @param[in] b the byte value to be written to the channel
+ * @return The operation status:
+ * @retval Q_OK if the operation succeeded.
+ * @retval Q_RESET if the channel associated queue (if any) was reset.
+ */
+#define chIOPut(ip, b) ((ip)->vmt->m0.put(ip, b, TIME_INFINITE))
+
+/**
+ * @brief Channel blocking byte write with timeout.
+ * @details This function writes a byte value to a channel. If the channel
+ * is not ready to accept data then the calling thread is suspended.
+ *
+ * @param[in] ip pointer to a @p BaseChannel or derived class
+ * @param[in] b the byte value to be written to the channel
+ * @param[in] timeout the number of ticks before the operation timeouts,
+ * the following special values are allowed:
+ * - @a TIME_IMMEDIATE immediate timeout.
+ * - @a TIME_INFINITE no timeout.
+ * .
+ * @return The operation status:
+ * @retval Q_OK if the operation succeeded.
+ * @retval Q_TIMEOUT if the specified time expired.
+ * @retval Q_RESET if the channel associated queue (if any) was reset.
+ */
+#define chIOPutTimeout(ip, b, timeout) ((ip)->vmt->m0.put(ip, b, timeout))
+
+/**
+ * @brief Channel blocking byte read.
+ * @details This function reads a byte value from a channel. If the data
+ * is not available then the calling thread is suspended.
+ *
+ * @param[in] ip pointer to a @p BaseChannel or derived class
+ * @return A byte value from the queue or:
+ * @retval Q_RESET if the channel associated queue (if any) was reset.
+ */
+#define chIOGet(ip) ((ip)->vmt->m0.get(ip, TIME_INFINITE))
+
+/**
+ * @brief Channel blocking byte read with timeout.
+ * @details This function reads a byte value from a channel. If the data
+ * is not available then the calling thread is suspended.
+ *
+ * @param[in] ip pointer to a @p BaseChannel or derived class
+ * @param[in] timeout the number of ticks before the operation timeouts,
+ * the following special values are allowed:
+ * - @a TIME_IMMEDIATE immediate timeout.
+ * - @a TIME_INFINITE no timeout.
+ * .
+ * @return A byte value from the queue or:
+ * @retval Q_TIMEOUT if the specified time expired.
+ * @retval Q_RESET if the channel associated queue (if any) was reset.
+ */
+#define chIOGetTimeout(ip, timeout) ((ip)->vmt->m0.get(ip, timeout))
+
+#if CH_USE_EVENTS
+/**
+ * @brief @p BaseAsynchronousChannel specific methods.
+ */
+struct _base_asynchronous_channel_methods {
+ /**
+ * Channel asynchronous write method.
+ * @see chIOWrite()
+ */
+ size_t (*write)(void *instance, uint8_t *buffer, size_t n);
+ /**
+ * Channel asynchronous read method.
+ * @see chIORead()
+ */
+ size_t (*read)(void *instance, uint8_t *buffer, size_t n);
+};
+
+/**
+ * @brief @p BaseAsynchronousChannel specific data.
+ */
+struct _base_asynchronous_channel_data {
+ /**
+ * Data Available @p EventSource. This event is generated when some incoming
+ * data is inserted in the input queue.
+ */
+ EventSource ievent;
+ /**
+ * Data Transmitted @p EventSource. This event is generated when the
+ * output queue is empty.
+ */
+ EventSource oevent;
+};
+
+/**
+ * @brief @p BaseAsynchronousChannel virtual methods table.
+ */
+struct BaseAsynchronousChannelVMT {
+ /**
+ * @p BaseChannel class inherited methods.
+ */
+ struct _base_channel_methods m0;
+ /**
+ * @p BaseAsynchronousChannel class specific methods.
+ */
+ struct _base_asynchronous_channel_methods m1;
+};
+
+/**
+ * @extends BaseChannel
+ *
+ * @brief Base asynchronous channel class.
+ * @details This class extends @p BaseChannel by adding methods for
+ * asynchronous I/O in an event-driven environment.
+ */
+typedef struct {
+ /**
+ * Virtual Methods Table.
+ */
+ const struct BaseAsynchronousChannelVMT *vmt;
+ /**
+ * @p BaseChannel class inherited data.
+ */
+ struct _base_channel_data d0;
+ /**
+ * @p BaseAsynchronousChannel class specific data.
+ */
+ struct _base_asynchronous_channel_data d1;
+} BaseAsynchronousChannel;
+
+/**
+ * @brief Channel non-blocking write.
+ * @details The function writes data from a buffer to a channel. The
+ * transfer is non-blocking and can return zero if the channel is
+ * not read to accept data.
+ *
+ * @param[in] ip pointer to a @p BaseAsynchronousChannel or derived class
+ * @param[out] bp pointer to the buffer where the data is stored
+ * @param[in] n the maximum amount of data to be transferred
+ * @return The number of bytes transferred.
+ */
+#define chIOWrite(ip, bp, n) ((ip)->vmt->m1.write(ip, bp, n))
+
+/**
+ * @brief Channel non-blocking read.
+ * @details The function reads data from a channel into a buffer. The
+ * transfer is non-blocking and can return zero if the channel has
+ * no data immediately available.
+ *
+ * @param[in] ip pointer to a @p BaseAsynchronousChannel or derived class
+ * @param[out] bp pointer to the buffer where the input data is copied
+ * @param[in] n the maximum amount of data to be transferred
+ * @return The number of bytes transferred.
+ */
+#define chIORead(ip, bp, n) ((ip)->vmt->m1.read(ip, bp, n))
+
+/**
+ * @brief Returns the write event source.
+ * @details The write event source is broadcasted when the channel is ready
+ * for write operations. This usually happens when the internal
+ * output queue becomes empty.
+ * @param[in] ip pointer to a @p BaseAsynchronousChannel or derived class
+ * @return A pointer to an @p EventSource object.
+ */
+#define chIOGetWriteEventSource(ip) (&((ip)->vmt->d1.oevent))
+
+/**
+ * @brief Returns the read event source.
+ * @details The read event source is broadcasted when the channel is ready
+ * for read operations. This usually happens when the internal
+ * input queue becomes non-empty.
+ * @param[in] ip pointer to a @p BaseAsynchronousChannel or derived class
+ * @return A pointer to an @p EventSource object.
+ */
+#define chIOGetReadEventSource(ip) (&((ip)->vmt->d1.ievent))
+
+#endif /* CH_USE_EVENTS */
+
+#endif /* _CHANNELS_H_ */
+
+/** @} */
diff --git a/os/kernel/include/condvars.h b/os/kernel/include/condvars.h
new file mode 100644
index 000000000..d68637f21
--- /dev/null
+++ b/os/kernel/include/condvars.h
@@ -0,0 +1,80 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT 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 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT 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, see <http://www.gnu.org/licenses/>.
+*/
+/*
+ Concepts and parts of this file are contributed by and Copyright (C) 2008
+ of Leon Woestenberg.
+ */
+
+/**
+ * @file condvars.h
+ * @brief Condition Variables macros and structures.
+ * @addtogroup CondVars
+ * @{
+ */
+
+#ifndef _CONDVARS_H_
+#define _CONDVARS_H_
+
+#if CH_USE_CONDVARS && CH_USE_MUTEXES
+
+/**
+ * @brief CondVar structure.
+ */
+typedef struct CondVar {
+ ThreadsQueue c_queue; /**< CondVar threads queue.*/
+} CondVar;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void chCondInit(CondVar *cp);
+ void chCondSignal(CondVar *cp);
+ void chCondSignalI(CondVar *cp);
+ void chCondBroadcast(CondVar *cp);
+ void chCondBroadcastI(CondVar *cp);
+ msg_t chCondWait(CondVar *cp);
+ msg_t chCondWaitS(CondVar *cp);
+#if CH_USE_CONDVARS_TIMEOUT
+ msg_t chCondWaitTimeout(CondVar *cp, systime_t time);
+ msg_t chCondWaitTimeoutS(CondVar *cp, systime_t time);
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+/**
+ * @brief Data part of a static condition variable initializer.
+ * @details This macro should be used when statically initializing a condition
+ * variable that is part of a bigger structure.
+ */
+#define _CONDVAR_DATA(name) {_THREADSQUEUE_DATA(name.c_queue)}
+
+/**
+ * @brief Static condition variable initializer.
+ * @details Statically initialized condition variables require no explicit
+ * initialization using @p chCondInit().
+ * @param name the name of the condition variable
+ */
+#define CONDVAR_DECL(name) CondVar name = _CONDVAR_DATA(name)
+
+#endif /* CH_USE_CONDVARS && CH_USE_MUTEXES */
+
+#endif /* _CONDVARS_H_ */
+
+/** @} */
diff --git a/os/kernel/include/debug.h b/os/kernel/include/debug.h
new file mode 100644
index 000000000..67a5d65b4
--- /dev/null
+++ b/os/kernel/include/debug.h
@@ -0,0 +1,149 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT 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 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT 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, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file debug.h
+ * @brief Debug macros and structures.
+ * @addtogroup Debug
+ * @{
+ */
+
+#ifndef _DEBUG_H_
+#define _DEBUG_H_
+
+/**
+ * @brief Trace buffer entries.
+ */
+#ifndef TRACE_BUFFER_SIZE
+#define TRACE_BUFFER_SIZE 64
+#endif
+
+/**
+ * @brief Fill value for thread stack area in debug mode.
+ */
+#ifndef STACK_FILL_VALUE
+#define STACK_FILL_VALUE 0x55
+#endif
+
+/**
+ * @brief Fill value for thread area in debug mode.
+ * @note The chosen default value is 0xFF in order to make evident which
+ * thread fields were not initialized when inspecting the memory with
+ * a debugger. A uninitialized field is not an error in itself but it
+ * better to know it.
+ */
+#ifndef THREAD_FILL_VALUE
+#define THREAD_FILL_VALUE 0xFF
+#endif
+
+/**
+ * @brief Trace buffer record.
+ */
+typedef struct {
+ void *cse_wtobjp; /**< Object where going to sleep.*/
+ systime_t cse_time; /**< Time of the switch event.*/
+ uint16_t cse_state: 4; /**< Switched out thread state.*/
+ uint16_t cse_tid: 12; /**< Switched in thdread id.*/
+} CtxSwcEvent;
+
+/**
+ * @brief Trace buffer header.
+ */
+typedef struct {
+ unsigned tb_size; /**< Trace buffer size (records).*/
+ CtxSwcEvent *tb_ptr; /**< Pointer to the ring buffer front.*/
+ CtxSwcEvent tb_buffer[TRACE_BUFFER_SIZE]; /**< Ring buffer.*/
+} TraceBuffer;
+
+#define __QUOTE_THIS(p) #p
+
+#if CH_DBG_ENABLE_CHECKS
+/**
+ * Function parameter check, if the condition check fails then the kernel
+ * panics.
+ * @param c the condition to be verified to be true
+ * @param func the undecorated function name
+ * @note The condition is tested only if the @p CH_DBG_ENABLE_CHECKS switch is
+ * specified in @p chconf.h else the macro does nothing.
+ */
+#define chDbgCheck(c, func) { \
+ if (!(c)) \
+ chDbgPanic(__QUOTE_THIS(func)"(), line "__QUOTE_THIS(__LINE__)); \
+}
+#else /* !CH_DBG_ENABLE_CHECKS */
+#define chDbgCheck(c, func) { \
+ (void)(c), (void)__QUOTE_THIS(func)"(), line "__QUOTE_THIS(__LINE__); \
+}
+#endif /* !CH_DBG_ENABLE_CHECKS */
+
+#if CH_DBG_ENABLE_ASSERTS
+/**
+ * Condition assertion, if the condition check fails then the kernel panics
+ * with the specified message.
+ * @param c the condition to be verified to be true
+ * @param m the text message
+ * @param r a remark string
+ * @note The condition is tested only if the @p CH_DBG_ENABLE_ASSERTS switch is
+ * specified in @p chconf.h else the macro does nothing.
+ * @note The convention for the message is the following:<br>
+ * @<function_name@>(), #@<assert_number@>
+ * @note The remark string is not currently used except for putting a comment
+ * in the code about the assert.
+ */
+#define chDbgAssert(c, m, r) { \
+ if (!(c)) \
+ chDbgPanic(m); \
+}
+#else /* !CH_DBG_ENABLE_ASSERTS */
+#define chDbgAssert(c, m, r) {(void)(c);}
+#endif /* !CH_DBG_ENABLE_ASSERTS */
+
+#if !(CH_DBG_ENABLE_ASSERTS || CH_DBG_ENABLE_CHECKS || CH_DBG_ENABLE_STACK_CHECK)
+/* When the debug features are disabled this function is replaced by an empty
+ * macro.*/
+#define chDbgPanic(msg) {}
+#endif
+
+#if !CH_DBG_ENABLE_TRACE
+/* When the trace feature is disabled this function is replaced by an empty
+ * macro.*/
+#define chDbgTrace(otp, ntp) {}
+#endif
+
+#if !defined(__DOXYGEN__)
+#ifdef __cplusplus
+extern "C" {
+#endif
+#if CH_DBG_ENABLE_TRACE
+ extern TraceBuffer trace_buffer;
+ void trace_init(void);
+ void chDbgTrace(Thread *otp, Thread *ntp);
+#endif
+#if CH_DBG_ENABLE_ASSERTS || CH_DBG_ENABLE_CHECKS || CH_DBG_ENABLE_STACK_CHECK
+ extern char *panic_msg;
+ void chDbgPanic(char *msg);
+#endif
+#ifdef __cplusplus
+}
+#endif
+#endif /* !defined(__DOXYGEN__) */
+
+#endif /* _DEBUG_H_ */
+
+/** @} */
diff --git a/os/kernel/include/events.h b/os/kernel/include/events.h
new file mode 100644
index 000000000..c8bf0c6e6
--- /dev/null
+++ b/os/kernel/include/events.h
@@ -0,0 +1,145 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT 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 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT 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, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file events.h
+ * @brief Events macros and structures.
+ * @addtogroup Events
+ * @{
+ */
+
+#ifndef _EVENTS_H_
+#define _EVENTS_H_
+
+#if CH_USE_EVENTS
+
+typedef struct EventListener EventListener;
+
+/**
+ * @brief Event Listener structure.
+ */
+struct EventListener {
+ EventListener *el_next; /**< Next Event Listener registered on
+ the Event Source.*/
+ Thread *el_listener; /**< Thread interested in the Event
+ Source.*/
+ eventmask_t el_mask; /**< Event flags mask associated by the
+ thread to the Event Source.*/
+};
+
+/**
+ * @brief Event Source structure.
+ */
+typedef struct EventSource {
+ EventListener *es_next; /**< First Event Listener registered on
+ the Event Source.*/
+} EventSource;
+
+/**
+ * @brief Data part of a static event source initializer.
+ * @details This macro should be used when statically initializing an event
+ * source that is part of a bigger structure.
+ * @param name the name of the event source variable
+ */
+#define _EVENTSOURCE_DATA(name) {(void *)(&name)}
+
+/**
+ * @brief Static event source initializer.
+ * @details Statically initialized event sources require no explicit
+ * initialization using @p chEvtInit().
+ * @param name the name of the event source variable
+ */
+#define EVENTSOURCE_DECL(name) EventSource name = _EVENTSOURCE_DATA(name)
+
+/** All events allowed mask.*/
+#define ALL_EVENTS -1
+
+/** Returns the event mask from the event identifier.*/
+#define EVENT_MASK(eid) (1 << (eid))
+
+/**
+ * Registers an Event Listener on an Event Source.
+ * @param esp pointer to the @p EventSource structure
+ * @param elp pointer to the @p EventListener structure
+ * @param eid numeric identifier assigned to the Event Listener. The identifier
+ * is used as index for the event callback function.
+ * The value must range between zero and the size, in bit, of the
+ * @p eventid_t type minus one.
+ * @note Multiple Event Listeners can use the same event identifier, the
+ * listener will share the callback function.
+ */
+#define chEvtRegister(esp, elp, eid) chEvtRegisterMask(esp, elp, EVENT_MASK(eid))
+
+/**
+ * Initializes an Event Source.
+ * @param esp pointer to the @p EventSource structure
+ * @note Can be called with interrupts disabled or enabled.
+ */
+#define chEvtInit(esp) \
+ ((esp)->es_next = (EventListener *)(void *)(esp))
+
+/**
+ * Verifies if there is at least one @p EventListener registered on the
+ * @p EventSource.
+ * @param esp pointer to the @p EventSource structure
+ * @note Can be called with interrupts disabled or enabled.
+ */
+#define chEvtIsListening(esp) \
+ ((void *)(esp) != (void *)(esp)->es_next)
+
+/** Event Handler callback function.*/
+typedef void (*evhandler_t)(eventid_t);
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void chEvtRegisterMask(EventSource *esp, EventListener *elp, eventmask_t emask);
+ void chEvtUnregister(EventSource *esp, EventListener *elp);
+ eventmask_t chEvtClear(eventmask_t mask);
+ eventmask_t chEvtPend(eventmask_t mask);
+ void chEvtSignal(Thread *tp, eventmask_t mask);
+ void chEvtSignalI(Thread *tp, eventmask_t mask);
+ void chEvtBroadcast(EventSource *esp);
+ void chEvtBroadcastI(EventSource *esp);
+ void chEvtDispatch(const evhandler_t handlers[], eventmask_t mask);
+#if CH_OPTIMIZE_SPEED || !CH_USE_EVENTS_TIMEOUT
+ eventmask_t chEvtWaitOne(eventmask_t ewmask);
+ eventmask_t chEvtWaitAny(eventmask_t ewmask);
+ eventmask_t chEvtWaitAll(eventmask_t ewmask);
+#endif
+#if CH_USE_EVENTS_TIMEOUT
+ eventmask_t chEvtWaitOneTimeout(eventmask_t ewmask, systime_t time);
+ eventmask_t chEvtWaitAnyTimeout(eventmask_t ewmask, systime_t time);
+ eventmask_t chEvtWaitAllTimeout(eventmask_t ewmask, systime_t time);
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+#if !CH_OPTIMIZE_SPEED && CH_USE_EVENTS_TIMEOUT
+#define chEvtWaitOne(ewmask) chEvtWaitOneTimeout(ewmask, TIME_INFINITE)
+#define chEvtWaitAny(ewmask) chEvtWaitAnyTimeout(ewmask, TIME_INFINITE)
+#define chEvtWaitAll(ewmask) chEvtWaitAllTimeout(ewmask, TIME_INFINITE)
+#endif
+
+#endif /* CH_USE_EVENTS */
+
+#endif /* _EVENTS_H_ */
+
+/** @} */
diff --git a/os/kernel/include/heap.h b/os/kernel/include/heap.h
new file mode 100644
index 000000000..4c9571070
--- /dev/null
+++ b/os/kernel/include/heap.h
@@ -0,0 +1,43 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT 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 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT 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, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file heap.h
+ * @brief Heap macros and structures.
+ * @addtogroup Heap
+ * @{
+ */
+
+#ifndef _HEAP_H_
+#define _HEAP_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void heap_init(void);
+ void *chHeapAlloc(size_t size);
+ void chHeapFree(void *p);
+ size_t chHeapStatus(size_t *sizep);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _HEAP_H_ */
+
+/** @} */
diff --git a/os/kernel/include/inline.h b/os/kernel/include/inline.h
new file mode 100644
index 000000000..42775d5cb
--- /dev/null
+++ b/os/kernel/include/inline.h
@@ -0,0 +1,72 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT 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 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _INLINE_H_
+#define _INLINE_H_
+
+/**
+ * @file inline.h
+ * @brief Kernel inlined functions.
+ */
+
+/*
+ * Inlined functions if CH_OPTIMIZE_SPEED is enabled.
+ * Note: static inlined functions do not duplicate the code in every module
+ * this is true for GCC, not sure about other compilers.
+ */
+#if CH_OPTIMIZE_SPEED
+static INLINE void prio_insert(Thread *tp, ThreadsQueue *tqp) {
+
+ Thread *cp = (Thread *)tqp;
+ do {
+ cp = cp->p_next;
+ } while ((cp != (Thread *)tqp) && (cp->p_prio >= tp->p_prio));
+ tp->p_prev = (tp->p_next = cp)->p_prev;
+ tp->p_prev->p_next = cp->p_prev = tp;
+}
+
+static INLINE void queue_insert(Thread *tp, ThreadsQueue *tqp) {
+
+ tp->p_prev = (tp->p_next = (Thread *)tqp)->p_prev;
+ tp->p_prev->p_next = tqp->p_prev = tp;
+}
+
+static INLINE Thread *fifo_remove(ThreadsQueue *tqp) {
+ Thread *tp = tqp->p_next;
+
+ (tqp->p_next = tp->p_next)->p_prev = (Thread *)tqp;
+ return tp;
+}
+
+static INLINE Thread *lifo_remove(ThreadsQueue *tqp) {
+ Thread *tp = tqp->p_prev;
+
+ (tqp->p_prev = tp->p_prev)->p_next = (Thread *)tqp;
+ return tp;
+}
+
+static INLINE Thread *dequeue(Thread *tp) {
+
+ tp->p_prev->p_next = tp->p_next;
+ tp->p_next->p_prev = tp->p_prev;
+ return tp;
+}
+#endif /* CH_OPTIMIZE_SPEED */
+
+#endif /* _INLINE_H_ */
diff --git a/os/kernel/include/lists.h b/os/kernel/include/lists.h
new file mode 100644
index 000000000..bc3fd7272
--- /dev/null
+++ b/os/kernel/include/lists.h
@@ -0,0 +1,92 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT 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 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT 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, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file lists.h
+ * @brief Thread queues/lists macros and structures.
+ * @addtogroup ThreadLists
+ * @{
+ */
+
+#ifndef _LISTS_H_
+#define _LISTS_H_
+
+typedef struct Thread Thread;
+
+/**
+ * Threads queue initialization.
+ */
+#define queue_init(tqp) ((tqp)->p_next = (tqp)->p_prev = (Thread *)(tqp));
+
+/**
+ * Macro evaluating to @p TRUE if the specified threads queue is empty.
+ */
+#define isempty(p) ((p)->p_next == (Thread *)(p))
+
+/**
+ * Macro evaluating to @p TRUE if the specified threads queue is not empty.
+ */
+#define notempty(p) ((p)->p_next != (Thread *)(p))
+
+/**
+ * @brief Data part of a static threads queue initializer.
+ * @details This macro should be used when statically initializing a threads
+ * queue that is part of a bigger structure.
+ * @param name the name of the threads queue variable
+ */
+#define _THREADSQUEUE_DATA(name) {(Thread *)&name, (Thread *)&name}
+
+/**
+ * @brief Static threads queue initializer.
+ * @details Statically initialized threads queues require no explicit
+ * initialization using @p queue_init().
+ * @param name the name of the threads queue variable
+ */
+#define THREADSQUEUE_DECL(name) ThreadsQueue name = _THREADSQUEUE_DATA(name)
+
+/**
+ * @brief Generic threads bidirectional linked list header and element.
+ * @extends ThreadsList
+ */
+typedef struct {
+ Thread *p_next; /**< First @p Thread in the queue, or
+ @p ThreadQueue when empty.*/
+ Thread *p_prev; /**< Last @p Thread in the queue, or
+ @p ThreadQueue when empty.*/
+} ThreadsQueue;
+
+#if !CH_OPTIMIZE_SPEED
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void prio_insert(Thread *tp, ThreadsQueue *tqp);
+ void queue_insert(Thread *tp, ThreadsQueue *tqp);
+ Thread *fifo_remove(ThreadsQueue *tqp);
+ Thread *lifo_remove(ThreadsQueue *tqp);
+ Thread *dequeue(Thread *tp);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !CH_OPTIMIZE_SPEED */
+
+#endif /* _LISTS_H_ */
+
+/** @} */
diff --git a/os/kernel/include/mailboxes.h b/os/kernel/include/mailboxes.h
new file mode 100644
index 000000000..075806da8
--- /dev/null
+++ b/os/kernel/include/mailboxes.h
@@ -0,0 +1,126 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT 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 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT 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, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file mailboxes.h
+ * @brief Mailboxes macros and structures.
+ * @addtogroup Mailboxes
+ * @{
+ */
+
+#ifndef _MAILBOXES_H_
+#define _MAILBOXES_H_
+
+#if CH_USE_MAILBOXES
+
+typedef struct {
+ msg_t *mb_buffer; /**< Pointer to the mailbox buffer.*/
+ msg_t *mb_top; /**< Pointer to the first location
+ after the buffer.*/
+ msg_t *mb_wrptr; /**< Write pointer.*/
+ msg_t *mb_rdptr; /**< Read pointer.*/
+ Semaphore mb_fullsem; /**< Full counter @p Semaphore.*/
+ Semaphore mb_emptysem; /**< Empty counter @p Semaphore.*/
+} Mailbox;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void chMBInit(Mailbox *mbp, msg_t *buf, cnt_t n);
+ void chMBReset(Mailbox *mbp);
+ msg_t chMBPost(Mailbox *mbp, msg_t msg, systime_t timeout);
+ msg_t chMBPostS(Mailbox *mbp, msg_t msg, systime_t timeout);
+ msg_t chMBPostAhead(Mailbox *mbp, msg_t msg, systime_t timeout);
+ msg_t chMBPostAheadS(Mailbox *mbp, msg_t msg, systime_t timeout);
+ msg_t chMBFetch(Mailbox *mbp, msg_t *msgp, systime_t timeout);
+ msg_t chMBFetchS(Mailbox *mbp, msg_t *msgp, systime_t timeout);
+#ifdef __cplusplus
+}
+#endif
+
+/**
+ * Returns the mailbox buffer size.
+ * @param[in] mbp the pointer to an initialized Mailbox object
+ */
+#define chMBSize(mbp) \
+ ((mbp)->mb_top - (mbp)->mb_buffer)
+
+/**
+ * Returns the free space into the mailbox.
+ * @param[in] mbp the pointer to an initialized Mailbox object
+ * @return The number of empty message slots.
+ * @note Can be invoked in any system state but if invoked out of a locked
+ * state then the returned value may change after reading.
+ * @note The returned value can be less than zero when there are waiting
+ * threads on the internal semaphore.
+ */
+#define chMBGetEmpty(mbp) chSemGetCounterI(&(mbp)->mb_emptysem)
+
+/**
+ * Returns the number of messages into the mailbox.
+ * @param[in] mbp the pointer to an initialized Mailbox object
+ * @return The number of queued messages.
+ * @note Can be invoked in any system state but if invoked out of a locked
+ * state then the returned value may change after reading.
+ * @note The returned value can be less than zero when there are waiting
+ * threads on the internal semaphore.
+ */
+#define chMBGetFull(mbp) chSemGetCounterI(&(mbp)->mb_fullsem)
+
+/**
+ * Returns the next message in the queue without removing it.
+ * @note A message must be waiting in the queue for this function to work or
+ * it would return garbage. The correct way to use this macro is to
+ * use @p chMBGetFull() and then use this macro, all within a lock state.
+ */
+#define chMBPeek(mbp) (*(mbp)->mb_rdptr)
+
+/**
+ * @brief Data part of a static mailbox initializer.
+ * @details This macro should be used when statically initializing a
+ * mailbox that is part of a bigger structure.
+ * @param name the name of the mailbox variable
+ * @param buffer pointer to the mailbox buffer area
+ * @param size size of the mailbox buffer area
+ */
+#define _MAILBOX_DATA(name, buffer, size) { \
+ (msg_t *)(buffer), \
+ (msg_t *)(buffer) + size, \
+ (msg_t *)(buffer), \
+ (msg_t *)(buffer), \
+ _SEMAPHORE_DATA(name.mb_fullsem, 0), \
+ _SEMAPHORE_DATA(name.mb_emptysem, size), \
+}
+
+/**
+ * @brief Static mailbox initializer.
+ * @details Statically initialized mailboxes require no explicit
+ * initialization using @p chMBInit().
+ * @param name the name of the mailbox variable
+ * @param buffer pointer to the mailbox buffer area
+ * @param size size of the mailbox buffer area
+ */
+#define MAILBOX_DECL(name, buffer, size) \
+ Mailbox name = _MAILBOX_DATA(name, buffer, size)
+
+#endif /* CH_USE_MAILBOXES */
+
+#endif /* _MAILBOXES_H_ */
+
+/** @} */
diff --git a/os/kernel/include/mempools.h b/os/kernel/include/mempools.h
new file mode 100644
index 000000000..38e54b3d8
--- /dev/null
+++ b/os/kernel/include/mempools.h
@@ -0,0 +1,82 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT 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 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT 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, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file mempools.h
+ * @brief Memory Pools macros and structures.
+ * @addtogroup MemoryPools
+ * @{
+ */
+
+#ifndef _MEMPOOLS_H_
+#define _MEMPOOLS_H_
+
+#if CH_USE_MEMPOOLS
+
+/**
+ * @brief Memory pool free object header.
+ */
+struct pool_header {
+ struct pool_header *ph_next;
+};
+
+/**
+ * @brief Memory pool descriptor.
+ */
+typedef struct {
+ struct pool_header *mp_next; /**< Pointer to the header.*/
+ size_t mp_object_size; /**< Memory pool objects size.*/
+} MemoryPool;
+
+/**
+ * @brief Data part of a static memory pool initializer.
+ * @details This macro should be used when statically initializing a
+ * memory pool that is part of a bigger structure.
+ * @param name the name of the memory pool variable
+ * @param size size of the memory pool contained objects
+ */
+#define _MEMORYPOOL_DATA(name, size) {NULL, size}
+
+/**
+ * @brief Static memory pool initializer.
+ * @details Statically initialized memory pools require no explicit
+ * initialization using @p chPoolInit().
+ * @param name the name of the memory pool variable
+ * @param size size of the memory pool contained objects
+ */
+#define MEMORYPOOL_DECL(name, size) \
+ MemoryPool name = _MEMORYPOOL_DATA(name, size)
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void chPoolInit(MemoryPool *mp, size_t size);
+ void *chPoolAllocI(MemoryPool *mp);
+ void *chPoolAlloc(MemoryPool *mp);
+ void chPoolFreeI(MemoryPool *mp, void *objp);
+ void chPoolFree(MemoryPool *mp, void *objp);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* CH_USE_MEMPOOLS */
+
+#endif /* _MEMPOOLS_H_ */
+
+/** @} */
diff --git a/os/kernel/include/messages.h b/os/kernel/include/messages.h
new file mode 100644
index 000000000..ee1449a82
--- /dev/null
+++ b/os/kernel/include/messages.h
@@ -0,0 +1,59 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT 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 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT 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, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file messages.h
+ * @brief Messages macros and structures.
+ * @addtogroup Messages
+ * @{
+ */
+
+#ifndef _MESSAGES_H_
+#define _MESSAGES_H_
+
+#if CH_USE_MESSAGES
+
+/**
+ * Evaluates to TRUE if the thread has pending messages.
+ */
+#define chMsgIsPendingI(tp) \
+ ((tp)->p_msgqueue.p_next != (Thread *)&(tp)->p_msgqueue)
+
+/**
+ * Returns the first message in the queue.
+ */
+#define chMsgGetI(tp) \
+ ((tp)->p_msgqueue.p_next->p_msg)
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ msg_t chMsgSend(Thread *tp, msg_t msg);
+ msg_t chMsgWait(void);
+ msg_t chMsgGet(void);
+ void chMsgRelease(msg_t msg);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* CH_USE_MESSAGES */
+
+#endif /* _MESSAGES_H_ */
+
+/** @} */
diff --git a/os/kernel/include/mutexes.h b/os/kernel/include/mutexes.h
new file mode 100644
index 000000000..6ef6e48f4
--- /dev/null
+++ b/os/kernel/include/mutexes.h
@@ -0,0 +1,84 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT 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 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT 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, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file mutexes.h
+ * @brief Mutexes macros and structures.
+ * @addtogroup Mutexes
+ * @{
+ */
+
+#ifndef _MUTEXES_H_
+#define _MUTEXES_H_
+
+#if CH_USE_MUTEXES
+
+/**
+ * @brief Mutex structure.
+ */
+typedef struct Mutex {
+ ThreadsQueue m_queue; /**< Queue of the threads sleeping on
+ this Mutex.*/
+ Thread *m_owner; /**< Owner @p Thread pointer or
+ @p NULL.*/
+ struct Mutex *m_next; /**< Next @p Mutex into an owner-list
+ or @p NULL.*/
+} Mutex;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void chMtxInit(Mutex *mp);
+ void chMtxLock(Mutex *mp);
+ void chMtxLockS(Mutex *mp);
+ bool_t chMtxTryLock(Mutex *mp);
+ bool_t chMtxTryLockS(Mutex *mp);
+ Mutex *chMtxUnlock(void);
+ Mutex *chMtxUnlockS(void);
+ void chMtxUnlockAll(void);
+#ifdef __cplusplus
+}
+#endif
+
+/**
+ * @brief Data part of a static mutex initializer.
+ * @details This macro should be used when statically initializing a mutex
+ * that is part of a bigger structure.
+ * @param name the name of the mutex variable
+ */
+#define _MUTEX_DATA(name) {_THREADSQUEUE_DATA(name.m_queue), NULL, NULL}
+
+/**
+ * @brief Static mutex initializer.
+ * @details Statically initialized mutexes require no explicit initialization
+ * using @p chMtxInit().
+ * @param name the name of the mutex variable
+ */
+#define MUTEX_DECL(name) Mutex name = _MUTEX_DATA(name)
+
+/**
+ * Returns @p TRUE if the mutex queue contains at least a waiting thread.
+ */
+#define chMtxQueueNotEmptyS(mp) notempty(&(mp)->m_queue)
+
+#endif /* CH_USE_MUTEXES */
+
+#endif /* _MUTEXES_H_ */
+
+/** @} */
diff --git a/os/kernel/include/queues.h b/os/kernel/include/queues.h
new file mode 100644
index 000000000..6bd98b4f1
--- /dev/null
+++ b/os/kernel/include/queues.h
@@ -0,0 +1,218 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT 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 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT 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, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file queues.h I/O
+ * @brief Queues macros and structures.
+ * @addtogroup IOQueues
+ * @{
+ */
+
+#ifndef _QUEUES_H_
+#define _QUEUES_H_
+
+/** Queue notification callback type. */
+typedef void (*qnotify_t)(void);
+
+/** Returned by the queue functions if the operation is successful. */
+#define Q_OK RDY_OK
+/** Returned by the queue functions if a timeout occurs. */
+#define Q_TIMEOUT RDY_TIMEOUT
+/** Returned by the queue functions if the queue is reset. */
+#define Q_RESET RDY_RESET
+/** Returned by the queue functions if the queue is empty. */
+#define Q_EMPTY -3
+/** Returned by the queue functions if the queue is full. */
+#define Q_FULL -4
+
+#if CH_USE_QUEUES
+/**
+ * @brief Generic I/O queue structure.
+ * @details This structure represents a generic Input or Output asymmetrical
+ * queue. The queue is asymmetrical because one end is meant to be
+ * accessed from a thread context, and thus can be blocking, the other
+ * end is accessible from interrupt handlers or from within a kernel
+ * lock zone (see <b>I-Locked</b> and <b>S-Locked</b> states in
+ * @ref system_states) and is non-blocking.
+ */
+typedef struct {
+ uint8_t *q_buffer; /**< Pointer to the queue buffer.*/
+ uint8_t *q_top; /**< Pointer to the first location
+ after the buffer.*/
+ uint8_t *q_wrptr; /**< Write pointer.*/
+ uint8_t *q_rdptr; /**< Read pointer.*/
+ Semaphore q_sem; /**< Counter @p Semaphore.*/
+ qnotify_t q_notify; /**< Data notification callback.*/
+} GenericQueue;
+
+/** Returns the queue's buffer size. */
+#define chQSize(q) ((q)->q_top - (q)->q_buffer)
+
+/**
+ * Returns the used space if used on an Input Queue and the empty space if
+ * used on an Output Queue.
+ * @note The returned value can be less than zero when there are waiting
+ * threads on the internal semaphore.
+ */
+#define chQSpace(q) chSemGetCounterI(&(q)->q_sem)
+
+/**
+ * @brief Input queue structure.
+ * @details This structure represents a generic asymmetrical input queue.
+ * Writing in the queue is non-blocking and can be performed from
+ * interrupt handlers or from within a kernel lock zone (see
+ * <b>I-Locked</b> and <b>S-Locked</b> states in @ref system_states).
+ * Reading the queue can be a blocking operation and is supposed to
+ * be performed by a system thread.
+ * @extends GenericQueue
+ */
+typedef GenericQueue InputQueue;
+
+/** Evaluates to @p TRUE if the specified Input Queue is empty. */
+#define chIQIsEmpty(q) (chQSpace(q) <= 0)
+
+/** Evaluates to @p TRUE if the specified Input Queue is full. */
+#define chIQIsFull(q) (chQSpace(q) >= chQSize(q))
+
+/**
+ * @brief Input queue read.
+ * @details This function reads a byte value from an input queue. If the queue
+ * is empty then the calling thread is suspended until a byte arrives
+ * in the queue.
+ *
+ * @param[in] iqp pointer to an @p InputQueue structure
+ * @return A byte value from the queue or:
+ * @retval Q_RESET if the queue was reset.
+ */
+#define chIQGet(iqp) chIQGetTimeout(iqp, TIME_INFINITE)
+
+/**
+ * @brief Data part of a static input queue initializer.
+ * @details This macro should be used when statically initializing an
+ * input queue that is part of a bigger structure.
+ * @param name the name of the input queue variable
+ * @param buffer pointer to the queue buffer area
+ * @param size size of the queue buffer area
+ * @param inotify input notification callback pointer
+ */
+#define _INPUTQUEUE_DATA(name, buffer, size, inotify) { \
+ (uint8_t *)(buffer), \
+ (uint8_t *)(buffer) + size, \
+ (uint8_t *)(buffer), \
+ (uint8_t *)(buffer), \
+ _SEMAPHORE_DATA(name.q_sem, 0), \
+ inotify \
+}
+
+/**
+ * @brief Static input queue initializer.
+ * @details Statically initialized input queues require no explicit
+ * initialization using @p chIQInit().
+ * @param name the name of the input queue variable
+ * @param buffer pointer to the queue buffer area
+ * @param size size of the queue buffer area
+ * @param inotify input notification callback pointer
+ */
+#define INPUTQUEUE_DECL(name, buffer, size, inotify) \
+ InputQueue name = _INPUTQUEUE_DATA(name, buffer, size, inotify)
+
+/**
+ * @brief Output queue structure.
+ * @details This structure represents a generic asymmetrical output queue.
+ * Reading from the queue is non-blocking and can be performed from
+ * interrupt handlers or from within a kernel lock zone (see
+ * <b>I-Locked</b> and <b>S-Locked</b> states in @ref system_states).
+ * Writing the queue can be a blocking operation and is supposed to
+ * be performed by a system thread.
+ * @extends GenericQueue
+ */
+typedef GenericQueue OutputQueue;
+
+/** Evaluates to @p TRUE if the specified Output Queue is empty. */
+#define chOQIsEmpty(q) (chQSpace(q) >= chQSize(q))
+
+/** Evaluates to @p TRUE if the specified Output Queue is full. */
+#define chOQIsFull(q) (chQSpace(q) <= 0)
+
+/**
+ * @brief Output queue write.
+ * @details This function writes a byte value to an output queue. If the queue
+ * is full then the calling thread is suspended until there is space
+ * in the queue.
+ *
+ * @param[in] oqp pointer to an @p OutputQueue structure
+ * @param[in] b the byte value to be written in the queue
+ * @return The operation status:
+ * @retval Q_OK if the operation succeeded.
+ * @retval Q_RESET if the queue was reset.
+ */
+#define chOQPut(oqp, b) chOQPutTimeout(oqp, b, TIME_INFINITE)
+
+/**
+ * @brief Data part of a static output queue initializer.
+ * @details This macro should be used when statically initializing an
+ * output queue that is part of a bigger structure.
+ * @param name the name of the output queue variable.
+ * @param buffer pointer to the queue buffer area
+ * @param size size of the queue buffer area
+ * @param onotify output notification callback pointer
+ */
+#define _OUTPUTQUEUE_DATA(name, buffer, size, onotify) { \
+ (uint8_t *)(buffer), \
+ (uint8_t *)(buffer) + size, \
+ (uint8_t *)(buffer), \
+ (uint8_t *)(buffer), \
+ _SEMAPHORE_DATA(name.q_sem, size), \
+ onotify \
+}
+
+/**
+ * @brief Static output queue initializer.
+ * @details Statically initialized output queues require no explicit
+ * initialization using @p chOQInit().
+ * @param name the name of the output queue variable
+ * @param buffer pointer to the queue buffer area
+ * @param size size of the queue buffer area
+ * @param onotify output notification callback pointer
+ */
+#define OUTPUTQUEUE_DECL(name, buffer, size, onotify) \
+ InputQueue name = _OUTPUTQUEUE_DATA(name, buffer, size, onotify)
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void chIQInit(InputQueue *qp, uint8_t *buffer, size_t size, qnotify_t inotify);
+ void chIQResetI(InputQueue *qp);
+ msg_t chIQPutI(InputQueue *qp, uint8_t b);
+ msg_t chIQGetTimeout(InputQueue *qp, systime_t timeout);
+ size_t chIQRead(InputQueue *qp, uint8_t *buffer, size_t n);
+
+ void chOQInit(OutputQueue *queue, uint8_t *buffer, size_t size, qnotify_t onotify);
+ void chOQResetI(OutputQueue *queue);
+ msg_t chOQPutTimeout(OutputQueue *queue, uint8_t b, systime_t timeout);
+ msg_t chOQGetI(OutputQueue *queue);
+ size_t chOQWrite(OutputQueue *queue, uint8_t *buffer, size_t n);
+#ifdef __cplusplus
+}
+#endif
+#endif /* CH_USE_QUEUES */
+
+#endif /* _QUEUES_H_ */
+
+/** @} */
diff --git a/os/kernel/include/scheduler.h b/os/kernel/include/scheduler.h
new file mode 100644
index 000000000..648cb7bc5
--- /dev/null
+++ b/os/kernel/include/scheduler.h
@@ -0,0 +1,110 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT 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 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT 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, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file scheduler.h
+ * @brief Scheduler macros and structures.
+ * @addtogroup Scheduler
+ * @{
+ */
+
+#ifndef _SCHEDULER_H_
+#define _SCHEDULER_H_
+
+/** Default thread wakeup low level message. */
+#define RDY_OK 0
+/** Low level message sent to a thread awakened by a timeout. */
+#define RDY_TIMEOUT -1
+/** Low level message sent to a thread awakened by a reset operation. */
+#define RDY_RESET -2
+
+#define NOPRIO 0 /**< Ready list header priority.*/
+#define IDLEPRIO 1 /**< Idle thread priority.*/
+#define LOWPRIO 2 /**< Lowest user priority.*/
+#define NORMALPRIO 64 /**< Normal user priority.*/
+#define HIGHPRIO 127 /**< Highest user priority.*/
+#define ABSPRIO 255 /**< Greatest possible priority.*/
+
+/**
+ * Zero time specification for some syscalls with a timeout
+ * specification.
+ * @note Not all functions accept @p TIME_IMMEDIATE as timeout parameter,
+ * see the specific function documentation.
+ */
+#define TIME_IMMEDIATE ((systime_t)-1)
+
+/**
+ * Infinite time specification for all the syscalls with a timeout
+ * specification.
+ */
+#define TIME_INFINITE ((systime_t)0)
+
+/** The priority of the first thread on the given ready list. */
+#define firstprio(rlp) ((rlp)->p_next->p_prio)
+
+/**
+ * @brief Ready list header.
+ *
+ * @extends ThreadsQueue
+ */
+typedef struct {
+ Thread *p_next; /**< Next @p Thread in the ready list.*/
+ Thread *p_prev; /**< Previous @p Thread in the ready
+ list.*/
+ /* End of the fields shared with the ThreadsQueue structure. */
+ tprio_t r_prio; /**< This field must be initialized to
+ zero.*/
+ /* End of the fields shared with the Thread structure. */
+#if CH_USE_ROUNDROBIN
+ cnt_t r_preempt; /**< Round robin counter.*/
+#endif
+#ifndef CH_CURRP_REGISTER_CACHE
+ Thread *r_current; /**< The currently running thread.*/
+#endif
+} ReadyList;
+
+extern ReadyList rlist;
+
+/*
+ * Scheduler APIs.
+ */
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void scheduler_init(void);
+ Thread *chSchReadyI(Thread *tp);
+ void chSchGoSleepS(tstate_t newstate);
+ msg_t chSchGoSleepTimeoutS(tstate_t newstate, systime_t time);
+ void chSchWakeupS(Thread *tp, msg_t msg);
+ void chSchDoRescheduleI(void);
+ void chSchRescheduleS(void);
+ bool_t chSchRescRequiredI(void);
+#ifdef __cplusplus
+}
+#endif
+
+#ifdef CH_CURRP_REGISTER_CACHE
+register Thread *currp asm(CH_CURRP_REGISTER_CACHE);
+#else
+#define currp rlist.r_current
+#endif
+
+#endif /* _SCHEDULER_H_ */
+
+/** @} */
diff --git a/os/kernel/include/semaphores.h b/os/kernel/include/semaphores.h
new file mode 100644
index 000000000..833fc5cd2
--- /dev/null
+++ b/os/kernel/include/semaphores.h
@@ -0,0 +1,99 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT 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 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT 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, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file semaphores.h
+ * @brief Semaphores macros and structures.
+ * @addtogroup Semaphores
+ * @{
+ */
+
+#ifndef _SEMAPHORES_H_
+#define _SEMAPHORES_H_
+
+#if CH_USE_SEMAPHORES
+
+/**
+ * @brief Semaphore structure.
+ */
+typedef struct Semaphore {
+ ThreadsQueue s_queue; /**< Queue of the threads sleeping on
+ this semaphore.*/
+ cnt_t s_cnt; /**< The semaphore counter.*/
+} Semaphore;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void chSemInit(Semaphore *sp, cnt_t n);
+ void chSemReset(Semaphore *sp, cnt_t n);
+ void chSemResetI(Semaphore *sp, cnt_t n);
+ msg_t chSemWait(Semaphore *sp);
+ msg_t chSemWaitS(Semaphore *sp);
+ msg_t chSemWaitTimeout(Semaphore *sp, systime_t time);
+ msg_t chSemWaitTimeoutS(Semaphore *sp, systime_t time);
+ void chSemSignal(Semaphore *sp);
+ void chSemSignalI(Semaphore *sp);
+#if CH_USE_SEMSW
+ msg_t chSemSignalWait(Semaphore *sps, Semaphore *spw);
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+/**
+ * @brief Data part of a static semaphore initializer.
+ * @details This macro should be used when statically initializing a semaphore
+ * that is part of a bigger structure.
+ * @param name the name of the semaphore variable
+ * @param n the counter initial value, this value must be non-negative
+ */
+#define _SEMAPHORE_DATA(name, n) {_THREADSQUEUE_DATA(name.s_queue), n}
+
+/**
+ * @brief Static semaphore initializer.
+ * @details Statically initialized semaphores require no explicit initialization
+ * using @p chSemInit().
+ * @param name the name of the semaphore variable
+ * @param n the counter initial value, this value must be non-negative
+ */
+#define SEMAPHORE_DECL(name, n) Semaphore name = _SEMAPHORE_DATA(name, n)
+
+/**
+ * Decreases the semaphore counter, this macro can be used when it is ensured
+ * that the counter would not become negative.
+ */
+#define chSemFastWaitI(sp) ((sp)->s_cnt--)
+
+/**
+ * Increases the semaphore counter, this macro can be used when the counter is
+ * not negative.
+ */
+#define chSemFastSignalI(sp) ((sp)->s_cnt++)
+
+/**
+ * Returns the semaphore counter current value.
+ */
+#define chSemGetCounterI(sp) ((sp)->s_cnt)
+
+#endif /* CH_USE_SEMAPHORES */
+
+#endif /* _SEMAPHORES_H_ */
+
+/** @} */
diff --git a/os/kernel/include/serial.h b/os/kernel/include/serial.h
new file mode 100644
index 000000000..deaca3d97
--- /dev/null
+++ b/os/kernel/include/serial.h
@@ -0,0 +1,217 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT 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 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT 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, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file serial.h
+ * @brief Serial Drivers macros and structures.
+ * @addtogroup Serial
+ * @{
+ */
+
+#ifndef _SERIAL_H_
+#define _SERIAL_H_
+
+#if CH_USE_SERIAL_FULLDUPLEX
+
+/** No pending conditions.*/
+#define SD_NO_ERROR 0
+/** Connection happened.*/
+#define SD_CONNECTED 1
+/** Disconnection happened.*/
+#define SD_DISCONNECTED 2
+/** Parity error happened.*/
+#define SD_PARITY_ERROR 4
+/** Framing error happened.*/
+#define SD_FRAMING_ERROR 8
+/** Overflow happened.*/
+#define SD_OVERRUN_ERROR 16
+/** Break detected.*/
+#define SD_BREAK_DETECTED 32
+
+/** Serial Driver condition flags type.*/
+typedef uint8_t dflags_t;
+
+/**
+ * @brief @p FullDuplexDriver specific methods.
+ */
+struct _full_duplex_driver_methods {
+};
+
+/**
+ * @brief @p FullDuplexDriver specific data.
+ */
+struct _full_duplex_driver_data {
+ /**
+ * Input queue, incoming data can be read from this input queue by
+ * using the queues APIs.
+ */
+ InputQueue iqueue;
+ /**
+ * Output queue, outgoing data can be written to this output queue by
+ * using the queues APIs.
+ */
+ OutputQueue oqueue;
+ /**
+ * Status Change @p EventSource. This event is generated when one or more
+ * condition flags change.
+ */
+ EventSource sevent;
+ /**
+ * I/O driver status flags.
+ */
+ dflags_t flags;
+};
+
+/**
+ * @brief @p FullDuplexDriver virtual methods table.
+ */
+struct FullDuplexDriverVMT {
+ /**
+ * @p BaseChannel class inherited methods.
+ */
+ struct _base_channel_methods m0;
+ /**
+ * @p BaseAsynchronousChannel class inherited methods.
+ */
+ struct _base_asynchronous_channel_methods m1;
+ /**
+ * @p FullDuplexDriver specific methods.
+ */
+ struct _full_duplex_driver_methods m2;
+};
+
+/**
+ * @extends BaseAsynchronousChannel
+ *
+ * @brief Full duplex serial driver class.
+ * @details This class extends @p GenericSerialDriver by adding physical I/O
+ * queues.
+ */
+typedef struct {
+ /**
+ * Virtual Methods Table.
+ */
+ const struct FullDuplexDriverVMT *vmt;
+ /**
+ * @p BaseChannel class inherited data.
+ */
+ struct _base_channel_data d0;
+ /**
+ * @p BaseAsynchronousChannel class inherited data.
+ */
+ struct _base_asynchronous_channel_data d1;
+ /**
+ * @p FullDuplexDriver specific data.
+ */
+ struct _full_duplex_driver_data d2;
+} FullDuplexDriver;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void chFDDInit(FullDuplexDriver *sd,
+ uint8_t *ib, size_t isize, qnotify_t inotify,
+ uint8_t *ob, size_t osize, qnotify_t onotify);
+ void chFDDIncomingDataI(FullDuplexDriver *sd, uint8_t b);
+ msg_t chFDDRequestDataI(FullDuplexDriver *sd);
+ void chFDDAddFlagsI(FullDuplexDriver *sd, dflags_t mask);
+ dflags_t chFDDGetAndClearFlags(FullDuplexDriver *sd);
+#ifdef __cplusplus
+}
+#endif
+
+/**
+ * @brief Direct output check on a @p FullDuplexDriver.
+ * @details This function bypasses the indirect access to the channel and
+ * checks directly the output queue. This is faster but cannot
+ * be used to check different channels implementations.
+ * @see chIOPutWouldBlock()
+ */
+#define chFDDPutWouldBlock(sd) chOQIsFull(&(sd)->d2.oqueue)
+
+/**
+ * @brief Direct input check on a @p FullDuplexDriver.
+ * @details This function bypasses the indirect access to the channel and
+ * checks directly the input queue. This is faster but cannot
+ * be used to check different channels implementations.
+ * @see chIOGetWouldBlock()
+ */
+#define chFDDGetWouldBlock(sd) chIQIsEmpty(&(sd)->d2.iqueue)
+
+/**
+ * @brief Direct blocking write to a @p FullDuplexDriver.
+ * @details This function bypasses the indirect access to the channel and
+ * writes directly on the output queue. This is faster but cannot
+ * be used to write to different channels implementations.
+ * @see chIOPut()
+ */
+#define chFDDPut(sd, b) chOQPut(&(sd)->d2.oqueue, b)
+
+/**
+ * @brief Direct blocking write on a @p FullDuplexDriver with timeout
+ * specification.
+ * @details This function bypasses the indirect access to the channel and
+ * writes directly on the output queue. This is faster but cannot
+ * be used to write to different channels implementations.
+ * @see chIOPutTimeout()
+ */
+#define chFDDPutTimeout(sd, b, t) chOQPutTimeout(&(sd)->d2.iqueue, b, t)
+
+/**
+ * @brief Direct blocking read from a @p FullDuplexDriver.
+ * @details This function bypasses the indirect access to the channel and
+ * reads directly from the input queue. This is faster but cannot
+ * be used to read from different channels implementations.
+ * @see chIOGet()
+ */
+#define chFDDGet(sd) chIQGet(&(sd)->d2.iqueue)
+
+/**
+ * @brief Direct blocking read from a @p FullDuplexDriver with timeout
+ * specification.
+ * @details This function bypasses the indirect access to the channel and
+ * reads directly from the input queue. This is faster but cannot
+ * be used to read from different channels implementations.
+ * @see chIOGetTimeout()
+ */
+#define chFDDGetTimeout(sd, t) chIQGetTimeout(&(sd)->d2.iqueue, t)
+
+/**
+ * @brief Direct non-blocking write to a @p FullDuplexDriver.
+ * @details This function bypasses the indirect access to the channel and
+ * writes directly to the output queue. This is faster but cannot
+ * be used to write from different channels implementations.
+ * @see chIOWrite()
+ */
+#define chFDDWrite(sd, b, n) chOQWrite(&(sd)->d2.oqueue, b, n)
+
+/**
+ * @brief Direct non-blocking read on a @p FullDuplexDriver.
+ * @details This function bypasses the indirect access to the channel and
+ * reads directly from the input queue. This is faster but cannot
+ * be used to read from different channels implementations.
+ * @see chIORead()
+ */
+#define chFDDRead(sd, b, n) chIQRead(&(sd)->d2.iqueue, b, n)
+
+#endif /* CH_USE_SERIAL_FULLDUPLEX */
+
+#endif /* _SERIAL_H_ */
+
+/** @} */
diff --git a/os/kernel/include/sys.h b/os/kernel/include/sys.h
new file mode 100644
index 000000000..a84d33da8
--- /dev/null
+++ b/os/kernel/include/sys.h
@@ -0,0 +1,184 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT 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 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT 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, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file sys.h
+ * @brief System related macros and structures.
+ * @addtogroup System
+ * @{
+ */
+
+#ifndef _SYS_H_
+#define _SYS_H_
+
+/**
+ * @brief Halts the system.
+ * @details This function is invoked by the operating system when an
+ * unrecoverable error is detected (as example because a programming error in
+ * the application code that triggers an assertion while in debug mode).
+ */
+#define chSysHalt() port_halt()
+
+/**
+ * @brief Performs a context switch.
+ *
+ * @param otp the thread to be switched out
+ * @param ntp the thread to be switched in
+ */
+#define chSysSwitchI(otp, ntp) port_switch(otp, ntp)
+
+/**
+ * @brief Raises the system interrupt priority mask to the maximum level.
+ * @details All the maskable interrupt sources are disabled regardless their
+ * hardware priority.
+ *
+ * @note The implementation is architecture dependent, it may just disable the
+ * interrupts or be exactly equivalent to @p chSysDisable().
+ * @note Do not invoke this API from within a kernel lock.
+ */
+#define chSysDisable() port_disable()
+
+/**
+ * @brief Raises the system interrupt priority mask to system level.
+ * @details The interrupt sources that should not be able to preempt the kernel
+ * are disabled, interrupt sources with higher priority are still enabled.
+ *
+ * @note The implementation is architecture dependent, it may just disable the
+ * interrupts.
+ * @note Do not invoke this API from within a kernel lock.
+ * @note This API is no replacement for @p chSysLock(), the @p chSysLock()
+ * could do more than just disable the interrupts.
+ */
+#define chSysSuspend() port_suspend()
+
+/**
+ * @brief Lowers the system interrupt priority mask to user level.
+ * @details All the interrupt sources are enabled.
+ *
+ * @note The implementation is architecture dependent, it may just enable the
+ * interrupts.
+ * @note Do not invoke this API from within a kernel lock.
+ * @note This API is no replacement for @p chSysUnlock(), the @p chSysUnlock()
+ * could do more than just enable the interrupts.
+ */
+#define chSysEnable() port_enable()
+
+/**
+ * @brief Enters the kernel lock mode.
+ *
+ * @note The use of kernel lock mode is not recommended in the user code, it is
+ * a better idea to use the semaphores or mutexes instead.
+ * @see CH_USE_NESTED_LOCKS
+ */
+#if CH_USE_NESTED_LOCKS || defined(__DOXYGEN__)
+#if CH_OPTIMIZE_SPEED || defined(__DOXYGEN__)
+#define chSysLock() { \
+ if (currp->p_locks++ == 0) \
+ port_lock(); \
+}
+#endif /* CH_OPTIMIZE_SPEED */
+#else /* !CH_USE_NESTED_LOCKS */
+#define chSysLock() port_lock()
+#endif /* !CH_USE_NESTED_LOCKS */
+
+/**
+ * @brief Leaves the kernel lock mode.
+ *
+ * @note The use of kernel lock mode is not recommended in the user code, it is
+ * a better idea to use the semaphores or mutexes instead.
+ * @see CH_USE_NESTED_LOCKS
+ */
+#if CH_USE_NESTED_LOCKS || defined(__DOXYGEN__)
+#if CH_OPTIMIZE_SPEED || defined(__DOXYGEN__)
+#define chSysUnlock() { \
+ if (--currp->p_locks == 0) \
+ port_unlock(); \
+}
+#endif /* CH_OPTIMIZE_SPEED */
+#else /* !CH_USE_NESTED_LOCKS */
+#define chSysUnlock() port_unlock()
+#endif /* !CH_USE_NESTED_LOCKS */
+
+/**
+ * @brief Enters the kernel lock mode from within an interrupt handler.
+ *
+ * @note This API may do nothing on some architectures, it is required because
+ * on ports that support preemptable interrupt handlers it is required to
+ * raise the interrupt mask to the same level of the system mutual
+ * exclusion zone.<br>
+ * It is good practice to invoke this API before invoking any I-class
+ * syscall from an interrupt handler.
+ * @note This API must be invoked exclusively from interrupt handlers.
+ */
+#define chSysLockFromIsr() port_lock_from_isr()
+
+/**
+ * @brief Leaves the kernel lock mode from within an interrupt handler.
+ *
+ * @note This API may do nothing on some architectures, it is required because
+ * on ports that support preemptable interrupt handlers it is required to
+ * raise the interrupt mask to the same level of the system mutual
+ * exclusion zone.<br>
+ * It is good practice to invoke this API after invoking any I-class
+ * syscall from an interrupt handler.
+ * @note This API must be invoked exclusively from interrupt handlers.
+ */
+#define chSysUnlockFromIsr() port_unlock_from_isr()
+
+/**
+ * @brief IRQ handler enter code.
+ *
+ * @note Usually IRQ handlers functions are also declared naked.
+ * @note On some architectures this macro can be empty.
+ */
+#define CH_IRQ_PROLOGUE() PORT_IRQ_PROLOGUE()
+
+/**
+ * @brief IRQ handler exit code.
+ *
+ * @note Usually IRQ handlers function are also declared naked.
+ * @note This macro usually performs the final reschedulation by using
+ * @p chSchRescRequiredI() and @p chSchDoRescheduleI().
+ */
+#define CH_IRQ_EPILOGUE() PORT_IRQ_EPILOGUE()
+
+/**
+ * @brief Standard IRQ handler declaration.
+ *
+ * @note @p id can be a function name or a vector number depending on the
+ * port implementation.
+ */
+#define CH_IRQ_HANDLER(id) PORT_IRQ_HANDLER(id)
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void chSysInit(void);
+ void chSysTimerHandlerI(void);
+#if CH_USE_NESTED_LOCKS && !CH_OPTIMIZE_SPEED
+ void chSysLock(void);
+ void chSysUnlock(void);
+#endif /* CH_USE_NESTED_LOCKS && !CH_OPTIMIZE_SPEED */
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _SYS_H_ */
+
+/** @} */
diff --git a/os/kernel/include/threads.h b/os/kernel/include/threads.h
new file mode 100644
index 000000000..07e068854
--- /dev/null
+++ b/os/kernel/include/threads.h
@@ -0,0 +1,269 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT 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 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT 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, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file threads.h
+ * @brief Threads macros and structures.
+ * @addtogroup Threads
+ * @{
+ */
+
+#ifndef _THREADS_H_
+#define _THREADS_H_
+
+/**
+ * @brief Structure representing a thread.
+ *
+ * @extends ThreadsQueue
+ * @note Not all the listed fields are always needed, by switching off some
+ * not needed ChibiOS/RT subsystems it is possible to save RAM space by
+ * shrinking the @p Thread structure.
+ */
+struct Thread {
+ Thread *p_next; /**< Next @p Thread in the threads
+ list/queue.*/
+ /* End of the fields shared with the ThreadsList structure. */
+ Thread *p_prev; /**< Previous @p Thread in the threads
+ queue.*/
+ /* End of the fields shared with the ThreadsQueue structure. */
+ tprio_t p_prio; /**< Thread priority.*/
+ /* End of the fields shared with the ReadyList structure. */
+ tstate_t p_state; /**< Current thread state.*/
+ tmode_t p_flags; /**< Various flags.*/
+ struct context p_ctx; /**< Processor context.*/
+#if CH_USE_NESTED_LOCKS
+ cnt_t p_locks; /**< Number of nested locks.*/
+#endif
+#if CH_DBG_THREADS_PROFILING
+ volatile systime_t p_time; /**< Consumed time.
+ @note This field can overflow.*/
+#endif
+ /*
+ * The following fields are merged in unions because they are all
+ * state-specific fields. This trick saves some extra space for each
+ * thread in the system.
+ */
+ union {
+ msg_t p_rdymsg; /**< Thread wakeup code.*/
+ msg_t p_exitcode; /**< The thread exit code
+ (@p PREXIT state).*/
+ void *p_wtobjp; /**< Generic kernel object pointer used
+ for opaque access.*/
+#if CH_USE_SEMAPHORES
+ Semaphore *p_wtsemp; /**< Semaphore where the thread is
+ waiting on (@p PRWTSEM state).*/
+#endif
+#if CH_USE_MUTEXES
+ Mutex *p_wtmtxp; /**< Mutex where the thread is waiting
+ on (@p PRWTMTX state).*/
+#endif
+#if CH_USE_CONDVARS
+ CondVar *p_wtcondp; /**< CondVar where the thread is
+ waiting on (@p PRWTCOND state).*/
+#endif
+#if CH_USE_MESSAGES
+ Thread *p_wtthdp; /**< Destination thread for message
+ send @p PRSNDMSG state).*/
+#endif
+#if CH_USE_EVENTS
+ eventmask_t p_ewmask; /**< Enabled events mask (@p PRWTOREVT
+ or @p PRWTANDEVT states).*/
+#endif
+ };
+ /*
+ * Start of the optional fields.
+ */
+#if CH_USE_WAITEXIT
+ Thread *p_waiting; /**< Thread waiting for termination.*/
+#endif
+#if CH_USE_MESSAGES
+ ThreadsQueue p_msgqueue; /**< Message queue.*/
+ msg_t p_msg; /**< The message.*/
+#endif
+#if CH_USE_EVENTS
+ eventmask_t p_epending; /**< Pending events mask.*/
+#endif
+#if CH_USE_MUTEXES
+ Mutex *p_mtxlist; /**< List of the mutexes owned by this
+ thread, @p NULL terminated.*/
+ tprio_t p_realprio; /**< Thread's own, non-inherited,
+ priority.*/
+#endif
+#if CH_USE_DYNAMIC && CH_USE_MEMPOOLS
+ void *p_mpool; /**< Memory Pool where the thread
+ workspace is returned.*/
+#endif
+ /* Extra fields defined in chconf.h */
+ THREAD_EXT_FIELDS
+};
+
+/** Thread state: Ready to run, waiting on the ready list.*/
+#define PRREADY 0
+/** Thread state: Currently running. */
+#define PRCURR 1
+/** Thread state: Thread created in suspended state. */
+#define PRSUSPENDED 2
+/** Thread state: Waiting on a semaphore. */
+#define PRWTSEM 3
+/** Thread state: Waiting on a mutex. */
+#define PRWTMTX 4
+/** Thread state: Waiting in @p chThdSleep() or @p chThdSleepUntil(). */
+#define PRWTCOND 5
+/** Thread state: Waiting in @p chCondWait(). */
+#define PRSLEEP 6
+/** Thread state: Waiting in @p chThdWait(). */
+#define PRWAIT 7
+/** Thread state: Waiting in @p chEvtWaitOneTimeout() or
+ @p chEvtWaitAnyTimeout(). */
+#define PRWTOREVT 8
+/** Thread state: Waiting in @p chEvtWaitAllTimeout(). */
+#define PRWTANDEVT 9
+/** Thread state: Waiting in @p chMsgSend(). */
+#define PRSNDMSG 10
+/** Thread state: Waiting in @p chMsgWait(). */
+#define PRWTMSG 11
+/** Thread state: After termination.*/
+#define PREXIT 12
+
+/*
+ * Various flags into the thread p_flags field.
+ */
+#define P_MEM_MODE_MASK 3 /* Thread memory mode mask. */
+#define P_MEM_MODE_STATIC 0 /* Thread memory mode: static. */
+#define P_MEM_MODE_HEAP 1 /* Thread memory mode: heap. */
+#define P_MEM_MODE_MEMPOOL 2 /* Thread memory mode: mempool. */
+#define P_TERMINATE 4 /* Termination requested. */
+
+/* Not an API, don't use into the application code.*/
+Thread *init_thread(Thread *tp, tprio_t prio);
+
+/** Thread function.*/
+typedef msg_t (*tfunc_t)(void *);
+
+/*
+ * Threads APIs.
+ */
+#ifdef __cplusplus
+extern "C" {
+#endif
+ Thread *chThdInit(void *wsp, size_t size,
+ tprio_t prio, tfunc_t pf, void *arg);
+ Thread *chThdCreateStatic(void *wsp, size_t size,
+ tprio_t prio, tfunc_t pf, void *arg);
+#if CH_USE_DYNAMIC && CH_USE_WAITEXIT && CH_USE_HEAP
+ Thread *chThdCreateFromHeap(size_t size, tprio_t prio,
+ tfunc_t pf, void *arg);
+#endif
+#if CH_USE_DYNAMIC && CH_USE_WAITEXIT && CH_USE_MEMPOOLS
+ Thread *chThdCreateFromMemoryPool(MemoryPool *mp, tprio_t prio,
+ tfunc_t pf, void *arg);
+#endif
+ tprio_t chThdSetPriority(tprio_t newprio);
+ Thread *chThdResume(Thread *tp);
+ void chThdTerminate(Thread *tp);
+ void chThdSleep(systime_t time);
+ void chThdSleepUntil(systime_t time);
+ void chThdExit(msg_t msg);
+#if CH_USE_WAITEXIT
+ msg_t chThdWait(Thread *tp);
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+/** Returns the pointer to the @p Thread currently in execution.*/
+#define chThdSelf() currp
+
+/** Returns the current thread priority.*/
+#define chThdGetPriority() (currp->p_prio)
+
+/** Returns the pointer to the @p Thread local storage area, if any.*/
+#define chThdLS() (void *)(currp + 1)
+
+/**
+ * Verifies if the specified thread is in the @p PREXIT state.
+ *
+ * @param[in] tp the pointer to the thread
+ * @retval TRUE thread terminated.
+ * @retval FALSE thread not terminated.
+ */
+#define chThdTerminated(tp) ((tp)->p_state == PREXIT)
+
+/**
+ * Verifies if the current thread has a termination request pending.
+ *
+ * @retval TRUE termination request pended.
+ * @retval FALSE termination request not pended.
+ */
+#define chThdShouldTerminate() (currp->p_flags & P_TERMINATE)
+
+/**
+ * Resumes a thread created with @p chThdInit().
+ *
+ * @param[in] tp the pointer to the thread
+ */
+#define chThdResumeI(tp) chSchReadyI(tp)
+
+/**
+ * Suspends the invoking thread for the specified time.
+ *
+ * @param[in] time the delay in system ticks, the special values are handled as
+ * follow:
+ * - @a TIME_INFINITE the thread enters an infinite sleep
+ * state.
+ * - @a TIME_IMMEDIATE this value is accepted but interpreted
+ * as a normal time specification not as an immediate timeout
+ * specification.
+ * .
+ */
+#define chThdSleepS(time) chSchGoSleepTimeoutS(PRSLEEP, time)
+
+/**
+ * Delays the invoking thread for the specified number of seconds.
+ *
+ * @param[in] sec the time in seconds
+ * @note The specified time is rounded up to a value allowed by the real
+ * system clock.
+ * @note The maximum specified value is implementation dependent.
+ */
+#define chThdSleepSeconds(sec) chThdSleep(S2ST(sec))
+
+/**
+ * Delays the invoking thread for the specified number of milliseconds.
+ *
+ * @param[in] msec the time in milliseconds
+ * @note The specified time is rounded up to a value allowed by the real
+ * system clock.
+ * @note The maximum specified value is implementation dependent.
+ */
+#define chThdSleepMilliseconds(msec) chThdSleep(MS2ST(msec))
+
+/**
+ * Delays the invoking thread for the specified number of microseconds.
+ *
+ * @param[in] usec the time in microseconds
+ * @note The specified time is rounded up to a value allowed by the real
+ * system clock.
+ * @note The maximum specified value is implementation dependent.
+ */
+#define chThdSleepMicroseconds(usec) chThdSleep(US2ST(usec))
+
+#endif /* _THREADS_H_ */
+
+/** @} */
diff --git a/os/kernel/include/vt.h b/os/kernel/include/vt.h
new file mode 100644
index 000000000..003cffd45
--- /dev/null
+++ b/os/kernel/include/vt.h
@@ -0,0 +1,125 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT 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 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT 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, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file vt.h
+ * @brief Time macros and structures.
+ * @addtogroup Time
+ * @{
+ */
+
+#ifndef _VT_H_
+#define _VT_H_
+
+/**
+ * Time conversion utility. Converts from seconds to system ticks number.
+ */
+#define S2ST(sec) ((systime_t)((sec) * CH_FREQUENCY))
+
+/**
+ * Time conversion utility. Converts from milliseconds to system ticks number.
+ * @note The result is rounded upward to the next tick boundary.
+ */
+#define MS2ST(msec) ((systime_t)(((((msec) - 1L) * CH_FREQUENCY) / 1000L) + 1L))
+
+/**
+ * Time conversion utility. Converts from microseconds to system ticks number.
+ * @note The result is rounded upward to the next tick boundary.
+ */
+#define US2ST(usec) ((systime_t)(((((usec) - 1L) * CH_FREQUENCY) / 1000000L) + 1L))
+
+/** Virtual Timer callback function.*/
+typedef void (*vtfunc_t)(void *);
+
+typedef struct VirtualTimer VirtualTimer;
+
+/**
+ * @brief Virtual Timer descriptor structure.
+ * @extends DeltaList
+ */
+struct VirtualTimer {
+ VirtualTimer *vt_next; /**< Next timer in the delta list.*/
+ VirtualTimer *vt_prev; /**< Previous timer in the delta list.*/
+ systime_t vt_time; /**< Time delta before timeout.*/
+ vtfunc_t vt_func; /**< Timer callback function pointer.
+ The pointer is reset to zero after
+ the callback is invoked.*/
+ void *vt_par; /**< Timer callback function
+ parameter.*/
+};
+
+/**
+ * @brief Virtual timers list header.
+ * @note The delta list is implemented as a double link bidirectional list in
+ * order to make the unlink time constant, the reset of a virtual timer
+ * is often used in the code.
+ */
+typedef struct {
+ VirtualTimer *vt_next; /**< Next timer in the delta list (the
+ one that will be triggered next).*/
+ VirtualTimer *vt_prev; /**< Last timer in the delta list.*/
+ systime_t vt_time; /**< Must be initialized to -1.*/
+ volatile systime_t vt_systime; /**< System Time counter.*/
+} VTList;
+
+extern VTList vtlist;
+
+#define chVTDoTickI() { \
+ vtlist.vt_systime++; \
+ if (&vtlist != (VTList *)vtlist.vt_next) { \
+ VirtualTimer *vtp; \
+ \
+ --vtlist.vt_next->vt_time; \
+ while (!(vtp = vtlist.vt_next)->vt_time) { \
+ vtfunc_t fn = vtp->vt_func; \
+ vtp->vt_func = NULL; \
+ (vtp->vt_next->vt_prev = (void *)&vtlist)->vt_next = vtp->vt_next;\
+ fn(vtp->vt_par); \
+ } \
+ } \
+}
+
+/*
+ * Virtual Timers APIs.
+ */
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void vt_init(void);
+ void chVTSetI(VirtualTimer *vtp, systime_t time, vtfunc_t vtfunc, void *par);
+ void chVTResetI(VirtualTimer *vtp);
+ bool_t chTimeIsWithin(systime_t start, systime_t end);
+#ifdef __cplusplus
+}
+#endif
+
+/** Returns TRUE if the speciified timer is armed.*/
+#define chVTIsArmedI(vtp) ((vtp)->vt_func != NULL)
+
+/**
+ * Returns the number of system ticks since the @p chSysInit() invocation.
+ * @return the system ticks number
+ * @note The counter can reach its maximum and then returns to zero.
+ * @note This function is designed to work with the @p chThdSleepUntil().
+ */
+#define chTimeNow() (vtlist.vt_systime)
+
+#endif /* _VT_H_ */
+
+/** @} */
diff --git a/os/kernel/kernel.mk b/os/kernel/kernel.mk
new file mode 100644
index 000000000..29644a5a9
--- /dev/null
+++ b/os/kernel/kernel.mk
@@ -0,0 +1,13 @@
+# List of all the ChibiOS/RT kernel files, there is no need to remove the files
+# from this list, you can disable parts of the kernel by editing chconf.h.
+KERNSRC = ../../os/kernel/src/chsys.c ../../os/kernel/src/chdebug.c \
+ ../../os/kernel/src/chlists.c ../../os/kernel/src/chvt.c \
+ ../../os/kernel/src/chschd.c ../../os/kernel/src/chthreads.c \
+ ../../os/kernel/src/chsem.c ../../os/kernel/src/chmtx.c \
+ ../../os/kernel/src/chcond.c ../../os/kernel/src/chevents.c \
+ ../../os/kernel/src/chmsg.c ../../os/kernel/src/chmboxes.c \
+ ../../os/kernel/src/chqueues.c ../../os/kernel/src/chheap.c \
+ ../../os/kernel/src/chmempools.c ../../os/kernel/src/chserial.c
+
+# Required include directories
+KERNINC = ../../os/kernel/include
diff --git a/os/kernel/readme.txt b/os/kernel/readme.txt
new file mode 100644
index 000000000..9a15d02f1
--- /dev/null
+++ b/os/kernel/readme.txt
@@ -0,0 +1 @@
+ChibiOS/RT portable kernel code \ No newline at end of file
diff --git a/os/kernel/src/chcond.c b/os/kernel/src/chcond.c
new file mode 100644
index 000000000..ef58f1ddf
--- /dev/null
+++ b/os/kernel/src/chcond.c
@@ -0,0 +1,227 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT 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 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT 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, see <http://www.gnu.org/licenses/>.
+*/
+/*
+ Concepts and parts of this file are contributed by and Copyright (C) 2008
+ of Leon Woestenberg.
+ */
+
+/**
+ * @file chcond.c
+ * @brief Condition Variables code.
+ * @addtogroup CondVars
+ * @{
+ */
+
+#include <ch.h>
+
+#if CH_USE_CONDVARS && CH_USE_MUTEXES
+
+/**
+ * @brief Initializes s @p CondVar structure.
+ *
+ * @param[out] cp pointer to a @p CondVar structure
+ * @note This function can be invoked from within an interrupt handler even if
+ * it is not an I-Class API because it does not touch any critical kernel
+ * data structure.
+ */
+void chCondInit(CondVar *cp) {
+
+ chDbgCheck(cp != NULL, "chCondInit");
+
+ queue_init(&cp->c_queue);
+}
+
+/**
+ * @brief Signals one thread that is waiting on the condition variable.
+ *
+ * @param[in] cp pointer to the @p CondVar structure
+ */
+void chCondSignal(CondVar *cp) {
+
+ chDbgCheck(cp != NULL, "chCondSignal");
+
+ chSysLock();
+ if (notempty(&cp->c_queue)) /* any thread ? */
+ chSchWakeupS(fifo_remove(&cp->c_queue), RDY_OK);
+ chSysUnlock();
+}
+
+/**
+ * @brief Signals one thread that is waiting on the condition variable.
+ *
+ * @param[in] cp pointer to the @p CondVar structure
+ */
+void chCondSignalI(CondVar *cp) {
+
+ chDbgCheck(cp != NULL, "chCondSignalI");
+
+ if (notempty(&cp->c_queue)) /* any thread ? */
+ chSchReadyI(fifo_remove(&cp->c_queue))->p_rdymsg = RDY_OK;
+}
+
+/**
+ * @brief Signals all threads that are waiting on the condition variable.
+ *
+ * @param[in] cp pointer to the @p CondVar structure
+ */
+void chCondBroadcast(CondVar *cp) {
+
+ chSysLock();
+ chCondBroadcastI(cp);
+ chSchRescheduleS();
+ chSysUnlock();
+}
+
+/**
+ * @brief Signals all threads that are waiting on the condition variable.
+ *
+ * @param[in] cp pointer to the @p CondVar structure
+ */
+void chCondBroadcastI(CondVar *cp) {
+
+ chDbgCheck(cp != NULL, "chCondBroadcastI");
+
+ /* empties the condition variable queue and inserts all the Threads into the
+ * ready list in FIFO order. The wakeup message is set to @p RDY_RESET in
+ * order to make a chCondBroadcast() detectable from a chCondSignal(). */
+ while (cp->c_queue.p_next != (void *)&cp->c_queue)
+ chSchReadyI(fifo_remove(&cp->c_queue))->p_rdymsg = RDY_RESET;
+}
+
+/**
+ * @brief Waits on the condition variable releasing the mutex lock.
+ * @details Releases the mutex, waits on the condition variable, and finally
+ * acquires the mutex again. This is done atomically.
+ *
+ * @param[in] cp pointer to the @p CondVar structure
+ * @return The wakep mode.
+ * @retval RDY_OK if the condvar was signaled using chCondSignal().
+ * @retval RDY_RESET if the condvar was signaled using chCondBroadcast().
+ * @note The thread MUST already have locked the mutex when calling
+ * @p chCondWait().
+ */
+msg_t chCondWait(CondVar *cp) {
+ msg_t msg;
+
+ chSysLock();
+ msg = chCondWaitS(cp);
+ chSysUnlock();
+ return msg;
+}
+
+/**
+ * @brief Waits on the condition variable releasing the mutex lock.
+ * @details Releases the mutex, waits on the condition variable, and finally
+ * acquires the mutex again. This is done atomically.
+ *
+ * @param[in] cp pointer to the @p CondVar structure
+ * @return The wakep mode.
+ * @retval RDY_OK if the condvar was signaled using chCondSignal().
+ * @retval RDY_RESET if the condvar was signaled using chCondBroadcast().
+ * @note The thread MUST already have locked the mutex when calling
+ * @p chCondWaitS().
+ */
+msg_t chCondWaitS(CondVar *cp) {
+ Mutex *mp;
+ msg_t msg;
+
+ chDbgCheck(cp != NULL, "chCondWaitS");
+ chDbgAssert(currp->p_mtxlist != NULL,
+ "chCondWaitS(), #1",
+ "not owning a mutex");
+
+ mp = chMtxUnlockS(); /* unlocks the condvar mutex */
+ prio_insert(currp, &cp->c_queue); /* enters the condvar queue */
+ currp->p_wtcondp = cp; /* needed by the tracer */
+ chSchGoSleepS(PRWTCOND); /* waits on the condvar */
+ msg = currp->p_rdymsg; /* fetches the wakeup message */
+ chMtxLockS(mp); /* atomically relocks the mutex */
+ return msg; /* returns the wakeup message */
+}
+
+#if CH_USE_CONDVARS_TIMEOUT
+/**
+ * @brief Waits on the condition variable releasing the mutex lock.
+ * @details Releases the mutex, waits on the condition variable, and finally
+ * acquires the mutex again. This is done atomically.
+ *
+ * @param[in] cp pointer to the @p CondVar structure
+ * @param[in] time the number of ticks before the operation timeouts,
+ * the special value @p TIME_INFINITE is allowed.
+ * It is not possible to specify zero @p TIME_IMMEDIATE
+ * as timeout specification because it would make no sense
+ * in this function.
+ * @return The wakep mode.
+ * @retval RDY_OK if the condvar was signaled using chCondSignal().
+ * @retval RDY_RESET if the condvar was signaled using chCondBroadcast().
+ * @retval RDY_TIMEOUT if the condvar was not signaled within the specified
+ * timeout.
+ * @note The thread MUST already have locked the mutex when calling
+ * @p chCondWaitTimeout().
+ */
+msg_t chCondWaitTimeout(CondVar *cp, systime_t time) {
+ msg_t msg;
+
+ chSysLock();
+ msg = chCondWaitTimeoutS(cp, time);
+ chSysUnlock();
+ return msg;
+}
+
+/**
+ * @brief Waits on the condition variable releasing the mutex lock.
+ * @details Releases the mutex, waits on the condition variable, and finally
+ * acquires the mutex again. This is done atomically.
+ *
+ * @param[in] cp pointer to the @p CondVar structure
+ * @param[in] time the number of ticks before the operation timeouts,
+ * the special value @p TIME_INFINITE is allowed.
+ * It is not possible to specify zero @p TIME_IMMEDIATE
+ * as timeout specification because it would make no sense
+ * in this function.
+ * @return The wakep mode.
+ * @retval RDY_OK if the condvar was signaled using chCondSignal().
+ * @retval RDY_RESET if the condvar was signaled using chCondBroadcast().
+ * @retval RDY_TIMEOUT if the condvar was not signaled within the specified
+ * timeout.
+ * @note The thread MUST already have locked the mutex when calling
+ * @p chCondWaitTimeoutS().
+ */
+msg_t chCondWaitTimeoutS(CondVar *cp, systime_t time) {
+ Mutex *mp;
+ msg_t msg;
+
+ chDbgCheck(cp != NULL, "chCondWaitTimeoutS");
+ chDbgAssert(currp->p_mtxlist != NULL,
+ "chCondWaitTimeoutS(), #1",
+ "not owning a mutex");
+
+ mp = chMtxUnlockS(); /* unlocks the condvar mutex */
+ prio_insert(currp, &cp->c_queue); /* enters the condvar queue */
+ currp->p_wtcondp = cp; /* needed by the tracer */
+ chSchGoSleepTimeoutS(PRWTCOND, time); /* waits on the condvar */
+ msg = currp->p_rdymsg; /* fetches the wakeup message */
+ chMtxLockS(mp); /* atomically relocks the mutex */
+ return msg; /* returns the wakeup message */
+}
+#endif /* CH_USE_CONDVARS_TIMEOUT */
+
+#endif /* CH_USE_CONDVARS && CH_USE_MUTEXES */
+
+/** @} */
diff --git a/os/kernel/src/chdebug.c b/os/kernel/src/chdebug.c
new file mode 100644
index 000000000..9a8120b29
--- /dev/null
+++ b/os/kernel/src/chdebug.c
@@ -0,0 +1,81 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT 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 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT 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, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file chdebug.c
+ * @brief ChibiOS/RT Debug code.
+ * @addtogroup Debug
+ * @{
+ */
+
+#include <ch.h>
+
+#if CH_DBG_ENABLE_TRACE
+/**
+ * @brief Public trace buffer.
+ */
+TraceBuffer trace_buffer;
+
+/**
+ * @brief Trace circular buffer subsystem initialization.
+ */
+void trace_init(void) {
+
+ trace_buffer.tb_size = TRACE_BUFFER_SIZE;
+ trace_buffer.tb_ptr = &trace_buffer.tb_buffer[0];
+}
+
+/**
+ * @brief Inserts in the circular debug trace buffer a context switch record.
+ *
+ * @param[in] otp the thread being switched out
+ * @param[in] ntp the thread to be switched in
+ */
+void chDbgTrace(Thread *otp, Thread *ntp) {
+
+ trace_buffer.tb_ptr->cse_wtobjp = otp->p_wtobjp;
+ trace_buffer.tb_ptr->cse_time = chTimeNow();
+ trace_buffer.tb_ptr->cse_state = otp->p_state;
+ trace_buffer.tb_ptr->cse_tid = (unsigned)ntp >> 4;
+ if (++trace_buffer.tb_ptr >= &trace_buffer.tb_buffer[TRACE_BUFFER_SIZE])
+ trace_buffer.tb_ptr = &trace_buffer.tb_buffer[0];
+}
+#endif /* CH_DBG_ENABLE_TRACE */
+
+#if CH_DBG_ENABLE_ASSERTS || CH_DBG_ENABLE_CHECKS || CH_DBG_ENABLE_STACK_CHECK
+/**
+ * @brief Pointer to the panic message.
+ * @details This pointer is meant to be accessed through the debugger, it is
+ * written once and then the system is halted.
+ */
+char *panic_msg;
+
+/**
+ * @brief Prints a panic message on the console and then halts the system.
+ *
+ * @param[in] msg the pointer to the panic message string
+ */
+void chDbgPanic(char *msg) {
+
+ panic_msg = msg;
+ chSysHalt();
+}
+#endif /* CH_DBG_ENABLE_ASSERTS || CH_DBG_ENABLE_CHECKS || CH_DBG_ENABLE_STACK_CHECK */
+
+/** @} */
diff --git a/os/kernel/src/chevents.c b/os/kernel/src/chevents.c
new file mode 100644
index 000000000..098adce5e
--- /dev/null
+++ b/os/kernel/src/chevents.c
@@ -0,0 +1,392 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT 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 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT 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, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file chevents.c
+ * @brief Events code.
+ * @addtogroup Events
+ * @{
+ */
+#include <ch.h>
+
+#if CH_USE_EVENTS
+/**
+ * @brief Registers an Event Listener on an Event Source.
+ *
+ * @param[in] esp pointer to the @p EventSource structure
+ * @param[in] elp pointer to the @p EventListener structure
+ * @param[in] emask the mask of event flags to be pended to the thread when the
+ * event source is broadcasted
+ * @note Multiple Event Listeners can specify the same bits to be pended.
+ */
+void chEvtRegisterMask(EventSource *esp, EventListener *elp, eventmask_t emask) {
+
+ chDbgCheck((esp != NULL) && (elp != NULL), "chEvtRegisterMask");
+
+ chSysLock();
+ elp->el_next = esp->es_next;
+ esp->es_next = elp;
+ elp->el_listener = currp;
+ elp->el_mask = emask;
+ chSysUnlock();
+}
+
+/**
+ * @brief Unregisters an Event Listener from its Event Source.
+ *
+ * @param[in] esp pointer to the @p EventSource structure
+ * @param[in] elp pointer to the @p EventListener structure
+ * @note If the event listener is not registered on the specified event source
+ * then the function does nothing.
+ * @note For optimal performance it is better to perform the unregister
+ * operations in inverse order of the register operations (elements are
+ * found on top of the list).
+ */
+void chEvtUnregister(EventSource *esp, EventListener *elp) {
+ EventListener *p;
+
+ chDbgCheck((esp != NULL) && (elp != NULL), "chEvtUnregister");
+
+ p = (EventListener *)esp;
+ chSysLock();
+ while (p->el_next != (EventListener *)esp) {
+ if (p->el_next == elp) {
+ p->el_next = elp->el_next;
+ break;
+ }
+ p = p->el_next;
+ }
+ chSysUnlock();
+}
+
+/**
+ * @brief Clears the pending events specified in the mask.
+ *
+ * @param[in] mask the events to be cleared
+ * @return The pending events that were cleared.
+ */
+eventmask_t chEvtClear(eventmask_t mask) {
+ eventmask_t m;
+
+ chSysLock();
+
+ m = currp->p_epending & mask;
+ currp->p_epending &= ~mask;
+
+ chSysUnlock();
+ return m;
+}
+
+/**
+ * @brief Pends a set of event flags on the current thread, this is @b much
+ * faster than using @p chEvtBroadcast() or @p chEvtSignal().
+ *
+ * @param[in] mask the events to be pended
+ * @return The current pending events mask.
+ */
+eventmask_t chEvtPend(eventmask_t mask) {
+
+ chSysLock();
+
+ mask = (currp->p_epending |= mask);
+
+ chSysUnlock();
+ return mask;
+}
+
+/**
+ * @brief Pends a set of event flags on the specified @p Thread.
+ *
+ * @param[in] tp the thread to be signaled
+ * @param[in] mask the event flags set to be pended
+ */
+void chEvtSignal(Thread *tp, eventmask_t mask) {
+
+ chDbgCheck(tp != NULL, "chEvtSignal");
+
+ chSysLock();
+ chEvtSignalI(tp, mask);
+ chSysUnlock();
+}
+
+/**
+ * @brief Pends a set of event flags on the specified @p Thread.
+ *
+ * @param[in] tp the thread to be signaled
+ * @param[in] mask the event flags set to be pended
+ */
+void chEvtSignalI(Thread *tp, eventmask_t mask) {
+
+ chDbgCheck(tp != NULL, "chEvtSignalI");
+
+ tp->p_epending |= mask;
+ /* Test on the AND/OR conditions wait states.*/
+ if (((tp->p_state == PRWTOREVT) && ((tp->p_epending & tp->p_ewmask) != 0)) ||
+ ((tp->p_state == PRWTANDEVT) && ((tp->p_epending & tp->p_ewmask) == tp->p_ewmask)))
+ chSchReadyI(tp)->p_rdymsg = RDY_OK;
+}
+
+/**
+ * @brief Signals all the Event Listeners registered on the specified Event
+ * Source.
+ *
+ * @param[in] esp pointer to the @p EventSource structure
+ */
+void chEvtBroadcast(EventSource *esp) {
+
+ chSysLock();
+ chEvtBroadcastI(esp);
+ chSchRescheduleS();
+ chSysUnlock();
+}
+
+/**
+ * @brief Signals all the Event Listeners registered on the specified Event
+ * Source.
+ *
+ * @param[in] esp pointer to the @p EventSource structure
+ */
+void chEvtBroadcastI(EventSource *esp) {
+ EventListener *elp;
+
+ chDbgCheck(esp != NULL, "chEvtBroadcastI");
+
+ elp = esp->es_next;
+ while (elp != (EventListener *)esp) {
+ chEvtSignalI(elp->el_listener, elp->el_mask);
+ elp = elp->el_next;
+ }
+}
+
+/**
+ * @brief Invokes the event handlers associated with a mask.
+ *
+ * @param[in] mask mask of the events to be dispatched
+ * @param[in] handlers an array of @p evhandler_t. The array must have size
+ * equal to the number of bits in eventmask_t.
+ */
+void chEvtDispatch(const evhandler_t handlers[], eventmask_t mask) {
+ eventid_t eid;
+
+ chDbgCheck(handlers != NULL, "chEvtDispatch");
+
+ eid = 0;
+ while (mask) {
+ if (mask & EVENT_MASK(eid)) {
+ chDbgAssert(handlers[eid] != NULL,
+ "chEvtDispatch(), #1",
+ "null handler");
+ mask &= ~EVENT_MASK(eid);
+ handlers[eid](eid);
+ }
+ eid++;
+ }
+}
+
+#if CH_OPTIMIZE_SPEED || !CH_USE_EVENTS_TIMEOUT || defined(__DOXYGEN__)
+/**
+ * @brief Waits for exactly one of the specified events.
+ * @details The function waits for one event among those specified in
+ * @p ewmask to become pending then the event is cleared and returned.
+ *
+ * @param[in] ewmask mask of the events that the function should wait for,
+ * @p ALL_EVENTS enables all the events
+ * @return The mask of the lowest id served and cleared event.
+ * @note One and only one event is served in the function, the one with the
+ * lowest event id. The function is meant to be invoked into a loop in
+ * order to serve all the pending events.<br>
+ * This means that Event Listeners with a lower event identifier have
+ * an higher priority.
+ */
+eventmask_t chEvtWaitOne(eventmask_t ewmask) {
+ eventmask_t m;
+
+ chSysLock();
+
+ if ((m = (currp->p_epending & ewmask)) == 0) {
+ currp->p_ewmask = ewmask;
+ chSchGoSleepS(PRWTOREVT);
+ m = currp->p_epending & ewmask;
+ }
+ m &= -m;
+ currp->p_epending &= ~m;
+
+ chSysUnlock();
+ return m;
+}
+
+/**
+ * @brief Waits for any of the specified events.
+ * @details The function waits for any event among those specified in
+ * @p ewmask to become pending then the events are cleared and returned.
+ *
+ * @param[in] ewmask mask of the events that the function should wait for,
+ * @p ALL_EVENTS enables all the events
+ * @return The mask of the served and cleared events.
+ */
+eventmask_t chEvtWaitAny(eventmask_t ewmask) {
+ eventmask_t m;
+
+ chSysLock();
+
+ if ((m = (currp->p_epending & ewmask)) == 0) {
+ currp->p_ewmask = ewmask;
+ chSchGoSleepS(PRWTOREVT);
+ m = currp->p_epending & ewmask;
+ }
+ currp->p_epending &= ~m;
+
+ chSysUnlock();
+ return m;
+}
+
+/**
+ * @brief Waits for all the specified events.
+ * @details The function waits for all the events specified in @p ewmask to
+ * become pending then the events are cleared and returned.
+ *
+ * @param[in] ewmask mask of the event ids that the function should wait for
+ * @return The mask of the served and cleared events.
+ */
+eventmask_t chEvtWaitAll(eventmask_t ewmask) {
+
+ chSysLock();
+
+ if ((currp->p_epending & ewmask) != ewmask) {
+ currp->p_ewmask = ewmask;
+ chSchGoSleepS(PRWTANDEVT);
+ }
+ currp->p_epending &= ~ewmask;
+
+ chSysUnlock();
+ return ewmask;
+}
+#endif /* CH_OPTIMIZE_SPEED || !CH_USE_EVENTS_TIMEOUT */
+
+#if CH_USE_EVENTS_TIMEOUT
+/**
+ * @brief Waits for exactly one of the specified events.
+ * @details The function waits for one event among those specified in
+ * @p ewmask to become pending then the event is cleared and returned.
+ *
+ * @param[in] ewmask mask of the events that the function should wait for,
+ * @p ALL_EVENTS enables all the events
+ * @param[in] time the number of ticks before the operation timeouts,
+ * the following special values are allowed:
+ * - @a TIME_IMMEDIATE immediate timeout.
+ * - @a TIME_INFINITE no timeout.
+ * .
+ * @return The mask of the lowest id served and cleared event.
+ * @retval 0 if the specified timeout expired.
+ * @note One and only one event is served in the function, the one with the
+ * lowest event id. The function is meant to be invoked into a loop in
+ * order to serve all the pending events.<br>
+ * This means that Event Listeners with a lower event identifier have
+ * an higher priority.
+ */
+eventmask_t chEvtWaitOneTimeout(eventmask_t ewmask, systime_t time) {
+ eventmask_t m;
+
+ chSysLock();
+
+ if ((m = (currp->p_epending & ewmask)) == 0) {
+ if (TIME_IMMEDIATE == time)
+ return (eventmask_t)0;
+ currp->p_ewmask = ewmask;
+ if (chSchGoSleepTimeoutS(PRWTOREVT, time) < RDY_OK)
+ return (eventmask_t)0;
+ m = currp->p_epending & ewmask;
+ }
+ m &= -m;
+ currp->p_epending &= ~m;
+
+ chSysUnlock();
+ return m;
+}
+
+/**
+ * @brief Waits for any of the specified events.
+ * @details The function waits for any event among those specified in
+ * @p ewmask to become pending then the events are cleared and
+ * returned.
+ *
+ * @param[in] ewmask mask of the events that the function should wait for,
+ * @p ALL_EVENTS enables all the events
+ * @param[in] time the number of ticks before the operation timeouts,
+ * the following special values are allowed:
+ * - @a TIME_IMMEDIATE immediate timeout.
+ * - @a TIME_INFINITE no timeout.
+ * .
+ * @return The mask of the served and cleared events.
+ * @retval 0 if the specified timeout expired.
+ */
+eventmask_t chEvtWaitAnyTimeout(eventmask_t ewmask, systime_t time) {
+ eventmask_t m;
+
+ chSysLock();
+
+ if ((m = (currp->p_epending & ewmask)) == 0) {
+ if (TIME_IMMEDIATE == time)
+ return (eventmask_t)0;
+ currp->p_ewmask = ewmask;
+ if (chSchGoSleepTimeoutS(PRWTOREVT, time) < RDY_OK)
+ return (eventmask_t)0;
+ m = currp->p_epending & ewmask;
+ }
+ currp->p_epending &= ~m;
+
+ chSysUnlock();
+ return m;
+}
+
+/**
+ * @brief Waits for all the specified events.
+ * @details The function waits for all the events specified in @p ewmask to
+ * become pending then the events are cleared and returned.
+ *
+ * @param[in] ewmask mask of the event ids that the function should wait for
+ * @param[in] time the number of ticks before the operation timeouts,
+ * the following special values are allowed:
+ * - @a TIME_IMMEDIATE immediate timeout.
+ * - @a TIME_INFINITE no timeout.
+ * .
+ * @return The mask of the served and cleared events.
+ * @retval 0 if the specified timeout expired.
+ */
+eventmask_t chEvtWaitAllTimeout(eventmask_t ewmask, systime_t time) {
+
+ chSysLock();
+
+ if ((currp->p_epending & ewmask) != ewmask) {
+ if (TIME_IMMEDIATE == time)
+ return (eventmask_t)0;
+ currp->p_ewmask = ewmask;
+ if (chSchGoSleepTimeoutS(PRWTANDEVT, time) < RDY_OK)
+ return (eventmask_t)0;
+ }
+ currp->p_epending &= ~ewmask;
+
+ chSysUnlock();
+ return ewmask;
+}
+#endif /* CH_USE_EVENTS_TIMEOUT */
+
+#endif /* CH_USE_EVENTS */
+
+/** @} */
diff --git a/os/kernel/src/chheap.c b/os/kernel/src/chheap.c
new file mode 100644
index 000000000..82b1ba785
--- /dev/null
+++ b/os/kernel/src/chheap.c
@@ -0,0 +1,276 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT 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 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT 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, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file chheap.c
+ * @brief Heap code.
+ * @addtogroup Heap
+ * @{
+ */
+
+#include <ch.h>
+
+#if CH_USE_HEAP
+
+#if !CH_USE_MALLOC_HEAP
+
+#define MAGIC 0xF5A0
+#define ALIGN_TYPE void *
+#define ALIGN_MASK (sizeof(ALIGN_TYPE) - 1)
+#define ALIGN_SIZE(p) (((size_t)(p) + ALIGN_MASK) & ~ALIGN_MASK)
+
+struct header {
+ union {
+ struct header *h_next;
+ size_t h_magic;
+ };
+ size_t h_size;
+};
+
+static struct {
+ struct header free; /* Guaranteed to be not adjacent to the heap */
+#if CH_USE_MUTEXES
+#define H_LOCK() chMtxLock(&heap.hmtx)
+#define H_UNLOCK() chMtxUnlock()
+ Mutex hmtx;
+#elif CH_USE_SEMAPHORES
+#define H_LOCK() chSemWait(&heap.hsem)
+#define H_UNLOCK() chSemSignal(&heap.hsem)
+ Semaphore hsem;
+#else
+#error "The heap allocator requires mutexes or semaphores to be enabled"
+#endif
+#if CH_HEAP_SIZE > 0
+ union {
+ ALIGN_TYPE alignment;
+ char buffer[ALIGN_SIZE(CH_HEAP_SIZE)];
+ };
+#endif
+} heap;
+
+/**
+ * @brief Initializes the allocator subsystem.
+ *
+ * @note Internal use only.
+ */
+void heap_init(void) {
+ struct header *hp;
+
+#if CH_HEAP_SIZE == 0
+ extern char __heap_base__;
+ extern char __heap_end__;
+
+ hp = (void *)&__heap_base__;
+ hp->h_size = &__heap_end__ - &__heap_base__ - sizeof(struct header);
+#else
+ hp = (void *)&heap.buffer[0];
+ hp->h_size = (&heap.buffer[ALIGN_SIZE(CH_HEAP_SIZE)] - &heap.buffer[0]) -
+ sizeof(struct header);
+#endif
+ hp->h_next = NULL;
+ heap.free.h_next = hp;
+ heap.free.h_size = 0;
+#if CH_USE_MUTEXES
+ chMtxInit(&heap.hmtx);
+#else
+ chSemInit(&heap.hsem, 1);
+#endif
+}
+
+/**
+ * @brief Allocates a block of memory from the heap by using the first-fit
+ * algorithm.
+ * @details The allocated block is guaranteed to be properly aligned for a
+ * pointer data type.
+ *
+ * @param[in] size the size of the block to be allocated. Note that the
+ * allocated block may be a bit bigger than the requested
+ * size for alignment and fragmentation reasons.
+ * @return A pointer to the allocated block.
+ * @retval NULL if the block cannot be allocated.
+ */
+void *chHeapAlloc(size_t size) {
+ struct header *qp, *hp, *fp;
+
+ size = ALIGN_SIZE(size);
+ qp = &heap.free;
+ H_LOCK();
+
+ while (qp->h_next != NULL) {
+ hp = qp->h_next;
+ if (hp->h_size >= size) {
+ if (hp->h_size < size + sizeof(struct header)) {
+ /* Gets the whole block even if it is slightly bigger than the
+ requested size because the fragment would be too small to be
+ useful */
+ qp->h_next = hp->h_next;
+ }
+ else {
+ /* Block bigger enough, must split it */
+ fp = (void *)((char *)(hp) + sizeof(struct header) + size);
+ fp->h_next = hp->h_next;
+ fp->h_size = hp->h_size - sizeof(struct header) - size;
+ qp->h_next = fp;
+ hp->h_size = size;
+ }
+ hp->h_magic = MAGIC;
+
+ H_UNLOCK();
+ return (void *)(hp + 1);
+ }
+ qp = hp;
+ }
+
+ H_UNLOCK();
+ return NULL;
+}
+
+#define LIMIT(p) (struct header *)((char *)(p) + \
+ sizeof(struct header) + \
+ (p)->h_size)
+
+/**
+ * @brief Frees a previously allocated memory block.
+ *
+ * @param[in] p the memory block pointer
+ */
+void chHeapFree(void *p) {
+ struct header *qp, *hp;
+
+ chDbgCheck(p != NULL, "chHeapFree");
+
+ hp = (struct header *)p - 1;
+ chDbgAssert(hp->h_magic == MAGIC,
+ "chHeapFree(), #1",
+ "it is not magic");
+ qp = &heap.free;
+ H_LOCK();
+
+ while (TRUE) {
+
+ chDbgAssert((hp < qp) || (hp >= LIMIT(qp)),
+ "chHeapFree(), #2",
+ "within free block");
+
+ if (((qp == &heap.free) || (hp > qp)) &&
+ ((qp->h_next == NULL) || (hp < qp->h_next))) {
+ /* Insertion after qp */
+ hp->h_next = qp->h_next;
+ qp->h_next = hp;
+ /* Verifies if the newly inserted block should be merged */
+ if (LIMIT(hp) == hp->h_next) {
+ /* Merge with the next block */
+ hp->h_size += hp->h_next->h_size + sizeof(struct header);
+ hp->h_next = hp->h_next->h_next;
+ }
+ if ((LIMIT(qp) == hp)) { /* Cannot happen when qp == &heap.free */
+ /* Merge with the previous block */
+ qp->h_size += hp->h_size + sizeof(struct header);
+ qp->h_next = hp->h_next;
+ }
+
+ H_UNLOCK();
+ return;
+ }
+ qp = qp->h_next;
+ }
+}
+
+/**
+ * @brief Reports the heap status.
+ *
+ * @param[in] sizep pointer to a variable that will receive the total
+ * fragmented free space
+ * @return The number of fragments in the heap.
+ * @note This function is meant to be used in the test suite, it should not be
+ * really useful for the application code.
+ * @note This function is not implemented when the @p CH_USE_MALLOC_HEAP
+ * configuration option is used (it always returns zero).
+ */
+size_t chHeapStatus(size_t *sizep) {
+ struct header *qp;
+ size_t n, sz;
+
+ H_LOCK();
+
+ sz = 0;
+ for (n = 0, qp = &heap.free; qp->h_next; n++, qp = qp->h_next)
+ sz += qp->h_next->h_size;
+ if (sizep)
+ *sizep = sz;
+
+ H_UNLOCK();
+ return n;
+}
+
+#else /* CH_USE_MALLOC_HEAP */
+
+#include <stdlib.h>
+
+#if CH_USE_MUTEXES
+#define H_LOCK() chMtxLock(&hmtx)
+#define H_UNLOCK() chMtxLock(&hmtx)
+static Mutex hmtx;
+#elif CH_USE_SEMAPHORES
+#define H_LOCK() chSemWait(&hsem)
+#define H_UNLOCK() chSemSignal(&hsem)
+static Semaphore hsem;
+#else
+#error "The heap allocator requires mutexes or semaphores to be enabled"
+#endif
+
+void heap_init(void) {
+
+#if CH_USE_MUTEXES
+ chMtxInit(&hmtx);
+#else
+ chSemInit(&hsem, 1);
+#endif
+}
+
+void *chHeapAlloc(size_t size) {
+ void *p;
+
+ H_LOCK();
+ p = malloc(size);
+ H_UNLOCK();
+ return p;
+}
+
+void chHeapFree(void *p) {
+
+ chDbgCheck(p != NULL, "chHeapFree");
+
+ H_LOCK();
+ free(p);
+ H_UNLOCK();
+}
+
+size_t chHeapStatus(size_t *sizep) {
+
+ if (sizep)
+ *sizep = 0;
+ return 0;
+}
+
+#endif /* CH_USE_MALLOC_HEAP */
+
+#endif /* CH_USE_HEAP */
+
+/** @} */
diff --git a/os/kernel/src/chlists.c b/os/kernel/src/chlists.c
new file mode 100644
index 000000000..a2177ca63
--- /dev/null
+++ b/os/kernel/src/chlists.c
@@ -0,0 +1,111 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT 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 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT 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, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file chlists.c
+ * @brief Thread queues/lists code.
+ * @addtogroup ThreadLists
+ * @{
+ */
+#include <ch.h>
+
+#if !CH_OPTIMIZE_SPEED || defined(__DOXYGEN__)
+/**
+ * @brief Inserts a thread into a priority ordered queue.
+ *
+ * @param[in] tp the pointer to the thread to be inserted in the list
+ * @param[in] tqp the pointer to the threads list header
+ * @note The insertion is done by scanning the list from the highest priority
+ * toward the lowest.
+ * @note This function is @b not an API.
+ */
+void prio_insert(Thread *tp, ThreadsQueue *tqp) {
+
+ /* cp iterates over the queue */
+ Thread *cp = (Thread *)tqp;
+ do {
+ /* iterate to next thread in queue */
+ cp = cp->p_next;
+ /* not end of queue? and cp has equal or higher priority than tp? */
+ } while ((cp != (Thread *)tqp) && (cp->p_prio >= tp->p_prio));
+ /* insert before cp, point tp to next and prev in queue */
+ tp->p_prev = (tp->p_next = cp)->p_prev;
+ /* make prev point to tp, and cp point back to tp */
+ tp->p_prev->p_next = cp->p_prev = tp;
+}
+
+/**
+ * @brief Inserts a Thread into a queue.
+ *
+ * @param[in] tp the pointer to the thread to be inserted in the list
+ * @param[in] tqp the pointer to the threads list header
+ * @note This function is @b not an API.
+ */
+void queue_insert(Thread *tp, ThreadsQueue *tqp) {
+
+ tp->p_prev = (tp->p_next = (Thread *)tqp)->p_prev;
+ tp->p_prev->p_next = tqp->p_prev = tp;
+}
+
+/**
+ * @brief Removes the first-out Thread from a queue and returns it.
+ *
+ * @param[in] tqp the pointer to the threads list header
+ * @return The removed thread pointer.
+ * @note This function is @b not an API.
+ */
+Thread *fifo_remove(ThreadsQueue *tqp) {
+ Thread *tp = tqp->p_next;
+
+ (tqp->p_next = tp->p_next)->p_prev = (Thread *)tqp;
+ return tp;
+}
+
+/**
+ * @brief Removes the last-out Thread from a queue and returns it.
+ *
+ * @param[in] tqp the pointer to the threads list header
+ * @return The removed thread pointer.
+ * @note This function is @b not an API.
+ */
+Thread *lifo_remove(ThreadsQueue *tqp) {
+ Thread *tp = tqp->p_next;
+
+ (tqp->p_next = tp->p_next)->p_prev = (Thread *)tqp;
+ return tp;
+}
+
+/**
+ * @brief Removes a Thread from a queue and returns it.
+ * @details The thread is removed from the queue regardless of its relative
+ * position and regardless the used insertion method.
+ *
+ * @param[in] tp the pointer to the thread to be removed from the queue
+ * @return The removed thread pointer.
+ * @note This function is @b not an API.
+ */
+Thread *dequeue(Thread *tp) {
+
+ tp->p_prev->p_next = tp->p_next;
+ tp->p_next->p_prev = tp->p_prev;
+ return tp;
+}
+#endif /* CH_OPTIMIZE_SPEED */
+
+/** @} */
diff --git a/os/kernel/src/chmboxes.c b/os/kernel/src/chmboxes.c
new file mode 100644
index 000000000..8a791a984
--- /dev/null
+++ b/os/kernel/src/chmboxes.c
@@ -0,0 +1,244 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT 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 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT 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, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file chmboxes.c
+ * @brief Mailboxes code.
+ * @addtogroup Mailboxes
+ * @{
+ */
+
+#include <ch.h>
+
+#if CH_USE_MAILBOXES
+/**
+ * @brief Initializes a Mailbox object.
+ *
+ * @param[out] mbp the pointer to the Mailbox structure to be initialized
+ * @param[in] buf the circular messages buffer
+ * @param[in] n the buffer size as number of @p msg_t
+ */
+void chMBInit(Mailbox *mbp, msg_t *buf, cnt_t n) {
+
+ chDbgCheck((mbp != NULL) && (buf != NULL) && (n > 0), "chMBInit");
+
+ mbp->mb_buffer = mbp->mb_wrptr = mbp->mb_rdptr = buf;
+ mbp->mb_top = &buf[n];
+ chSemInit(&mbp->mb_emptysem, n);
+ chSemInit(&mbp->mb_fullsem, 0);
+}
+
+/**
+ * @brief Resets a Mailbox object.
+ * @details All the waiting threads are resumed with status @p RDY_RESET and
+ * the queued messages are lost.
+ *
+ * @param[in] mbp the pointer to an initialized Mailbox object
+ */
+void chMBReset(Mailbox *mbp) {
+
+ chDbgCheck(mbp != NULL, "chMBReset");
+
+ chSysLock();
+ mbp->mb_wrptr = mbp->mb_rdptr = mbp->mb_buffer;
+ chSemResetI(&mbp->mb_emptysem, mbp->mb_top - mbp->mb_buffer);
+ chSemResetI(&mbp->mb_fullsem, 0);
+ chSchRescheduleS();
+ chSysUnlock();
+}
+
+/**
+ * @brief Posts a message into a mailbox.
+ * @details The invoking thread waits until a empty slot in the mailbox becomes
+ * available or the specified time runs out.
+ *
+ * @param[in] mbp the pointer to an initialized Mailbox object
+ * @param[in] msg the message to be posted on the mailbox
+ * @param[in] time the number of ticks before the operation timeouts,
+ * the following special values are allowed:
+ * - @a TIME_IMMEDIATE immediate timeout.
+ * - @a TIME_INFINITE no timeout.
+ * .
+ * @return The operation status.
+ * @retval RDY_OK if the message was correctly posted.
+ * @retval RDY_RESET if the mailbox was reset while waiting.
+ * @retval RDY_TIMEOUT if the operation timed out.
+ */
+msg_t chMBPost(Mailbox *mbp, msg_t msg, systime_t time) {
+ msg_t rdymsg;
+
+ chSysLock();
+ rdymsg = chMBPostS(mbp, msg, time);
+ chSysUnlock();
+ return rdymsg;
+}
+
+/**
+ * @brief Posts a message into a mailbox.
+ * @details The invoking thread waits until a empty slot in the mailbox becomes
+ * available or the specified time runs out.
+ *
+ * @param[in] mbp the pointer to an initialized Mailbox object
+ * @param[in] msg the message to be posted on the mailbox
+ * @param[in] time the number of ticks before the operation timeouts,
+ * the following special values are allowed:
+ * - @a TIME_IMMEDIATE immediate timeout.
+ * - @a TIME_INFINITE no timeout.
+ * .
+ * @return The operation status.
+ * @retval RDY_OK if the message was correctly posted.
+ * @retval RDY_RESET if the mailbox was reset while waiting.
+ * @retval RDY_TIMEOUT if the operation timed out.
+ */
+msg_t chMBPostS(Mailbox *mbp, msg_t msg, systime_t time) {
+ msg_t rdymsg;
+
+ chDbgCheck(mbp != NULL, "chMBPostS");
+
+ rdymsg = chSemWaitTimeoutS(&mbp->mb_emptysem, time);
+ if (rdymsg == RDY_OK) {
+ *mbp->mb_wrptr++ = msg;
+ if (mbp->mb_wrptr >= mbp->mb_top)
+ mbp->mb_wrptr = mbp->mb_buffer;
+ chSemSignalI(&mbp->mb_fullsem);
+ chSchRescheduleS();
+ }
+ return rdymsg;
+}
+
+/**
+ * @brief Posts an high priority message into a mailbox.
+ * @details The invoking thread waits until a empty slot in the mailbox becomes
+ * available or the specified time runs out.
+ *
+ * @param[in] mbp the pointer to an initialized Mailbox object
+ * @param[in] msg the message to be posted on the mailbox
+ * @param[in] time the number of ticks before the operation timeouts,
+ * the following special values are allowed:
+ * - @a TIME_IMMEDIATE immediate timeout.
+ * - @a TIME_INFINITE no timeout.
+ * .
+ * @return The operation status.
+ * @retval RDY_OK if the message was correctly posted.
+ * @retval RDY_RESET if the mailbox was reset while waiting.
+ * @retval RDY_TIMEOUT if the operation timed out.
+ */
+msg_t chMBPostAhead(Mailbox *mbp, msg_t msg, systime_t time) {
+ msg_t rdymsg;
+
+ chSysLock();
+ rdymsg = chMBPostAheadS(mbp, msg, time);
+ chSysUnlock();
+ return rdymsg;
+}
+
+/**
+ * @brief Posts an high priority message into a mailbox.
+ * @details The invoking thread waits until a empty slot in the mailbox becomes
+ * available or the specified time runs out.
+ *
+ * @param[in] mbp the pointer to an initialized Mailbox object
+ * @param[in] msg the message to be posted on the mailbox
+ * @param[in] time the number of ticks before the operation timeouts,
+ * the following special values are allowed:
+ * - @a TIME_IMMEDIATE immediate timeout.
+ * - @a TIME_INFINITE no timeout.
+ * .
+ * @return The operation status.
+ * @retval RDY_OK if the message was correctly posted.
+ * @retval RDY_RESET if the mailbox was reset while waiting.
+ * @retval RDY_TIMEOUT if the operation timed out.
+ */
+msg_t chMBPostAheadS(Mailbox *mbp, msg_t msg, systime_t time) {
+ msg_t rdymsg;
+
+ chDbgCheck(mbp != NULL, "chMBPostAheadS");
+
+ rdymsg = chSemWaitTimeoutS(&mbp->mb_emptysem, time);
+ if (rdymsg == RDY_OK) {
+ if (--mbp->mb_rdptr < mbp->mb_buffer)
+ mbp->mb_rdptr = mbp->mb_top - 1;
+ *mbp->mb_rdptr = msg;
+ chSemSignalI(&mbp->mb_fullsem);
+ chSchRescheduleS();
+ }
+ return rdymsg;
+}
+
+/**
+ * @brief Retrieves a message from a mailbox.
+ * @details The invoking thread waits until a message is posted in the mailbox
+ * or the specified time runs out.
+ *
+ * @param[in] mbp the pointer to an initialized Mailbox object
+ * @param[out] msgp pointer to a message variable for the received message
+ * @param[in] time the number of ticks before the operation timeouts,
+ * the following special values are allowed:
+ * - @a TIME_IMMEDIATE immediate timeout.
+ * - @a TIME_INFINITE no timeout.
+ * .
+ * @return The operation status.
+ * @retval RDY_OK if a message was correctly fetched.
+ * @retval RDY_RESET if the mailbox was reset while waiting.
+ * @retval RDY_TIMEOUT if the operation timed out.
+ */
+msg_t chMBFetch(Mailbox *mbp, msg_t *msgp, systime_t time) {
+ msg_t rdymsg;
+
+ chSysLock();
+ rdymsg = chMBFetchS(mbp, msgp, time);
+ chSysUnlock();
+ return rdymsg;
+}
+
+/**
+ * @brief Retrieves a message from a mailbox.
+ * @details The invoking thread waits until a message is posted in the mailbox
+ * or the specified time runs out.
+ *
+ * @param[in] mbp the pointer to an initialized Mailbox object
+ * @param[out] msgp pointer to a message variable for the received message
+ * @param[in] time the number of ticks before the operation timeouts,
+ * the following special values are allowed:
+ * - @a TIME_IMMEDIATE immediate timeout.
+ * - @a TIME_INFINITE no timeout.
+ * .
+ * @return The operation status.
+ * @retval RDY_OK if a message was correctly fetched.
+ * @retval RDY_RESET if the mailbox was reset while waiting.
+ * @retval RDY_TIMEOUT if the operation timed out.
+ */
+msg_t chMBFetchS(Mailbox *mbp, msg_t *msgp, systime_t time) {
+ msg_t rdymsg;
+
+ chDbgCheck((mbp != NULL) && (msgp != NULL), "chMBFetchS");
+
+ rdymsg = chSemWaitTimeoutS(&mbp->mb_fullsem, time);
+ if (rdymsg == RDY_OK) {
+ *msgp = *mbp->mb_rdptr++;
+ if (mbp->mb_rdptr >= mbp->mb_top)
+ mbp->mb_rdptr = mbp->mb_buffer;
+ chSemSignalI(&mbp->mb_emptysem);
+ chSchRescheduleS();
+ }
+ return rdymsg;
+}
+#endif /* CH_USE_MAILBOXES */
+
+/** @} */
diff --git a/os/kernel/src/chmempools.c b/os/kernel/src/chmempools.c
new file mode 100644
index 000000000..dd6f3d1ba
--- /dev/null
+++ b/os/kernel/src/chmempools.c
@@ -0,0 +1,112 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT 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 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT 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, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file chmempools.c
+ * @brief Memory Pools code.
+ * @addtogroup MemoryPools
+ * @{
+ */
+
+#include <ch.h>
+
+#if CH_USE_MEMPOOLS
+/**
+ * @brief Initializes an empty memory pool.
+ *
+ * @param[out] mp pointer to a @p MemoryPool structure
+ * @param[in] size the size of the objects contained in this memory pool,
+ * the minimum accepted size is the size of a pointer to void
+ */
+void chPoolInit(MemoryPool *mp, size_t size) {
+
+ chDbgCheck((mp != NULL) && (size >= sizeof(void *)), "chPoolInit");
+
+ mp->mp_next = NULL;
+ mp->mp_object_size = size;
+}
+
+/**
+ * @brief Allocates an object from a memory pool.
+ *
+ * @param[in] mp pointer to a @p MemoryPool structure
+ * @return The pointer to the allocated object.
+ * @retval NULL if pool is empty.
+ */
+void *chPoolAllocI(MemoryPool *mp) {
+ void *objp;
+
+ chDbgCheck(mp != NULL, "chPoolAllocI");
+
+ if ((objp = mp->mp_next) != NULL)
+ mp->mp_next = mp->mp_next->ph_next;
+
+ return objp;
+}
+
+/**
+ * @brief Allocates an object from a memory pool.
+ *
+ * @param[in] mp pointer to a @p MemoryPool structure
+ * @return The pointer to the allocated object.
+ * @retval NULL if pool is empty.
+ */
+void *chPoolAlloc(MemoryPool *mp) {
+ void *objp;
+
+ chSysLock();
+ objp = chPoolAllocI(mp);
+ chSysUnlock();
+ return objp;
+}
+
+/**
+ * @brief Releases (or adds) an object into (to) a memory pool.
+ *
+ * @param[in] mp pointer to a @p MemoryPool structure
+ * @param[in] objp the pointer to the object to be released or added
+ * @note the object is assumed to be of the right size for the specified
+ * memory pool.
+ */
+void chPoolFreeI(MemoryPool *mp, void *objp) {
+ struct pool_header *php = objp;
+
+ chDbgCheck((mp != NULL) && (objp != NULL), "chPoolFreeI");
+
+ php->ph_next = mp->mp_next;
+ mp->mp_next = php;
+}
+
+/**
+ * @brief Releases (or adds) an object into (to) a memory pool.
+ *
+ * @param[in] mp pointer to a @p MemoryPool structure
+ * @param[in] objp the pointer to the object to be released or added
+ * @note the object is assumed to be of the right size for the specified
+ * memory pool.
+ */
+void chPoolFree(MemoryPool *mp, void *objp) {
+
+ chSysLock();
+ chPoolFreeI(mp, objp);
+ chSysUnlock();
+}
+#endif /* CH_USE_MEMPOOLS */
+
+/** @} */
diff --git a/os/kernel/src/chmsg.c b/os/kernel/src/chmsg.c
new file mode 100644
index 000000000..393ab8dad
--- /dev/null
+++ b/os/kernel/src/chmsg.c
@@ -0,0 +1,125 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT 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 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT 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, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file chmsg.c
+ * @brief Messages code.
+ * @addtogroup Messages
+ * @{
+ */
+
+#include <ch.h>
+
+#if CH_USE_MESSAGES
+
+#if CH_USE_MESSAGES_PRIORITY
+#define msg_insert(tp, qp) prio_insert(tp, qp)
+#else
+#define msg_insert(tp, qp) queue_insert(tp, qp)
+#endif
+
+/**
+ * @brief Sends a message to the specified thread.
+ * @details The sender is stopped until the receiver executes a
+ * @p chMsgRelease()after receiving the message.
+ *
+ * @param[in] tp the pointer to the thread
+ * @param[in] msg the message
+ * @return The return message from @p chMsgRelease().
+ */
+msg_t chMsgSend(Thread *tp, msg_t msg) {
+
+ chDbgCheck(tp != NULL, "chMsgSend");
+
+ chSysLock();
+ msg_insert(currp, &tp->p_msgqueue);
+ currp->p_msg = msg;
+ currp->p_wtthdp = tp;
+ if (tp->p_state == PRWTMSG)
+ chSchReadyI(tp);
+ chSchGoSleepS(PRSNDMSG);
+ msg = currp->p_rdymsg;
+ chSysUnlock();
+ return msg;
+}
+
+/**
+ * @brief Suspends the thread and waits for an incoming message.
+ *
+ * @return The pointer to the message structure. Note, it is always the
+ * message associated to the thread on the top of the messages queue.
+ * @note You can assume that the data contained in the message is stable until
+ * you invoke @p chMsgRelease() because the sending thread is
+ * suspended until then.
+ */
+msg_t chMsgWait(void) {
+ msg_t msg;
+
+ chSysLock();
+ if (!chMsgIsPendingI(currp))
+ chSchGoSleepS(PRWTMSG);
+ msg = chMsgGetI(currp);
+ chSysUnlock();
+ return msg;
+}
+
+/**
+ * @brief Returns the next message in the queue.
+ *
+ * @return The pointer to the message structure. Note, it is always the
+ * message associated to the thread on the top of the messages queue.
+ * If the queue is empty then @p NULL is returned.
+ * @note You can assume that the data pointed by the message is stable until
+ * you invoke @p chMsgRelease() because the sending thread is
+ * suspended until then. Always remember that the message data is not
+ * copied between the sender and the receiver, just a pointer is passed.
+ */
+msg_t chMsgGet(void) {
+ msg_t msg;
+
+ chSysLock();
+ msg = chMsgIsPendingI(currp) ? chMsgGetI(currp) : (msg_t)NULL;
+ chSysUnlock();
+ return msg;
+}
+
+/**
+ * @brief Releases the thread waiting on top of the messages queue.
+ *
+ * @param[in] msg the message returned to the message sender
+ * @note You can call this function only if there is a message already in the
+ * queue else the result will be unpredictable (a crash most likely).
+ * Exiting from the @p chMsgWait() ensures you have at least one
+ * message in the queue so it is not a big deal.<br>
+ * The condition is only tested in debug mode in order to make this code
+ * as fast as possible.
+ */
+void chMsgRelease(msg_t msg) {
+
+ chSysLock();
+ chDbgAssert(chMsgIsPendingI(currp),
+ "chMsgRelease(), #1",
+ "no message pending");
+ chSchWakeupS(fifo_remove(&currp->p_msgqueue), msg);
+ chSysUnlock();
+}
+
+#endif /* CH_USE_MESSAGES */
+
+/** @} */
diff --git a/os/kernel/src/chmtx.c b/os/kernel/src/chmtx.c
new file mode 100644
index 000000000..5fcb6fd5e
--- /dev/null
+++ b/os/kernel/src/chmtx.c
@@ -0,0 +1,299 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT 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 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT 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, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file chmtx.c
+ * @brief Mutexes code.
+ * @addtogroup Mutexes
+ * @{
+ */
+
+#include <ch.h>
+
+#if CH_USE_MUTEXES
+
+/**
+ * @brief Initializes s @p Mutex structure.
+ *
+ * @param[out] mp pointer to a @p Mutex structure
+ * @note This function can be invoked from within an interrupt handler even if
+ * it is not an I-Class API because it does not touch any critical kernel
+ * data structure.
+ */
+void chMtxInit(Mutex *mp) {
+
+ chDbgCheck(mp != NULL, "chMtxInit");
+
+ queue_init(&mp->m_queue);
+ mp->m_owner = NULL;
+}
+
+/**
+ * @brief Locks the specified mutex.
+ *
+ * @param[in] mp pointer to the @p Mutex structure
+ */
+void chMtxLock(Mutex *mp) {
+
+ chSysLock();
+
+ chMtxLockS(mp);
+
+ chSysUnlock();
+}
+
+/**
+ * @brief Locks the specified mutex.
+ *
+ * @param[in] mp pointer to the @p Mutex structure
+ * @note This function must be called within a @p chSysLock() / @p chSysUnlock()
+ * block.
+ */
+void chMtxLockS(Mutex *mp) {
+
+ chDbgCheck(mp != NULL, "chMtxLockS");
+
+ /* the mutex is already locked? */
+ if (mp->m_owner != NULL) {
+ /*
+ * Priority inheritance protocol; explores the thread-mutex dependencies
+ * boosting the priority of all the affected threads to equal the priority
+ * of the running thread requesting the mutex.
+ */
+ Thread *tp = mp->m_owner;
+ /* { tp is the thread currently owning the mutex } */
+ /* the running thread has higher priority than tp? */
+ while (tp->p_prio < currp->p_prio) {
+ /* make priority of thread tp match the running thread's priority */
+ tp->p_prio = currp->p_prio;
+ /*
+ * The following states need priority queues reordering.
+ */
+ switch (tp->p_state) {
+ /* thread tp is waiting on a mutex? */
+ case PRWTMTX:
+ /* Requeues tp with its new priority on the mutex wait queue. */
+ prio_insert(dequeue(tp), &tp->p_wtmtxp->m_queue);
+ /* boost the owner of this mutex if needed */
+ tp = tp->p_wtmtxp->m_owner;
+ continue;
+#if CH_USE_CONDVARS
+ case PRWTCOND:
+ /* Requeues tp with its new priority on the condvar queue. */
+ prio_insert(dequeue(tp), &tp->p_wtcondp->c_queue);
+ break;
+#endif
+#if CH_USE_SEMAPHORES_PRIORITY
+ case PRWTSEM:
+ /* Requeues tp with its new priority on the semaphore queue. */
+ prio_insert(dequeue(tp), &tp->p_wtsemp->s_queue);
+ break;
+#endif
+#if CH_USE_MESSAGES_PRIORITY
+ case PRSNDMSG:
+ /* Requeues tp with its new priority on the server thread queue. */
+ prio_insert(dequeue(tp), &tp->p_wtthdp->p_msgqueue);
+ break;
+#endif
+ /* thread tp is ready? */
+ case PRREADY:
+ /* Requeue tp with its new priority on the ready list. */
+ chSchReadyI(dequeue(tp));
+ }
+ break;
+ }
+ /* sleep on the mutex */
+ prio_insert(currp, &mp->m_queue);
+ /* thread remembers the mutex where it is waiting on */
+ currp->p_wtmtxp = mp;
+ chSchGoSleepS(PRWTMTX);
+ chDbgAssert(mp->m_owner == NULL, "chMtxLockS(), #1", "still owned");
+ }
+ /*
+ * The mutex is now inserted in the owned mutexes list.
+ */
+ mp->m_owner = currp;
+ mp->m_next = currp->p_mtxlist;
+ currp->p_mtxlist = mp;
+}
+
+/**
+ * @brief Tries to lock a mutex.
+ * @details This function does not have any overhead related to
+ * the priority inheritance mechanism because it does not try to
+ * enter a sleep state on the mutex.
+ *
+ * @param[in] mp pointer to the @p Mutex structure
+ * @retval TRUE if the mutex was successfully acquired
+ * @retval FALSE if the lock attempt failed.
+ */
+bool_t chMtxTryLock(Mutex *mp) {
+ bool_t b;
+
+ chSysLock();
+
+ b = chMtxTryLockS(mp);
+
+ chSysUnlock();
+ return b;
+}
+
+/**
+ * @brief Tries to lock a mutex.
+ * @details This function does not have any overhead related to
+ * the priority inheritance mechanism because it does not try to
+ * enter a sleep state on the mutex.
+ * @param[in] mp pointer to the @p Mutex structure
+ * @retval TRUE if the mutex was successfully acquired
+ * @retval FALSE if the lock attempt failed.
+ * @note This function must be called within a @p chSysLock() / @p chSysUnlock()
+ * block.
+ */
+bool_t chMtxTryLockS(Mutex *mp) {
+
+ chDbgCheck(mp != NULL, "chMtxTryLockS");
+
+ if (mp->m_owner != NULL)
+ return FALSE;
+ mp->m_owner = currp;
+ mp->m_next = currp->p_mtxlist;
+ currp->p_mtxlist = mp;
+ return TRUE;
+}
+
+/**
+ * @brief Unlocks the next owned mutex in reverse lock order.
+ *
+ * @return The pointer to the unlocked mutex.
+ */
+Mutex *chMtxUnlock(void) {
+ Mutex *ump, *mp;
+
+ chSysLock();
+ chDbgAssert(currp->p_mtxlist != NULL,
+ "chMtxUnlock(), #1",
+ "owned mutexes list empty");
+ chDbgAssert(currp->p_mtxlist->m_owner == currp,
+ "chMtxUnlock(), #2",
+ "ownership failure");
+ /* remove the top Mutex from the Threads's owned mutexes list */
+ ump = currp->p_mtxlist;
+ currp->p_mtxlist = ump->m_next;
+ /* mark the Mutex as not owned */
+ ump->m_owner = NULL;
+ /*
+ * If a thread is waiting on the mutex then the hard part begins.
+ */
+ if (chMtxQueueNotEmptyS(ump)) {
+ /* get the highest priority thread waiting for the unlocked mutex */
+ Thread *tp = fifo_remove(&ump->m_queue);
+ /*
+ * Recalculates the optimal thread priority by scanning the owned mutexes list.
+ */
+ tprio_t newprio = currp->p_realprio;
+ /* iterate mp over all the (other) mutexes the current thread still owns */
+ mp = currp->p_mtxlist;
+ while (mp != NULL) {
+ /* mutex mp has a higher priority thread pending? */
+ if (chMtxQueueNotEmptyS(mp) && (mp->m_queue.p_next->p_prio > newprio))
+ /* boost current thread's priority to waiting thread */
+ newprio = mp->m_queue.p_next->p_prio;
+ mp = mp->m_next;
+ }
+ /* (possibly) boost the priority of the current thread */
+ currp->p_prio = newprio;
+ /* awaken the highest priority thread waiting for the unlocked mutex */
+ chSchWakeupS(tp, RDY_OK);
+ }
+ chSysUnlock();
+ return ump;
+}
+
+/**
+ * @brief Unlocks the next owned mutex in reverse lock order.
+ *
+ * @return The pointer to the unlocked mutex.
+ * @note This function must be called within a @p chSysLock() / @p chSysUnlock()
+ * block.
+ * @note This function does not reschedule internally.
+ */
+Mutex *chMtxUnlockS(void) {
+ Mutex *ump, *mp;
+
+ chDbgAssert(currp->p_mtxlist != NULL,
+ "chMtxUnlockS(), #1",
+ "owned mutexes list empty");
+ chDbgAssert(currp->p_mtxlist->m_owner == currp,
+ "chMtxUnlockS(), #2",
+ "ownership failure");
+
+ /*
+ * Removes the top Mutex from the owned mutexes list and marks it as not owned.
+ */
+ ump = currp->p_mtxlist;
+ currp->p_mtxlist = ump->m_next;
+ ump->m_owner = NULL;
+ /*
+ * If a thread is waiting on the mutex then the hard part begins.
+ */
+ if (chMtxQueueNotEmptyS(ump)) {
+ Thread *tp = fifo_remove(&ump->m_queue);
+ /*
+ * Recalculates the optimal thread priority by scanning the owned mutexes list.
+ */
+ tprio_t newprio = currp->p_realprio;
+ mp = currp->p_mtxlist;
+ while (mp != NULL) {
+ if (chMtxQueueNotEmptyS(mp) && (mp->m_queue.p_next->p_prio > newprio))
+ newprio = mp->m_queue.p_next->p_prio;
+ mp = mp->m_next;
+ }
+ currp->p_prio = newprio;
+ chSchReadyI(tp);
+ }
+ return ump;
+}
+
+/**
+ * @brief Unlocks all the mutexes owned by the invoking thread.
+ * @details This function is <b>MUCH MORE</b> efficient than releasing the
+ * mutexes one by one and not just because the call overhead,
+ * this function does not have any overhead related to the priority
+ * inheritance mechanism.
+ */
+void chMtxUnlockAll(void) {
+
+ chSysLock();
+ if (currp->p_mtxlist != NULL) {
+ do {
+ Mutex *mp = currp->p_mtxlist;
+ currp->p_mtxlist = mp->m_next;
+ mp->m_owner = NULL;
+ if (chMtxQueueNotEmptyS(mp))
+ chSchReadyI(fifo_remove(&mp->m_queue));
+ } while (currp->p_mtxlist != NULL);
+ currp->p_prio = currp->p_realprio;
+ chSchRescheduleS();
+ }
+ chSysUnlock();
+}
+
+#endif /* CH_USE_MUTEXES */
+
+/** @} */
diff --git a/os/kernel/src/chqueues.c b/os/kernel/src/chqueues.c
new file mode 100644
index 000000000..a72b83696
--- /dev/null
+++ b/os/kernel/src/chqueues.c
@@ -0,0 +1,304 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT 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 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT 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, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file chqueues.c
+ * @brief I/O Queues code.
+ * @addtogroup IOQueues
+ * @{
+ */
+
+#include <ch.h>
+
+#if CH_USE_QUEUES
+
+/**
+ * @brief Initializes an input queue.
+ * @details A Semaphore is internally initialized and works as a counter of
+ * the bytes contained in the queue.
+ *
+ * @param[out] iqp pointer to an @p InputQueue structure
+ * @param[in] buffer pointer to a memory area allocated as queue buffer
+ * @param[in] size size of the queue buffer
+ * @param[in] inotify pointer to a callback function that is invoked when
+ * some data is read from the queue. The value can be
+ * @p NULL.
+ *
+ * @note The callback is invoked from within the S-Locked system state,
+ * see @ref system_states.
+ */
+void chIQInit(InputQueue *iqp, uint8_t *buffer,
+ size_t size, qnotify_t inotify) {
+
+ iqp->q_buffer = iqp->q_rdptr = iqp->q_wrptr = buffer;
+ iqp->q_top = buffer + size;
+ chSemInit(&iqp->q_sem, 0);
+ iqp->q_notify = inotify;
+}
+
+/**
+ * @brief Resets an input queue.
+ * @details All the data in the input queue is erased and lost, any waiting
+ * thread is resumed with status @p Q_RESET.
+ *
+ * @param[in] iqp pointer to an @p InputQueue structure
+ *
+ * @note A reset operation can be used by a low level driver in order to obtain
+ * immediate attention from the high level layers.
+ */
+void chIQResetI(InputQueue *iqp) {
+
+ iqp->q_rdptr = iqp->q_wrptr = iqp->q_buffer;
+ chSemResetI(&iqp->q_sem, 0);
+}
+
+/**
+ * @brief Input queue write.
+ * @details A byte value is written into the low end of an input queue.
+ *
+ * @param[in] iqp pointer to an @p InputQueue structure
+ * @param[in] b the byte value to be written in the queue
+ * @return The operation status, it can be one of:
+ * @retval Q_OK if the operation has been completed with success.
+ * @retval Q_FULL if the queue is full and the operation cannot be completed.
+ */
+msg_t chIQPutI(InputQueue *iqp, uint8_t b) {
+
+ if (chIQIsFull(iqp))
+ return Q_FULL;
+
+ *iqp->q_wrptr++ = b;
+ if (iqp->q_wrptr >= iqp->q_top)
+ iqp->q_wrptr = iqp->q_buffer;
+ chSemSignalI(&iqp->q_sem);
+ return Q_OK;
+}
+
+/**
+ * @brief Input queue read with timeout.
+ * @details This function reads a byte value from an input queue. If the queue
+ * is empty then the calling thread is suspended until a byte arrives
+ * in the queue or a timeout occurs.
+ *
+ * @param[in] iqp pointer to an @p InputQueue structure
+ * @param[in] timeout the number of ticks before the operation timeouts,
+ * the following special values are allowed:
+ * - @a TIME_IMMEDIATE immediate timeout.
+ * - @a TIME_INFINITE no timeout.
+ * .
+ * @return A byte value from the queue or:
+ * @retval Q_TIMEOUT if the specified time expired.
+ * @retval Q_RESET if the queue was reset.
+ */
+msg_t chIQGetTimeout(InputQueue *iqp, systime_t timeout) {
+ uint8_t b;
+ msg_t msg;
+
+ chSysLock();
+ if ((msg = chSemWaitTimeoutS(&iqp->q_sem, timeout)) < RDY_OK) {
+ chSysUnlock();
+ return msg;
+ }
+ b = *iqp->q_rdptr++;
+ if (iqp->q_rdptr >= iqp->q_top)
+ iqp->q_rdptr = iqp->q_buffer;
+
+ if (iqp->q_notify)
+ iqp->q_notify();
+
+ chSysUnlock();
+ return b;
+}
+
+/**
+ * @brief Non-blocking read.
+ * @details The function reads data from an input queue into a buffer. The
+ * transfer is non-blocking and can return zero if the queue is
+ * empty.
+ *
+ * @param[in] iqp pointer to an @p InputQueue structure
+ * @param[out] buffer pointer to the buffer where the input data is copied
+ * @param[in] n the maximum amount of data to be transferred
+ * @return The number of bytes transferred.
+ *
+ * @note The function is not atomic, if you need atomicity it is suggested
+ * to use a semaphore or a mutex for mutual exclusion.
+ */
+size_t chIQRead(InputQueue *iqp, uint8_t *buffer, size_t n) {
+ size_t r = 0;
+
+ while (n--) {
+ chSysLock();
+ if (chIQIsEmpty(iqp)) {
+ chSysUnlock();
+ break;
+ }
+ chSemFastWaitI(&iqp->q_sem);
+ *buffer++ = *iqp->q_rdptr++;
+ if (iqp->q_rdptr >= iqp->q_top)
+ iqp->q_rdptr = iqp->q_buffer;
+ chSysUnlock();
+ r++;
+ }
+ if (r && iqp->q_notify) {
+ chSysLock();
+ iqp->q_notify();
+ chSysUnlock();
+ }
+ return r;
+}
+
+/**
+ * @brief Initializes an output queue.
+ * @details A Semaphore is internally initialized and works as a counter of
+ * the free bytes in the queue.
+ *
+ * @param[out] oqp pointer to an @p OutputQueue structure
+ * @param[in] buffer pointer to a memory area allocated as queue buffer
+ * @param[in] size size of the queue buffer
+ * @param[in] onotify pointer to a callback function that is invoked when
+ * some data is written to the queue. The value can be
+ * @p NULL.
+ *
+ * @note The callback is invoked from within the S-Locked system state,
+ * see @ref system_states.
+ */
+void chOQInit(OutputQueue *oqp, uint8_t *buffer,
+ size_t size, qnotify_t onotify) {
+
+ oqp->q_buffer = oqp->q_rdptr = oqp->q_wrptr = buffer;
+ oqp->q_top = buffer + size;
+ chSemInit(&oqp->q_sem, size);
+ oqp->q_notify = onotify;
+}
+
+/**
+ * @brief Resets an output queue.
+ * @details All the data in the output queue is erased and lost, any waiting
+ * thread is resumed with status @p Q_RESET.
+ *
+ * @param[in] oqp pointer to an @p OutputQueue structure
+ *
+ * @note A reset operation can be used by a low level driver in order to obtain
+ * immediate attention from the high level layers.
+ */
+void chOQResetI(OutputQueue *oqp) {
+
+ oqp->q_rdptr = oqp->q_wrptr = oqp->q_buffer;
+ chSemResetI(&oqp->q_sem, (cnt_t)(oqp->q_top - oqp->q_buffer));
+}
+
+/**
+ * @brief Output queue write with timeout.
+ * @details This function writes a byte value to an output queue. If the queue
+ * is full then the calling thread is suspended until there is space
+ * in the queue or a timeout occurs.
+ *
+ * @param[in] oqp pointer to an @p OutputQueue structure
+ * @param[in] b the byte value to be written in the queue
+ * @param[in] timeout the number of ticks before the operation timeouts,
+ * the following special values are allowed:
+ * - @a TIME_IMMEDIATE immediate timeout.
+ * - @a TIME_INFINITE no timeout.
+ * .
+ * @return The operation status:
+ * @retval Q_OK if the operation succeeded.
+ * @retval Q_TIMEOUT if the specified time expired.
+ * @retval Q_RESET if the queue was reset.
+ */
+msg_t chOQPutTimeout(OutputQueue *oqp, uint8_t b, systime_t timeout) {
+ msg_t msg;
+
+ chSysLock();
+ if ((msg = chSemWaitTimeoutS(&oqp->q_sem, timeout)) < RDY_OK) {
+ chSysUnlock();
+ return msg;
+ }
+ *oqp->q_wrptr++ = b;
+ if (oqp->q_wrptr >= oqp->q_top)
+ oqp->q_wrptr = oqp->q_buffer;
+
+ if (oqp->q_notify)
+ oqp->q_notify();
+
+ chSysUnlock();
+ return Q_OK;
+}
+
+/**
+ * @brief Output queue read.
+ * @details A byte value is read from the low end of an output queue.
+ *
+ * @param[in] oqp pointer to an @p OutputQueue structure
+ * @return The byte value from the queue or:
+ * @retval Q_EMPTY if the queue is empty.
+ */
+msg_t chOQGetI(OutputQueue *oqp) {
+ uint8_t b;
+
+ if (chOQIsEmpty(oqp))
+ return Q_EMPTY;
+
+ b = *oqp->q_rdptr++;
+ if (oqp->q_rdptr >= oqp->q_top)
+ oqp->q_rdptr = oqp->q_buffer;
+ chSemSignalI(&oqp->q_sem);
+ return b;
+}
+
+/**
+ * @brief Non-blocking write.
+ * @details The function writes data from a buffer to an output queue. The
+ * transfer is non-blocking and can return zero if the queue is
+ * already full.
+ *
+ * @param[in] oqp pointer to an @p OutputQueue structure
+ * @param[out] buffer pointer to the buffer where the output data is stored
+ * @param[in] n the maximum amount of data to be transferred
+ * @return The number of bytes transferred.
+ *
+ * @note The function is not atomic, if you need atomicity it is suggested
+ * to use a semaphore or a mutex for mutual exclusion.
+ */
+size_t chOQWrite(OutputQueue *oqp, uint8_t *buffer, size_t n) {
+
+ size_t w = 0;
+ while (n--) {
+ chSysLock();
+ if (chOQIsFull(oqp)) {
+ chSysUnlock();
+ break;
+ }
+ chSemFastWaitI(&oqp->q_sem);
+ *oqp->q_wrptr++ = *buffer++;
+ if (oqp->q_wrptr >= oqp->q_top)
+ oqp->q_wrptr = oqp->q_buffer;
+ chSysUnlock();
+ w++;
+ }
+ if (w && oqp->q_notify) {
+ chSysLock();
+ oqp->q_notify();
+ chSysUnlock();
+ }
+ return w;
+}
+#endif /* CH_USE_QUEUES */
+
+/** @} */
diff --git a/os/kernel/src/chschd.c b/os/kernel/src/chschd.c
new file mode 100644
index 000000000..3ba8b29e9
--- /dev/null
+++ b/os/kernel/src/chschd.c
@@ -0,0 +1,242 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT 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 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT 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, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file chschd.c
+ * @brief Scheduler code.
+ * @addtogroup Scheduler
+ * @{
+ */
+
+#include <ch.h>
+
+/** @cond never */
+ReadyList rlist;
+/** @endcond */
+
+/**
+ * @brief Scheduler initialization.
+ *
+ * @note Internally invoked by the @p chSysInit().
+ */
+void scheduler_init(void) {
+
+ queue_init(&rlist);
+ rlist.r_prio = NOPRIO;
+#if CH_USE_ROUNDROBIN
+ rlist.r_preempt = CH_TIME_QUANTUM;
+#endif
+}
+
+/**
+ * @brief Inserts a thread in the Ready List.
+ *
+ * @param[in] tp the Thread to be made ready
+ * @return The Thread pointer.
+ * @note The function does not reschedule, the @p chSchRescheduleS() should
+ * be called soon after.
+ */
+#if CH_OPTIMIZE_SPEED
+/* NOTE: it is inlined in this module only.*/
+INLINE Thread *chSchReadyI(Thread *tp) {
+#else
+Thread *chSchReadyI(Thread *tp) {
+#endif
+ Thread *cp;
+
+ tp->p_state = PRREADY;
+ cp = (Thread *)&rlist;
+ do {
+ cp = cp->p_next;
+ } while (cp->p_prio >= tp->p_prio);
+ /* Insertion on p_prev.*/
+ tp->p_prev = (tp->p_next = cp)->p_prev;
+ tp->p_prev->p_next = cp->p_prev = tp;
+ return tp;
+}
+
+/**
+ * @brief Puts the current thread to sleep into the specified state.
+ * @details The thread goes into a sleeping state. The @ref thread_states are
+ * described into @p threads.h.
+ *
+ * @param[in] newstate the new thread state
+ */
+void chSchGoSleepS(tstate_t newstate) {
+ Thread *otp;
+
+ (otp = currp)->p_state = newstate;
+ (currp = fifo_remove((void *)&rlist))->p_state = PRCURR;
+#if CH_USE_ROUNDROBIN
+ rlist.r_preempt = CH_TIME_QUANTUM;
+#endif
+ chDbgTrace(otp, currp);
+ chSysSwitchI(otp, currp);
+}
+
+/*
+ * Timeout wakeup callback.
+ */
+static void wakeup(void *p) {
+ Thread *tp = (Thread *)p;
+
+#if CH_USE_SEMAPHORES || CH_USE_MUTEXES || CH_USE_CONDVARS
+ switch (tp->p_state) {
+#if CH_USE_SEMAPHORES
+ case PRWTSEM:
+ chSemFastSignalI(tp->p_wtsemp);
+ /* Falls into, intentional. */
+#endif
+#if CH_USE_MUTEXES
+ case PRWTMTX:
+#endif
+#if CH_USE_CONDVARS
+ case PRWTCOND:
+#endif
+ /* States requiring dequeuing. */
+ dequeue(tp);
+ }
+#endif
+ chSchReadyI(tp)->p_rdymsg = RDY_TIMEOUT;
+}
+
+/**
+ * @brief Puts the current thread to sleep into the specified state with
+ * timeout specification.
+ * @details The thread goes into a sleeping state, if it is not awakened
+ * explicitly within the specified timeout then it is forcibly
+ * awakened with a @p RDY_TIMEOUT low level message. The @ref
+ * thread_states are described into @p threads.h.
+ *
+ * @param[in] newstate the new thread state
+ * @param[in] time the number of ticks before the operation timeouts, the
+ * special values are handled as follow:
+ * - @a TIME_INFINITE the thread enters an infinite sleep
+ * state, this is equivalent to invoking @p chSchGoSleepS()
+ * but, of course, less efficient.
+ * - @a TIME_IMMEDIATE this value is accepted but interpreted
+ * as a normal time specification not as an immediate timeout
+ * specification.
+ * .
+ * @return The wakeup message.
+ * @retval RDY_TIMEOUT if a timeout occurs.
+ */
+msg_t chSchGoSleepTimeoutS(tstate_t newstate, systime_t time) {
+
+ if (TIME_INFINITE != time) {
+ VirtualTimer vt;
+
+ chVTSetI(&vt, time, wakeup, currp);
+ chSchGoSleepS(newstate);
+ if (chVTIsArmedI(&vt))
+ chVTResetI(&vt);
+ }
+ else
+ chSchGoSleepS(newstate);
+ return currp->p_rdymsg;
+}
+
+/**
+ * @brief Wakes up a thread.
+ * @details The thread is inserted into the ready list or immediately made
+ * running depending on its relative priority compared to the current
+ * thread.
+ *
+ * @param[in] ntp the Thread to be made ready
+ * @param[in] msg message to the awakened thread
+ * @note It is equivalent to a @p chSchReadyI() followed by a
+ * @p chSchRescheduleS() but much more efficient.
+ */
+void chSchWakeupS(Thread *ntp, msg_t msg) {
+
+ ntp->p_rdymsg = msg;
+ /* If the waken thread has a not-greater priority than the current
+ * one then it is just inserted in the ready list else it made
+ * running immediately and the invoking thread goes in the ready
+ * list instead.*/
+ if (ntp->p_prio <= currp->p_prio)
+ chSchReadyI(ntp);
+ else {
+ Thread *otp = currp;
+ chSchReadyI(otp);
+ (currp = ntp)->p_state = PRCURR;
+#if CH_USE_ROUNDROBIN
+ rlist.r_preempt = CH_TIME_QUANTUM;
+#endif
+ chDbgTrace(otp, ntp);
+ chSysSwitchI(otp, ntp);
+ }
+}
+
+/**
+ * @brief Switches to the first thread on the runnable queue.
+ *
+ * @note It is intended to be called if @p chSchRescRequiredI() evaluates to
+ * @p TRUE.
+ */
+void chSchDoRescheduleI(void) {
+
+ Thread *otp = currp;
+ /* pick the first thread from the ready queue and makes it current */
+ (currp = fifo_remove((void *)&rlist))->p_state = PRCURR;
+ chSchReadyI(otp);
+#if CH_USE_ROUNDROBIN
+ rlist.r_preempt = CH_TIME_QUANTUM;
+#endif
+ chDbgTrace(otp, currp);
+ chSysSwitchI(otp, currp);
+}
+
+/**
+ * @brief Performs a reschedulation if a higher priority thread is runnable.
+ * @details If a thread with a higher priority than the current thread is in
+ * the ready list then make the higher priority thread running.
+ */
+void chSchRescheduleS(void) {
+ /* first thread in the runnable queue has higher priority than the running
+ * thread? */
+ if (firstprio(&rlist) > currp->p_prio)
+ chSchDoRescheduleI();
+}
+
+/**
+ * @brief Evaluates if a reschedulation is required.
+ * @details The decision is taken by comparing the relative priorities and
+ * depending on the state of the round robin timeout counter.
+ *
+ * @retval TRUE if there is a thread that should go in running state.
+ * @retval FALSE if a reschedulation is not required.
+ */
+bool_t chSchRescRequiredI(void) {
+ tprio_t p1 = firstprio(&rlist);
+ tprio_t p2 = currp->p_prio;
+#if CH_USE_ROUNDROBIN
+ /* If the running thread has not reached its time quantum, reschedule only
+ * if the first thread on the ready queue has a higher priority.
+ * Otherwise, if the running thread has used up its time quantum, reschedule
+ * if the first thread on the ready queue has equal or higher priority.*/
+ return rlist.r_preempt ? p1 > p2 : p1 >= p2;
+#else
+ /* If the round robin feature is not enabled then performs a simpler
+ * comparison.*/
+ return p1 > p2;
+#endif
+}
+
+/** @} */
diff --git a/os/kernel/src/chsem.c b/os/kernel/src/chsem.c
new file mode 100644
index 000000000..9a8570580
--- /dev/null
+++ b/os/kernel/src/chsem.c
@@ -0,0 +1,257 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT 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 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT 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, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file chsem.c
+ * @brief Semaphores code.
+ * @addtogroup Semaphores
+ * @{
+ */
+
+#include <ch.h>
+
+#if CH_USE_SEMAPHORES
+
+#if CH_USE_SEMAPHORES_PRIORITY
+#define sem_insert(tp, qp) prio_insert(tp, qp)
+#else
+#define sem_insert(tp, qp) queue_insert(tp, qp)
+#endif
+
+/**
+ * @brief Initializes a semaphore with the specified counter value.
+ *
+ * @param[out] sp pointer to a @p Semaphore structure
+ * @param[in] n initial value of the semaphore counter. Must be non-negative.
+ * @note This function can be invoked from within an interrupt handler even if
+ * it is not an I-Class API because it does not touch any critical kernel
+ * data structure.
+ */
+void chSemInit(Semaphore *sp, cnt_t n) {
+
+ chDbgCheck((sp != NULL) && (n >= 0), "chSemInit");
+
+ queue_init(&sp->s_queue);
+ sp->s_cnt = n;
+}
+
+/**
+ * @brief Performs a reset operation on the semaphore.
+ *
+ * @param[in] sp pointer to a @p Semaphore structure
+ * @param[in] n the new value of the semaphore counter. The value must be non-negative.
+ * @note The released threads can recognize they were waked up by a reset
+ * instead than a signal because the @p chSemWait() will return
+ * @p RDY_RESET instead of @p RDY_OK.
+ */
+void chSemReset(Semaphore *sp, cnt_t n) {
+
+ chSysLock();
+ chSemResetI(sp, n);
+ chSchRescheduleS();
+ chSysUnlock();
+}
+
+/**
+ * @brief Performs a reset operation on the semaphore.
+ *
+ * @param[in] sp pointer to a @p Semaphore structure
+ * @param[in] n the new value of the semaphore counter. The value must be non-negative.
+ * @note The released threads can recognize they were waked up by a reset
+ * instead than a signal because the @p chSemWait() will return
+ * @p RDY_RESET instead of @p RDY_OK.
+ * @note This function does not reschedule.
+ */
+void chSemResetI(Semaphore *sp, cnt_t n) {
+ cnt_t cnt;
+
+ chDbgCheck((sp != NULL) && (n >= 0), "chSemResetI");
+
+ cnt = sp->s_cnt;
+ sp->s_cnt = n;
+ while (cnt++ < 0)
+ chSchReadyI(lifo_remove(&sp->s_queue))->p_rdymsg = RDY_RESET;
+}
+
+/**
+ * @brief Performs a wait operation on a semaphore.
+ *
+ * @param[in] sp pointer to a @p Semaphore structure
+ * @retval RDY_OK if the semaphore was signaled or not taken.
+ * @retval RDY_RESET if the semaphore was reset using @p chSemReset().
+ */
+msg_t chSemWait(Semaphore *sp) {
+ msg_t msg;
+
+ chSysLock();
+ msg = chSemWaitS(sp);
+ chSysUnlock();
+ return msg;
+}
+
+/**
+ * @brief Performs a wait operation on a semaphore.
+ *
+ * @param[in] sp pointer to a @p Semaphore structure
+ * @retval RDY_OK if the semaphore was signaled or not taken.
+ * @retval RDY_RESET if the semaphore was reset using @p chSemReset().
+ * @note This function must be called with interrupts disabled.
+ * @note This function cannot be called by an interrupt handler.
+ */
+msg_t chSemWaitS(Semaphore *sp) {
+
+ chDbgCheck(sp != NULL, "chSemWaitS");
+
+ if (--sp->s_cnt < 0) {
+ sem_insert(currp, &sp->s_queue);
+ currp->p_wtsemp = sp;
+ chSchGoSleepS(PRWTSEM);
+ return currp->p_rdymsg;
+ }
+ return RDY_OK;
+}
+
+/**
+ * @brief Performs a wait operation on a semaphore with timeout specification.
+ *
+ * @param[in] sp pointer to a @p Semaphore structure
+ * @param[in] time the number of ticks before the operation timeouts,
+ * the following special values are allowed:
+ * - @a TIME_IMMEDIATE immediate timeout.
+ * - @a TIME_INFINITE no timeout.
+ * .
+ * @retval RDY_OK if the semaphore was signaled or not taken.
+ * @retval RDY_RESET if the semaphore was reset using @p chSemReset().
+ * @retval RDY_TIMEOUT if the semaphore was not signaled or reset within the
+ * specified timeout.
+ */
+msg_t chSemWaitTimeout(Semaphore *sp, systime_t time) {
+ msg_t msg;
+
+ chSysLock();
+ msg = chSemWaitTimeoutS(sp, time);
+ chSysUnlock();
+ return msg;
+}
+
+/**
+ * @brief Performs a wait operation on a semaphore with timeout specification.
+ *
+ * @param[in] sp pointer to a @p Semaphore structure
+ * @param[in] time the number of ticks before the operation timeouts,
+ * the following special values are allowed:
+ * - @a TIME_IMMEDIATE immediate timeout.
+ * - @a TIME_INFINITE no timeout.
+ * .
+ * @retval RDY_OK if the semaphore was signaled or not taken.
+ * @retval RDY_RESET if the semaphore was reset using @p chSemReset().
+ * @retval RDY_TIMEOUT if the semaphore was not signaled or reset within the specified
+ * timeout.
+ */
+msg_t chSemWaitTimeoutS(Semaphore *sp, systime_t time) {
+
+ chDbgCheck(sp != NULL, "chSemWaitTimeoutS");
+
+ if (--sp->s_cnt < 0) {
+ if (TIME_IMMEDIATE == time) {
+ sp->s_cnt++;
+ return RDY_TIMEOUT;
+ }
+ sem_insert(currp, &sp->s_queue);
+ currp->p_wtsemp = sp;
+ return chSchGoSleepTimeoutS(PRWTSEM, time);
+ }
+ return RDY_OK;
+}
+
+/**
+ * @brief Performs a signal operation on a semaphore.
+ *
+ * @param[in] sp pointer to a @p Semaphore structure
+ * @note The function is available only if the @p CH_USE_SEMAPHORES
+ * option is enabled in @p chconf.h.
+ */
+void chSemSignal(Semaphore *sp) {
+
+ chDbgCheck(sp != NULL, "chSemSignal");
+
+ chSysLock();
+ if (sp->s_cnt++ < 0)
+ chSchWakeupS(fifo_remove(&sp->s_queue), RDY_OK);
+ chSysUnlock();
+}
+
+/**
+ * @brief Performs a signal operation on a semaphore.
+ *
+ * @param[in] sp pointer to a @p Semaphore structure
+ * @note The function is available only if the @p CH_USE_SEMAPHORES
+ * option is enabled in @p chconf.h.
+ * @note This function does not reschedule.
+ */
+void chSemSignalI(Semaphore *sp) {
+
+ chDbgCheck(sp != NULL, "chSemSignalI");
+
+ if (sp->s_cnt++ < 0) {
+ /* NOTE: It is done this way in order to allow a tail call on
+ chSchReadyI().*/
+ Thread *tp = fifo_remove(&sp->s_queue);
+ tp->p_rdymsg = RDY_OK;
+ chSchReadyI(tp);
+ }
+}
+
+#if CH_USE_SEMSW
+/**
+ * @brief Performs atomic signal and wait operations on two semaphores.
+ *
+ * @param[in] sps pointer to a @p Semaphore structure to be signaled
+ * @param[in] spw pointer to a @p Semaphore structure to be wait on
+ * @retval RDY_OK if the semaphore was signaled or not taken.
+ * @retval RDY_RESET if the semaphore was reset using @p chSemReset().
+ * @note The function is available only if the @p CH_USE_SEMSW
+ * option is enabled in @p chconf.h.
+ */
+msg_t chSemSignalWait(Semaphore *sps, Semaphore *spw) {
+ msg_t msg;
+
+ chDbgCheck((sps != NULL) && (spw != NULL), "chSemSignalWait");
+
+ chSysLock();
+ if (sps->s_cnt++ < 0)
+ chSchReadyI(fifo_remove(&sps->s_queue))->p_rdymsg = RDY_OK;
+ if (--spw->s_cnt < 0) {
+ sem_insert(currp, &spw->s_queue);
+ currp->p_wtsemp = spw;
+ chSchGoSleepS(PRWTSEM);
+ msg = currp->p_rdymsg;
+ }
+ else {
+ chSchRescheduleS();
+ msg = RDY_OK;
+ }
+ chSysUnlock();
+ return msg;
+}
+#endif /* CH_USE_SEMSW */
+
+#endif /* CH_USE_SEMAPHORES */
+
+/** @} */
diff --git a/os/kernel/src/chserial.c b/os/kernel/src/chserial.c
new file mode 100644
index 000000000..65179689d
--- /dev/null
+++ b/os/kernel/src/chserial.c
@@ -0,0 +1,168 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT 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 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT 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, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file chserial.c
+ * @brief Serial Drivers code.
+ * @addtogroup Serial
+ * @{
+ */
+
+#include <ch.h>
+
+#if CH_USE_SERIAL_FULLDUPLEX
+
+/*
+ * Interface implementation, the following functions just invoke the equivalent
+ * queue-level function or macro.
+ */
+static bool_t putwouldblock(void *instance) {
+
+ return chOQIsFull(&((FullDuplexDriver *)instance)->d2.oqueue);
+}
+
+static bool_t getwouldblock(void *instance) {
+
+ return chIQIsEmpty(&((FullDuplexDriver *)instance)->d2.iqueue);
+}
+
+static msg_t put(void *instance, uint8_t b, systime_t timeout) {
+
+ return chOQPutTimeout(&((FullDuplexDriver *)instance)->d2.oqueue, b, timeout);
+}
+
+static msg_t get(void *instance, systime_t timeout) {
+
+ return chIQGetTimeout(&((FullDuplexDriver *)instance)->d2.iqueue, timeout);
+}
+
+static size_t write(void *instance, uint8_t *buffer, size_t n) {
+
+ return chOQWrite(&((FullDuplexDriver *)instance)->d2.oqueue, buffer, n);
+}
+
+static size_t read(void *instance, uint8_t *buffer, size_t n) {
+
+ return chIQRead(&((FullDuplexDriver *)instance)->d2.iqueue, buffer, n);
+}
+
+static const struct FullDuplexDriverVMT vmt = {
+ {putwouldblock, getwouldblock, put, get},
+ {write, read},
+ {}
+};
+
+/**
+ * @brief Initializes a generic full duplex driver.
+ * @details The HW dependent part of the initialization has to be performed
+ * outside, usually in the hardware initialization code.
+ *
+ * @param[out] sd pointer to a @p FullDuplexDriver structure
+ * @param[in] ib pointer to a memory area allocated for the Input Queue buffer
+ * @param[in] isize size of the Input Queue buffer
+ * @param[in] inotify pointer to a callback function that is invoked when
+ * some data is read from the Queue. The value can be
+ * @p NULL.
+ * @param[in] ob pointer to a memory area allocated for the Output Queue buffer
+ * @param[in] osize size of the Output Queue buffer
+ * @param[in] onotify pointer to a callback function that is invoked when
+ * some data is written in the Queue. The value can be
+ * @p NULL.
+ */
+void chFDDInit(FullDuplexDriver *sd,
+ uint8_t *ib, size_t isize, qnotify_t inotify,
+ uint8_t *ob, size_t osize, qnotify_t onotify) {
+
+ chDbgCheck((sd != NULL) && (ib != NULL) && (ob != NULL) &&
+ (isize > 0) && (osize > 0), "chFDDInit");
+
+ sd->vmt = &vmt;
+ chEvtInit(&sd->d1.ievent);
+ chEvtInit(&sd->d1.oevent);
+ chEvtInit(&sd->d2.sevent);
+ sd->d2.flags = SD_NO_ERROR;
+ chIQInit(&sd->d2.iqueue, ib, isize, inotify);
+ chOQInit(&sd->d2.oqueue, ob, osize, onotify);
+}
+
+/**
+ * @brief Handles incoming data.
+ * @details This function must be called from the input interrupt service
+ * routine in order to enqueue incoming data and generate the
+ * related events.
+ * @param[in] sd pointer to a @p FullDuplexDriver structure
+ * @param[in] b the byte to be written in the driver's Input Queue
+ */
+void chFDDIncomingDataI(FullDuplexDriver *sd, uint8_t b) {
+
+ if (chIQPutI(&sd->d2.iqueue, b) < Q_OK)
+ chFDDAddFlagsI(sd, SD_OVERRUN_ERROR);
+ else
+ chEvtBroadcastI(&sd->d1.ievent);
+}
+
+/**
+ * @brief Handles outgoing data.
+ * @details Must be called from the output interrupt service routine in order
+ * to get the next byte to be transmitted.
+ *
+ * @param[in] sd pointer to a @p FullDuplexDriver structure
+ * @return The byte value read from the driver's output queue.
+ * @retval Q_EMPTY if the queue is empty (the lower driver usually disables
+ * the interrupt source when this happens).
+ */
+msg_t chFDDRequestDataI(FullDuplexDriver *sd) {
+
+ msg_t b = chOQGetI(&sd->d2.oqueue);
+ if (b < Q_OK)
+ chEvtBroadcastI(&sd->d1.oevent);
+ return b;
+}
+
+/**
+ * @brief Handles communication events/errors.
+ * @details Must be called from the I/O interrupt service routine in order to
+ * notify I/O conditions as errors, signals change etc.
+ *
+ * @param[in] sd pointer to a @p FullDuplexDriver structure
+ * @param[in] mask condition flags to be added to the mask
+ */
+void chFDDAddFlagsI(FullDuplexDriver *sd, dflags_t mask) {
+
+ sd->d2.flags |= mask;
+ chEvtBroadcastI(&sd->d2.sevent);
+}
+
+/**
+ * @brief Returns and clears the errors mask associated to the driver.
+ *
+ * @param[in] sd pointer to a @p FullDuplexDriver structure
+ * @return The condition flags modified since last time this function was
+ * invoked.
+ */
+dflags_t chFDDGetAndClearFlags(FullDuplexDriver *sd) {
+ dflags_t mask;
+
+ mask = sd->d2.flags;
+ sd->d2.flags = SD_NO_ERROR;
+ return mask;
+}
+#endif /* CH_USE_SERIAL_FULLDUPLEX */
+
+/** @} */
diff --git a/os/kernel/src/chsys.c b/os/kernel/src/chsys.c
new file mode 100644
index 000000000..217e2f2da
--- /dev/null
+++ b/os/kernel/src/chsys.c
@@ -0,0 +1,129 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT 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 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT 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, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file chsys.c
+ * @brief System related code.
+ * @addtogroup System
+ * @{
+ */
+
+#include <ch.h>
+
+static WORKING_AREA(idle_thread_wa, IDLE_THREAD_STACK_SIZE);
+
+/**
+ * @brief This function implements the idle thread infinite loop.
+ * @details The function puts the processor in the lowest power mode capable
+ * to serve interrupts.<br>
+ * The priority is internally set to the minimum system value so
+ * that this thread is executed only if there are no other ready
+ * threads in the system.
+ *
+ * @param[in] p the thread parameter, unused in this scenario
+ */
+static void idle_thread(void *p) {
+
+ while (TRUE) {
+ port_wait_for_interrupt();
+ IDLE_LOOP_HOOK();
+ }
+}
+
+/**
+ * @brief ChibiOS/RT initialization.
+ * @details After executing this function the current instructions stream
+ * becomes the main thread.
+ *
+ * @note Interrupts should be still disabled when @p chSysInit() is invoked
+ * and are internally enabled.
+ * @note The main thread is created with priority @p NORMALPRIO.
+ */
+void chSysInit(void) {
+ static Thread mainthread;
+
+ port_init();
+ scheduler_init();
+ vt_init();
+#if CH_USE_HEAP
+ heap_init();
+#endif
+#if CH_DBG_ENABLE_TRACE
+ trace_init();
+#endif
+
+ /*
+ * Now this instructions flow becomes the main thread.
+ */
+ (currp = init_thread(&mainthread, NORMALPRIO))->p_state = PRCURR;
+ chSysEnable();
+
+ /*
+ * This thread has the lowest priority in the system, its role is just to
+ * serve interrupts in its context while keeping the lowest energy saving
+ * mode compatible with the system status.
+ */
+ chThdCreateStatic(idle_thread_wa, sizeof(idle_thread_wa), IDLEPRIO,
+ (tfunc_t)idle_thread, NULL);
+}
+
+/**
+ * @brief Handles time ticks for round robin preemption and timer increments.
+ * @details Decrements the remaining time quantum of the running thread
+ * and preempts it when the quantum is used up. Increments system
+ * time and manages the timers.
+ *
+ * @note The frequency of the timer determines the system tick granularity and,
+ * together with the @p CH_TIME_QUANTUM macro, the round robin interval.
+ */
+void chSysTimerHandlerI(void) {
+
+#if CH_USE_ROUNDROBIN
+ /* running thread has not used up quantum yet? */
+ if (rlist.r_preempt > 0)
+ /* decrement remaining quantum */
+ rlist.r_preempt--;
+#endif
+#if CH_DBG_THREADS_PROFILING
+ currp->p_time++;
+#endif
+ chVTDoTickI();
+}
+
+#if CH_USE_NESTED_LOCKS && !CH_OPTIMIZE_SPEED
+void chSysLock(void) {
+
+ chDbgAssert(currp->p_locks >= 0,
+ "chSysLock(), #1",
+ "negative nesting counter");
+ if (currp->p_locks++ == 0)
+ port_lock();
+}
+
+void chSysUnlock(void) {
+
+ chDbgAssert(currp->p_locks > 0,
+ "chSysUnlock(), #1",
+ "non-positive nesting counter");
+ if (--currp->p_locks == 0)
+ port_unlock();
+}
+#endif /* CH_USE_NESTED_LOCKS && !CH_OPTIMIZE_SPEED */
+
+/** @} */
diff --git a/os/kernel/src/chthreads.c b/os/kernel/src/chthreads.c
new file mode 100644
index 000000000..f8bb3b869
--- /dev/null
+++ b/os/kernel/src/chthreads.c
@@ -0,0 +1,381 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT 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 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT 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, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file chthreads.c
+ * @brief Threads code.
+ * @addtogroup Threads
+ * @{
+ */
+
+#include <ch.h>
+
+/*
+ * Initializes a thread structure.
+ */
+Thread *init_thread(Thread *tp, tprio_t prio) {
+
+ tp->p_flags = P_MEM_MODE_STATIC;
+ tp->p_prio = prio;
+ tp->p_state = PRSUSPENDED;
+#if CH_USE_NESTED_LOCKS
+ tp->p_locks = 0;
+#endif
+#if CH_DBG_THREADS_PROFILING
+ tp->p_time = 0;
+#endif
+#if CH_USE_MUTEXES
+ /* realprio is the thread's own, non-inherited, priority */
+ tp->p_realprio = prio;
+ tp->p_mtxlist = NULL;
+#endif
+#if CH_USE_WAITEXIT
+ tp->p_waiting = NULL;
+#endif
+#if CH_USE_MESSAGES
+ queue_init(&tp->p_msgqueue);
+#endif
+#if CH_USE_EVENTS
+ tp->p_epending = 0;
+#endif
+ THREAD_EXT_INIT(tp);
+ return tp;
+}
+
+#if CH_DBG_FILL_THREADS
+static void memfill(uint8_t *startp, uint8_t *endp, uint8_t v) {
+
+ while (startp < endp)
+ *startp++ = v;
+}
+#endif
+
+/**
+ * @brief Initializes a new thread.
+ * @details The new thread is initialized but not inserted in the ready list,
+ * the initial state is @p PRSUSPENDED.
+ *
+ * @param[out] wsp pointer to a working area dedicated to the thread stack
+ * @param[in] size size of the working area
+ * @param[in] prio the priority level for the new thread
+ * @param[in] pf the thread function
+ * @param[in] arg an argument passed to the thread function. It can be @p NULL.
+ * @return The pointer to the @p Thread structure allocated for the
+ * thread into the working space area.
+ * @note A thread can terminate by calling @p chThdExit() or by simply
+ * returning from its main function.
+ * @note This function can be invoked from within an interrupt handler even if
+ * it is not an I-Class API because it does not touch any critical kernel
+ * data structure.
+ */
+Thread *chThdInit(void *wsp, size_t size, tprio_t prio, tfunc_t pf, void *arg) {
+ /* Thread structure is layed out in the lower part of the thread workspace */
+ Thread *tp = wsp;
+
+ chDbgCheck((wsp != NULL) && (size >= THD_WA_SIZE(0)) &&
+ (prio <= HIGHPRIO) && (pf != NULL),
+ "chThdInit");
+#if CH_DBG_FILL_THREADS
+ memfill((uint8_t *)wsp, (uint8_t *)wsp + sizeof(Thread), THREAD_FILL_VALUE);
+ memfill((uint8_t *)wsp + sizeof(Thread),
+ (uint8_t *)wsp + size, STACK_FILL_VALUE);
+#endif
+ SETUP_CONTEXT(wsp, size, pf, arg);
+ return init_thread(tp, prio);
+}
+
+/**
+ * @brief Creates a new thread into a static memory area.
+ *
+ * @param[out] wsp pointer to a working area dedicated to the thread
+ * stack
+ * @param[in] size size of the working area
+ * @param[in] prio the priority level for the new thread
+ * @param[in] pf the thread function
+ * @param[in] arg an argument passed to the thread function. It can be @p NULL.
+ * @return The pointer to the @p Thread structure allocated for the
+ * thread into the working space area.
+ * @note A thread can terminate by calling @p chThdExit() or by simply
+ * returning from its main function.
+ */
+Thread *chThdCreateStatic(void *wsp, size_t size,
+ tprio_t prio, tfunc_t pf, void *arg) {
+
+ return chThdResume(chThdInit(wsp, size, prio, pf, arg));
+}
+
+#if CH_USE_DYNAMIC && CH_USE_WAITEXIT && CH_USE_HEAP
+/**
+ * @brief Creates a new thread allocating the memory from the heap.
+ *
+ * @param[in] size size of the working area to be allocated
+ * @param[in] prio the priority level for the new thread
+ * @param[in] pf the thread function
+ * @param[in] arg an argument passed to the thread function. It can be @p NULL.
+ * @return The pointer to the @p Thread structure allocated for the
+ * thread into the working space area.
+ * @retval NULL if the memory cannot be allocated.
+ * @note A thread can terminate by calling @p chThdExit() or by simply
+ * returning from its main function.
+ * @note The memory allocated for the thread is not released when the thread
+ * terminates but when a @p chThdWait() is performed.
+ * @note The function is available only if the @p CH_USE_DYNAMIC,
+ * @p CH_USE_HEAP and @p CH_USE_WAITEXIT options are enabled
+ * in @p chconf.h.
+ */
+Thread *chThdCreateFromHeap(size_t size, tprio_t prio, tfunc_t pf, void *arg) {
+ void *wsp;
+ Thread *tp;
+
+ wsp = chHeapAlloc(size);
+ if (wsp == NULL)
+ return NULL;
+ tp = chThdInit(wsp, size, prio, pf, arg);
+ tp->p_flags = P_MEM_MODE_HEAP;
+ return chThdResume(tp);
+}
+#endif /* CH_USE_DYNAMIC && CH_USE_WAITEXIT && CH_USE_HEAP */
+
+#if CH_USE_DYNAMIC && CH_USE_WAITEXIT && CH_USE_MEMPOOLS
+/**
+ * @brief Creates a new thread allocating the memory from the specified Memory
+ * Pool.
+ *
+ * @param[in] mp the memory pool
+ * @param[in] prio the priority level for the new thread
+ * @param[in] pf the thread function
+ * @param[in] arg an argument passed to the thread function. It can be @p NULL.
+ * @return The pointer to the @p Thread structure allocated for the
+ * thread into the working space area or @p NULL if the memory cannot
+ * be allocated.
+ * @retval NULL if the memory pool is empty.
+ * @note A thread can terminate by calling @p chThdExit() or by simply
+ * returning from its main function.
+ * @note The memory allocated for the thread is not released when the thread
+ * terminates but when a @p chThdWait() is performed.
+ * @note The function is available only if the @p CH_USE_DYNAMIC,
+ * @p CH_USE_MEMPOOLS and @p CH_USE_WAITEXIT options are enabled
+ * in @p chconf.h.
+ */
+Thread *chThdCreateFromMemoryPool(MemoryPool *mp, tprio_t prio,
+ tfunc_t pf, void *arg) {
+ void *wsp;
+ Thread *tp;
+
+ chDbgCheck(mp != NULL, "chThdCreateFromMemoryPool");
+
+ wsp = chPoolAlloc(mp);
+ if (wsp == NULL)
+ return NULL;
+ tp = chThdInit(wsp, mp->mp_object_size, prio, pf, arg);
+ tp->p_flags = P_MEM_MODE_MEMPOOL;
+ tp->p_mpool = mp;
+ return chThdResume(tp);
+}
+#endif /* CH_USE_DYNAMIC && CH_USE_WAITEXIT && CH_USE_MEMPOOLS */
+
+/**
+ * @brief Changes the running thread priority level then reschedules if
+ * necessary.
+ *
+ * @param[in] newprio the new priority level of the running thread
+ * @return The old priority level.
+ * @note The function returns the real thread priority regardless of the
+ * current priority that could be higher than the real priority because
+ * the priority inheritance mechanism.
+ */
+tprio_t chThdSetPriority(tprio_t newprio) {
+ tprio_t oldprio;
+
+ chDbgCheck((newprio >= LOWPRIO) && (newprio <= HIGHPRIO),
+ "chThdSetPriority");
+
+ chSysLock();
+#if CH_USE_MUTEXES
+ oldprio = currp->p_realprio;
+ if ((currp->p_prio == currp->p_realprio) || (newprio > currp->p_prio))
+ currp->p_prio = newprio;
+ currp->p_realprio = newprio;
+#else
+ oldprio = currp->p_prio;
+ currp->p_prio = newprio;
+#endif
+ chSchRescheduleS();
+ chSysUnlock();
+ return oldprio;
+}
+
+/**
+ * @brief Resumes a suspended thread.
+ *
+ * @param[in] tp the pointer to the thread
+ * @return The pointer to the thread.
+ * @note This call is supposed to resume threads created with @p chThdInit().
+ * It should not be used on threads suspended using @p chThdSuspend().
+ */
+Thread *chThdResume(Thread *tp) {
+
+ chSysLock();
+ chDbgAssert(tp->p_state == PRSUSPENDED,
+ "chThdResume(), #1",
+ "thread not in PRSUSPENDED state");
+ chSchWakeupS(tp, RDY_OK);
+ chSysUnlock();
+ return tp;
+}
+
+/**
+ * @brief Requests a thread termination.
+ *
+ * @param[in] tp the pointer to the thread
+ * @note The thread is not termitated but a termination request is added to
+ * its @p p_flags field. The thread can read this status by
+ * invoking @p chThdShouldTerminate() and then terminate cleanly.
+ */
+void chThdTerminate(Thread *tp) {
+
+ chSysLock();
+ tp->p_flags |= P_TERMINATE;
+ chSysUnlock();
+}
+
+/**
+ * @brief Suspends the invoking thread for the specified time.
+ *
+ * @param[in] time the delay in system ticks, the special values are handled as
+ * follow:
+ * - @a TIME_INFINITE the thread enters an infinite sleep
+ * state.
+ * - @a TIME_IMMEDIATE this value is accepted but interpreted
+ * as a normal time specification not as an immediate timeout
+ * specification.
+ * .
+ */
+void chThdSleep(systime_t time) {
+
+ chDbgCheck(time != TIME_INFINITE, "chThdSleep");
+
+ chSysLock();
+ chThdSleepS(time);
+ chSysUnlock();
+}
+
+/**
+ * @brief Suspends the invoking thread until the system time arrives to the
+ * specified value.
+ *
+ * @param[in] time the absolute system time
+ */
+void chThdSleepUntil(systime_t time) {
+
+ chSysLock();
+ if ((time -= chTimeNow()) > 0)
+ chThdSleepS(time);
+ chSysUnlock();
+}
+
+/**
+ * @brief Terminates the current thread by specifying an exit status code.
+ *
+ * @param[in] msg the thread exit code. The code can be retrieved by using
+ * @p chThdWait().
+ */
+void chThdExit(msg_t msg) {
+ Thread *tp = currp;
+
+ chSysLock();
+ tp->p_exitcode = msg;
+ THREAD_EXT_EXIT(tp);
+#if CH_USE_WAITEXIT
+ if (tp->p_waiting != NULL)
+ chSchReadyI(tp->p_waiting);
+#endif
+ chSchGoSleepS(PREXIT);
+}
+
+#if CH_USE_WAITEXIT
+/**
+ * @brief Blocks the execution of the invoking thread until the specified
+ * thread terminates then the exit code is returned.
+ * @details The memory used by the exited thread is handled in different ways
+ * depending on the API that spawned the thread:
+ * - If the thread was spawned by @p chThdCreateStatic() or by
+ * @p chThdInit() then nothing happens and the thread working area
+ * is not released or modified in any way. This is the default,
+ * totally static, behavior.
+ * - If the thread was spawned by @p chThdCreateFromHeap() then
+ * the working area is returned to the system heap.
+ * - If the thread was spawned by @p chThdCreateFromMemoryPool()
+ * then the working area is returned to the owning memory pool.
+ * .
+ * @param[in] tp the thread pointer
+ * @return The exit code from the terminated thread
+ * @note After invoking @p chThdWait() the thread pointer becomes invalid and
+ * must not be used as parameter for further system calls.
+ * @note The function is available only if the @p CH_USE_WAITEXIT
+ * option is enabled in @p chconf.h.
+ * @note Only one thread can be waiting for another thread at any time. You
+ * should imagine the threads as having a reference counter that is set
+ * to one when the thread is created, chThdWait() decreases the reference
+ * and the memory is freed when the counter reaches zero. In the current
+ * implementation there is no real reference counter in the thread
+ * structure but it is a planned extension.
+ */
+msg_t chThdWait(Thread *tp) {
+ msg_t msg;
+
+ chDbgCheck(tp != NULL, "chThdWait");
+
+ chSysLock();
+
+ chDbgAssert(tp != currp, "chThdWait(), #1", "waiting self");
+ chDbgAssert(tp->p_waiting == NULL, "chThdWait(), #2", "some other thread waiting");
+
+ if (tp->p_state != PREXIT) {
+ tp->p_waiting = currp;
+ chSchGoSleepS(PRWAIT);
+ }
+ msg = tp->p_exitcode;
+#if !CH_USE_DYNAMIC
+ chSysUnlock();
+ return msg;
+#else /* CH_USE_DYNAMIC */
+
+ /* Returning memory.*/
+ tmode_t mode = tp->p_flags & P_MEM_MODE_MASK;
+ chSysUnlock();
+
+ switch (mode) {
+#if CH_USE_HEAP
+ case P_MEM_MODE_HEAP:
+ chHeapFree(tp);
+ break;
+#endif
+#if CH_USE_MEMPOOLS
+ case P_MEM_MODE_MEMPOOL:
+ chPoolFree(tp->p_mpool, tp);
+ break;
+#endif
+ }
+ return msg;
+#endif /* CH_USE_DYNAMIC */
+}
+#endif /* CH_USE_WAITEXIT */
+
+/** @} */
diff --git a/os/kernel/src/chvt.c b/os/kernel/src/chvt.c
new file mode 100644
index 000000000..c1d8734ec
--- /dev/null
+++ b/os/kernel/src/chvt.c
@@ -0,0 +1,116 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT 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 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT 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, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file chvt.c
+ * @brief Time and Virtual Timers related code.
+ * @addtogroup Time
+ * @{
+ */
+
+#include <ch.h>
+
+VTList vtlist;
+
+/**
+ * @brief Virtual Timers initialization.
+ *
+ * @note Internal use only.
+ */
+void vt_init(void) {
+
+ vtlist.vt_next = vtlist.vt_prev = (void *)&vtlist;
+ vtlist.vt_time = (systime_t)-1;
+ vtlist.vt_systime = 0;
+}
+
+/**
+ * @brief Enables a virtual timer.
+ *
+ * @param[out] vtp the @p VirtualTimer structure pointer
+ * @param[in] time the number of time ticks, the value @p TIME_INFINITE is not
+ * allowed. The value @p TIME_IMMEDIATE is allowed but
+ * interpreted as a normal time specification not as an
+ * immediate timeout specification.
+ * @param[in] vtfunc the timer callback function. After invoking the callback
+ * the timer is disabled and the structure can be disposed or
+ * reused.
+ * @param[in] par a parameter that will be passed to the callback function
+ * @note The associated function is invoked by an interrupt handler within
+ * the I-Locked state, see @ref system_states.
+ */
+void chVTSetI(VirtualTimer *vtp, systime_t time, vtfunc_t vtfunc, void *par) {
+ VirtualTimer *p;
+
+ chDbgCheck((vtp != NULL) && (vtfunc != NULL) && (time != TIME_INFINITE),
+ "chVTSetI");
+
+ vtp->vt_par = par;
+ vtp->vt_func = vtfunc;
+ p = vtlist.vt_next;
+ while (p->vt_time < time) {
+ time -= p->vt_time;
+ p = p->vt_next;
+ }
+
+ vtp->vt_prev = (vtp->vt_next = p)->vt_prev;
+ vtp->vt_prev->vt_next = p->vt_prev = vtp;
+ vtp->vt_time = time;
+ if (p != (void *)&vtlist)
+ p->vt_time -= time;
+}
+
+/**
+ * @brief Disables a Virtual Timer.
+ *
+ * @param[in] vtp the @p VirtualTimer structure pointer
+ * @note The timer MUST be active when this function is invoked.
+ */
+void chVTResetI(VirtualTimer *vtp) {
+
+ chDbgCheck(vtp != NULL, "chVTResetI");
+ chDbgAssert(vtp->vt_func != NULL,
+ "chVTResetI(), #1",
+ "timer not set or already triggered");
+
+ if (vtp->vt_next != (void *)&vtlist)
+ vtp->vt_next->vt_time += vtp->vt_time;
+ vtp->vt_prev->vt_next = vtp->vt_next;
+ vtp->vt_next->vt_prev = vtp->vt_prev;
+ vtp->vt_func = NULL;
+}
+
+/**
+ * @brief Checks if the current system time is within the specified time window.
+ *
+ * @param[in] start the start of the time window (inclusive)
+ * @param[in] end the end of the time window (non inclusive)
+ * @retval TRUE current time within the specified time window.
+ * @retval FALSE current time not within the specified time window.
+ * @note When start==end then the function returns always true because the
+ * whole time range is specified.
+ */
+bool_t chTimeIsWithin(systime_t start, systime_t end) {
+
+ systime_t time = chTimeNow();
+ return end > start ? (time >= start) && (time < end) :
+ (time >= start) || (time < end);
+}
+
+/** @} */
diff --git a/os/ports/GCC/ARM/rules.mk b/os/ports/GCC/ARM/rules.mk
new file mode 100644
index 000000000..5b7d5ae6f
--- /dev/null
+++ b/os/ports/GCC/ARM/rules.mk
@@ -0,0 +1,136 @@
+# ARM7 common makefile scripts and rules.
+
+# Automatic compiler options
+OPT = $(USE_OPT)
+CPPOPT = $(USE_CPPOPT)
+ifeq ($(USE_CURRP_CACHING),yes)
+ OPT += -ffixed-r7 -DCH_CURRP_REGISTER_CACHE='"r7"'
+endif
+ifeq ($(USE_LINK_GC),yes)
+ OPT += -ffunction-sections -fdata-sections
+endif
+
+# Source files groups
+ifeq ($(USE_THUMB),yes)
+ TCSRC += $(CSRC)
+ TCPPSRC += $(CPPSRC)
+else
+ ACSRC += $(CSRC)
+ ACPPSRC += $(CPPSRC)
+endif
+ASRC = $(ACSRC)$(ACPPSRC)
+TSRC = $(TCSRC)$(TCPPSRC)
+SRC = $(ASRC)$(TSRC)
+
+# Object files groups
+ACOBJS = $(ACSRC:.c=.o)
+ACPPOBJS = $(ACPPSRC:.cpp=.o)
+TCOBJS = $(TCSRC:.c=.o)
+TCPPOBJS = $(TCPPSRC:.cpp=.o)
+ASMOBJS = $(ASMSRC:.s=.o)
+OBJS = $(ASMOBJS) $(ACOBJS) $(TCOBJS) $(ACPPOBJS) $(TCPPOBJS)
+
+# Paths
+IINCDIR = $(patsubst %,-I%,$(INCDIR) $(DINCDIR) $(UINCDIR))
+LLIBDIR = $(patsubst %,-L%,$(DLIBDIR) $(ULIBDIR))
+
+# Macros
+DEFS = $(DDEFS) $(UDEFS)
+ADEFS = $(DADEFS) $(UADEFS)
+
+# Libs
+LIBS = $(DLIBS) $(ULIBS)
+
+# Various settings
+MCFLAGS = -mcpu=$(MCU)
+ODFLAGS = -x --syms
+ASFLAGS = $(MCFLAGS) -Wa,-amhls=$(<:.s=.lst) $(ADEFS)
+CFLAGS = $(MCFLAGS) $(OPT) $(CWARN) -Wa,-alms=$(<:.c=.lst) $(DEFS)
+CPPFLAGS = $(MCFLAGS) $(OPT) $(CPPOPT) $(CPPWARN) -Wa,-alms=$(<:.cpp=.lst) $(DEFS)
+ifeq ($(LINK_GC),yes)
+ LDFLAGS = $(MCFLAGS) -nostartfiles -T$(LDSCRIPT) -Wl,-Map=$(PROJECT).map,--cref,--no-warn-mismatch,--gc-sections $(LLIBDIR)
+else
+ LDFLAGS = $(MCFLAGS) -nostartfiles -T$(LDSCRIPT) -Wl,-Map=$(PROJECT).map,--cref,--no-warn-mismatch $(LLIBDIR)
+endif
+
+# Thumb interwork enabled only if needed because it kills performance.
+ifneq ($(TSRC),)
+ CFLAGS += -DTHUMB_PRESENT
+ CPPFLAGS += -DTHUMB_PRESENT
+ ASFLAGS += -DTHUMB_PRESENT
+ ifneq ($(ASRC),)
+ # Mixed ARM and THUMB mode.
+ CFLAGS += -mthumb-interwork
+ CPPFLAGS += -mthumb-interwork
+ ASFLAGS += -mthumb-interwork
+ LDFLAGS += -mthumb-interwork
+ else
+ # Pure THUMB mode, THUMB C code cannot be called by ARM asm code directly.
+ CFLAGS += -mno-thumb-interwork -DTHUMB_NO_INTERWORKING
+ CPPFLAGS += -mno-thumb-interwork -DTHUMB_NO_INTERWORKING
+ ASFLAGS += -mno-thumb-interwork -DTHUMB_NO_INTERWORKING -mthumb
+ LDFLAGS += -mno-thumb-interwork -mthumb
+ endif
+else
+ # Pure ARM mode
+ CPFLAGS += -mno-thumb-interwork
+ CPPFLAGS += -mno-thumb-interwork
+ ASFLAGS += -mno-thumb-interwork
+ LDFLAGS += -mno-thumb-interwork
+endif
+
+# Generate dependency information
+CFLAGS += -MD -MP -MF .dep/$(@F).d
+CPPFLAGS += -MD -MP -MF .dep/$(@F).d
+
+#
+# Makefile rules
+#
+
+all: $(OBJS) $(PROJECT).elf $(PROJECT).hex $(PROJECT).bin $(PROJECT).dmp
+
+$(ACPPOBJS) : %.o : %.cpp
+ @echo
+ $(CPPC) -c $(CPPFLAGS) $(AOPT) -I . $(IINCDIR) $< -o $@
+
+$(TCPPOBJS) : %.o : %.cpp
+ @echo
+ $(CPPC) -c $(CPPFLAGS) $(TOPT) -I . $(IINCDIR) $< -o $@
+
+$(ACOBJS) : %.o : %.c
+ @echo
+ $(CC) -c $(CFLAGS) $(AOPT) -I . $(IINCDIR) $< -o $@
+
+$(TCOBJS) : %.o : %.c
+ @echo
+ $(CC) -c $(CFLAGS) $(TOPT) -I . $(IINCDIR) $< -o $@
+
+$(ASMOBJS) : %.o : %.s
+ @echo
+ $(AS) -c $(ASFLAGS) -I . $(IINCDIR) $< -o $@
+
+%elf: $(OBJS)
+ @echo
+ $(LD) $(OBJS) $(LDFLAGS) $(LIBS) -o $@
+
+%hex: %elf
+ $(HEX) $< $@
+
+%bin: %elf
+ $(BIN) $< $@
+
+%dmp: %elf
+ $(OD) $(ODFLAGS) $< > $@
+
+clean:
+ -rm -f $(OBJS)
+ -rm -f $(ACSRC:.c=.lst) $(TCSRC:.c=.lst) $(ACPPSRC:.cpp=.lst) $(TCPPSRC:.cpp=.lst) $(ASMSRC:.s=.lst)
+ -rm -f $(PROJECT).elf $(PROJECT).dmp $(PROJECT).map $(PROJECT).hex $(PROJECT).bin
+ -rm -fR .dep
+
+#
+# Include the dependency files, should be the last of the makefile
+#
+-include $(shell mkdir .dep 2>/dev/null) $(wildcard .dep/*)
+
+# *** EOF ***
diff --git a/os/ports/GCC/ARM7/AT91SAM7X/mii.h b/os/ports/GCC/ARM7/AT91SAM7X/mii.h
new file mode 100644
index 000000000..4ec25667a
--- /dev/null
+++ b/os/ports/GCC/ARM7/AT91SAM7X/mii.h
@@ -0,0 +1,156 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT 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 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT 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, see <http://www.gnu.org/licenses/>.
+*/
+
+/*
+ * Parts of this file are borrowed by the Linux include file linux/mii.h:
+ * Copyright (C) 1996, 1999, 2001 David S. Miller (davem@redhat.com)
+ */
+
+#ifndef _MII_H_
+#define _MII_H_
+
+/* Generic MII registers. */
+#define MII_BMCR 0x00 /* Basic mode control register */
+#define MII_BMSR 0x01 /* Basic mode status register */
+#define MII_PHYSID1 0x02 /* PHYS ID 1 */
+#define MII_PHYSID2 0x03 /* PHYS ID 2 */
+#define MII_ADVERTISE 0x04 /* Advertisement control reg */
+#define MII_LPA 0x05 /* Link partner ability reg */
+#define MII_EXPANSION 0x06 /* Expansion register */
+#define MII_CTRL1000 0x09 /* 1000BASE-T control */
+#define MII_STAT1000 0x0a /* 1000BASE-T status */
+#define MII_ESTATUS 0x0f /* Extended Status */
+#define MII_DCOUNTER 0x12 /* Disconnect counter */
+#define MII_FCSCOUNTER 0x13 /* False carrier counter */
+#define MII_NWAYTEST 0x14 /* N-way auto-neg test reg */
+#define MII_RERRCOUNTER 0x15 /* Receive error counter */
+#define MII_SREVISION 0x16 /* Silicon revision */
+#define MII_RESV1 0x17 /* Reserved... */
+#define MII_LBRERROR 0x18 /* Lpback, rx, bypass error */
+#define MII_PHYADDR 0x19 /* PHY address */
+#define MII_RESV2 0x1a /* Reserved... */
+#define MII_TPISTATUS 0x1b /* TPI status for 10mbps */
+#define MII_NCONFIG 0x1c /* Network interface config */
+
+/* Basic mode control register. */
+#define BMCR_RESV 0x003f /* Unused... */
+#define BMCR_SPEED1000 0x0040 /* MSB of Speed (1000) */
+#define BMCR_CTST 0x0080 /* Collision test */
+#define BMCR_FULLDPLX 0x0100 /* Full duplex */
+#define BMCR_ANRESTART 0x0200 /* Auto negotiation restart */
+#define BMCR_ISOLATE 0x0400 /* Disconnect DP83840 from MII */
+#define BMCR_PDOWN 0x0800 /* Powerdown the DP83840 */
+#define BMCR_ANENABLE 0x1000 /* Enable auto negotiation */
+#define BMCR_SPEED100 0x2000 /* Select 100Mbps */
+#define BMCR_LOOPBACK 0x4000 /* TXD loopback bits */
+#define BMCR_RESET 0x8000 /* Reset the DP83840 */
+
+/* Basic mode status register. */
+#define BMSR_ERCAP 0x0001 /* Ext-reg capability */
+#define BMSR_JCD 0x0002 /* Jabber detected */
+#define BMSR_LSTATUS 0x0004 /* Link status */
+#define BMSR_ANEGCAPABLE 0x0008 /* Able to do auto-negotiation */
+#define BMSR_RFAULT 0x0010 /* Remote fault detected */
+#define BMSR_ANEGCOMPLETE 0x0020 /* Auto-negotiation complete */
+#define BMSR_RESV 0x00c0 /* Unused... */
+#define BMSR_ESTATEN 0x0100 /* Extended Status in R15 */
+#define BMSR_100HALF2 0x0200 /* Can do 100BASE-T2 HDX */
+#define BMSR_100FULL2 0x0400 /* Can do 100BASE-T2 FDX */
+#define BMSR_10HALF 0x0800 /* Can do 10mbps, half-duplex */
+#define BMSR_10FULL 0x1000 /* Can do 10mbps, full-duplex */
+#define BMSR_100HALF 0x2000 /* Can do 100mbps, half-duplex */
+#define BMSR_100FULL 0x4000 /* Can do 100mbps, full-duplex */
+#define BMSR_100BASE4 0x8000 /* Can do 100mbps, 4k packets */
+
+/* Advertisement control register. */
+#define ADVERTISE_SLCT 0x001f /* Selector bits */
+#define ADVERTISE_CSMA 0x0001 /* Only selector supported */
+#define ADVERTISE_10HALF 0x0020 /* Try for 10mbps half-duplex */
+#define ADVERTISE_1000XFULL 0x0020 /* Try for 1000BASE-X full-duplex */
+#define ADVERTISE_10FULL 0x0040 /* Try for 10mbps full-duplex */
+#define ADVERTISE_1000XHALF 0x0040 /* Try for 1000BASE-X half-duplex */
+#define ADVERTISE_100HALF 0x0080 /* Try for 100mbps half-duplex */
+#define ADVERTISE_1000XPAUSE 0x0080 /* Try for 1000BASE-X pause */
+#define ADVERTISE_100FULL 0x0100 /* Try for 100mbps full-duplex */
+#define ADVERTISE_1000XPSE_ASYM 0x0100 /* Try for 1000BASE-X asym pause */
+#define ADVERTISE_100BASE4 0x0200 /* Try for 100mbps 4k packets */
+#define ADVERTISE_PAUSE_CAP 0x0400 /* Try for pause */
+#define ADVERTISE_PAUSE_ASYM 0x0800 /* Try for asymetric pause */
+#define ADVERTISE_RESV 0x1000 /* Unused... */
+#define ADVERTISE_RFAULT 0x2000 /* Say we can detect faults */
+#define ADVERTISE_LPACK 0x4000 /* Ack link partners response */
+#define ADVERTISE_NPAGE 0x8000 /* Next page bit */
+
+#define ADVERTISE_FULL (ADVERTISE_100FULL | ADVERTISE_10FULL | \
+ ADVERTISE_CSMA)
+#define ADVERTISE_ALL (ADVERTISE_10HALF | ADVERTISE_10FULL | \
+ ADVERTISE_100HALF | ADVERTISE_100FULL)
+
+/* Link partner ability register. */
+#define LPA_SLCT 0x001f /* Same as advertise selector */
+#define LPA_10HALF 0x0020 /* Can do 10mbps half-duplex */
+#define LPA_1000XFULL 0x0020 /* Can do 1000BASE-X full-duplex */
+#define LPA_10FULL 0x0040 /* Can do 10mbps full-duplex */
+#define LPA_1000XHALF 0x0040 /* Can do 1000BASE-X half-duplex */
+#define LPA_100HALF 0x0080 /* Can do 100mbps half-duplex */
+#define LPA_1000XPAUSE 0x0080 /* Can do 1000BASE-X pause */
+#define LPA_100FULL 0x0100 /* Can do 100mbps full-duplex */
+#define LPA_1000XPAUSE_ASYM 0x0100 /* Can do 1000BASE-X pause asym*/
+#define LPA_100BASE4 0x0200 /* Can do 100mbps 4k packets */
+#define LPA_PAUSE_CAP 0x0400 /* Can pause */
+#define LPA_PAUSE_ASYM 0x0800 /* Can pause asymetrically */
+#define LPA_RESV 0x1000 /* Unused... */
+#define LPA_RFAULT 0x2000 /* Link partner faulted */
+#define LPA_LPACK 0x4000 /* Link partner acked us */
+#define LPA_NPAGE 0x8000 /* Next page bit */
+
+#define LPA_DUPLEX (LPA_10FULL | LPA_100FULL)
+#define LPA_100 (LPA_100FULL | LPA_100HALF | LPA_100BASE4)
+
+/* Expansion register for auto-negotiation. */
+#define EXPANSION_NWAY 0x0001 /* Can do N-way auto-nego */
+#define EXPANSION_LCWP 0x0002 /* Got new RX page code word */
+#define EXPANSION_ENABLENPAGE 0x0004 /* This enables npage words */
+#define EXPANSION_NPCAPABLE 0x0008 /* Link partner supports npage */
+#define EXPANSION_MFAULTS 0x0010 /* Multiple faults detected */
+#define EXPANSION_RESV 0xffe0 /* Unused... */
+
+#define ESTATUS_1000_TFULL 0x2000 /* Can do 1000BT Full */
+#define ESTATUS_1000_THALF 0x1000 /* Can do 1000BT Half */
+
+/* N-way test register. */
+#define NWAYTEST_RESV1 0x00ff /* Unused... */
+#define NWAYTEST_LOOPBACK 0x0100 /* Enable loopback for N-way */
+#define NWAYTEST_RESV2 0xfe00 /* Unused... */
+
+/* 1000BASE-T Control register */
+#define ADVERTISE_1000FULL 0x0200 /* Advertise 1000BASE-T full duplex */
+#define ADVERTISE_1000HALF 0x0100 /* Advertise 1000BASE-T half duplex */
+
+/* 1000BASE-T Status register */
+#define LPA_1000LOCALRXOK 0x2000 /* Link partner local receiver status */
+#define LPA_1000REMRXOK 0x1000 /* Link partner remote receiver status */
+#define LPA_1000FULL 0x0800 /* Link partner 1000BASE-T full duplex */
+#define LPA_1000HALF 0x0400 /* Link partner 1000BASE-T half duplex */
+
+#define MII_DM9161_ID 0x0181b8a0
+#define MII_AM79C875_ID 0x00225540
+#define MII_MICREL_ID 0x00221610
+
+#endif /* _MII_H_ */
diff --git a/os/ports/GCC/ARM7/AT91SAM7X/pal_lld.c b/os/ports/GCC/ARM7/AT91SAM7X/pal_lld.c
new file mode 100644
index 000000000..266bdb38d
--- /dev/null
+++ b/os/ports/GCC/ARM7/AT91SAM7X/pal_lld.c
@@ -0,0 +1,116 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT 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 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT 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, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file ports/ARM7-AT91SAM7X/pal_lld.c
+ * @brief AT91SAM7X PIO low level driver code
+ * @addtogroup AT91SAM7X_PAL
+ * @{
+ */
+
+#include <ch.h>
+#include <pal.h>
+
+/**
+ * @brief AT91SAM7X I/O ports configuration.
+ * @details PIO registers initialization.
+ *
+ * @param[in] config the AT91SAM7X ports configuration
+ */
+void _pal_lld_init(const AT91SAM7XPIOConfig *config) {
+
+ AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_PIOA) | (1 << AT91C_ID_PIOB);
+
+ /*
+ * PIOA setup.
+ */
+ AT91C_BASE_PIOA->PIO_OER = config->P0Data.pusr; /* Pull-up as spec.*/
+ AT91C_BASE_PIOA->PIO_ODR = ~config->P0Data.pusr;
+ AT91C_BASE_PIOA->PIO_PER = 0xFFFFFFFF; /* PIO enabled.*/
+ AT91C_BASE_PIOA->PIO_ODSR = config->P0Data.odsr; /* Data as specified.*/
+ AT91C_BASE_PIOA->PIO_OER = config->P0Data.osr; /* Dir. as specified.*/
+ AT91C_BASE_PIOA->PIO_ODR = ~config->P0Data.osr;
+ AT91C_BASE_PIOA->PIO_IFDR = 0xFFFFFFFF; /* Filter disabled.*/
+ AT91C_BASE_PIOA->PIO_IDR = 0xFFFFFFFF; /* Int. disabled.*/
+ AT91C_BASE_PIOA->PIO_MDDR = 0xFFFFFFFF; /* Push Pull drive.*/
+ AT91C_BASE_PIOA->PIO_ASR = 0xFFFFFFFF; /* Peripheral A.*/
+ AT91C_BASE_PIOA->PIO_OWER = 0xFFFFFFFF; /* Write enabled.*/
+
+ /*
+ * PIOB setup.
+ */
+ AT91C_BASE_PIOB->PIO_OER = config->P0Data.pusr; /* Pull-up as spec.*/
+ AT91C_BASE_PIOB->PIO_ODR = ~config->P0Data.pusr;
+ AT91C_BASE_PIOB->PIO_PER = 0xFFFFFFFF; /* PIO enabled.*/
+ AT91C_BASE_PIOB->PIO_ODSR = config->P1Data.odsr; /* Data as specified.*/
+ AT91C_BASE_PIOB->PIO_OER = config->P1Data.osr; /* Dir. as specified.*/
+ AT91C_BASE_PIOB->PIO_ODR = ~config->P1Data.osr;
+ AT91C_BASE_PIOB->PIO_IFDR = 0xFFFFFFFF; /* Filter disabled.*/
+ AT91C_BASE_PIOB->PIO_IDR = 0xFFFFFFFF; /* Int. disabled.*/
+ AT91C_BASE_PIOB->PIO_MDDR = 0xFFFFFFFF; /* Push Pull drive.*/
+ AT91C_BASE_PIOB->PIO_ASR = 0xFFFFFFFF; /* Peripheral A.*/
+ AT91C_BASE_PIOB->PIO_OWER = 0xFFFFFFFF; /* Write enabled.*/
+}
+
+/**
+ * @brief Pads mode setup.
+ * @details This function programs a pads group belonging to the same port
+ * with the specified mode.
+ *
+ * @param[in] port the port identifier
+ * @param[in] mask the group mask
+ * @param[in] mode the mode
+ *
+ * @note This function is not meant to be invoked directly by the application
+ * code.
+ * @note @p PAL_MODE_RESET is implemented as input with pull-up.
+ * @note @p PAL_MODE_UNCONNECTED is implemented as push pull output with high
+ * state.
+ * @note @p PAL_MODE_OUTPUT_OPENDRAIN also enables the pull-up resistor.
+ */
+void _pal_lld_setgroupmode(ioportid_t port,
+ ioportmask_t mask,
+ uint_fast8_t mode) {
+
+ switch (mode & PAL_MODE_MASK) {
+ case PAL_MODE_RESET:
+ case PAL_MODE_INPUT_PULLUP:
+ port->PIO_PPUER = mask;
+ port->PIO_ODR = mask;
+ break;
+ case PAL_MODE_INPUT:
+ port->PIO_PPUDR = mask;
+ port->PIO_ODR = mask;
+ break;
+ case PAL_MODE_UNCONNECTED:
+ port->PIO_SODR = mask;
+ /* Falls in */
+ case PAL_MODE_OUTPUT_PUSHPULL:
+ port->PIO_PPUDR = mask;
+ port->PIO_OER = mask;
+ port->PIO_MDDR = mask;
+ break;
+ case PAL_MODE_OUTPUT_OPENDRAIN:
+ port->PIO_PPUER = mask;
+ port->PIO_OER = mask;
+ port->PIO_MDER = mask;
+ }
+}
+
+/** @} */
diff --git a/os/ports/GCC/ARM7/AT91SAM7X/pal_lld.h b/os/ports/GCC/ARM7/AT91SAM7X/pal_lld.h
new file mode 100644
index 000000000..b403fc2cc
--- /dev/null
+++ b/os/ports/GCC/ARM7/AT91SAM7X/pal_lld.h
@@ -0,0 +1,245 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT 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 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT 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, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file ports/ARM7-AT91SAM7X/pal_lld.h
+ * @brief AT91SAM7X PIO low level driver header
+ * @addtogroup AT91SAM7X_PAL
+ * @{
+ */
+
+#ifndef _PAL_LLD_H_
+#define _PAL_LLD_H_
+
+#include "at91lib/AT91SAM7X256.h"
+
+/*===========================================================================*/
+/* Unsupported modes and specific modes */
+/*===========================================================================*/
+
+#undef PAL_MODE_INPUT_PULLDOWN
+
+/*===========================================================================*/
+/* I/O Ports Types and constants. */
+/*===========================================================================*/
+
+/**
+ * @brief PIO port setup info.
+ */
+typedef struct {
+ /** Initial value for ODSR register (data).*/
+ uint32_t odsr;
+ /** Initial value for OSR register (direction).*/
+ uint32_t osr;
+ /** Initial value for PUSR register (Pull-ups).*/
+ uint32_t pusr;
+} at91sam7x_pio_setup_t;
+
+/**
+ * @brief AT91SAM7X PIO static initializer.
+ * @details An instance of this structure must be passed to @p palInit() at
+ * system startup time in order to initialized the digital I/O
+ * subsystem. This represents only the initial setup, specific pads
+ * or whole ports can be reprogrammed at later time.
+ */
+typedef struct {
+ /** @brief Port 0 setup data.*/
+ at91sam7x_pio_setup_t P0Data;
+ /** @brief Port 1 setup data.*/
+ at91sam7x_pio_setup_t P1Data;
+} AT91SAM7XPIOConfig;
+
+/**
+ * @brief Width, in bits, of an I/O port.
+ */
+#define PAL_IOPORTS_WIDTH 32
+
+/**
+ * @brief Digital I/O port sized unsigned type.
+ */
+typedef uint32_t ioportmask_t;
+
+/**
+ * @brief Port Identifier.
+ * @details This type can be a scalar or some kind of pointer, do not make
+ * any assumption about it, use the provided macros when populating
+ * variables of this type.
+ */
+typedef AT91PS_PIO ioportid_t;
+
+/*===========================================================================*/
+/* I/O Ports Identifiers. */
+/*===========================================================================*/
+
+/**
+ * @brief PIO port A identifier.
+ */
+#define IOPORT_A AT91C_BASE_PIOA
+
+/**
+ * @brief PIO port B identifier.
+ */
+#define IOPORT_B AT91C_BASE_PIOB
+
+/*===========================================================================*/
+/* Implementation, some of the following macros could be implemented as */
+/* functions, if so please put them in a file named pal_lld.c. */
+/*===========================================================================*/
+
+/**
+ * @brief Low level PAL subsystem initialization.
+ */
+#define pal_lld_init(config) _pal_lld_init(config)
+
+/**
+ * @brief Reads the physical I/O port states.
+ * @details This function is implemented by reading the PIO_PDSR register, the
+ * implementation has no side effects.
+ *
+ * @param[in] port the port identifier
+ * @return The port bits.
+ *
+ * @note This function is not meant to be invoked directly by the application
+ * code.
+ */
+#define pal_lld_readport(port) ((port)->PIO_PDSR)
+
+/**
+ * @brief Reads the output latch.
+ * @details This function is implemented by reading the PIO_ODSR register, the
+ * implementation has no side effects.
+ *
+ * @param[in] port the port identifier
+ * @return The latched logical states.
+ *
+ * @note This function is not meant to be invoked directly by the application
+ * code.
+ */
+#define pal_lld_readlatch(port) ((port)->PIO_ODSR)
+
+/**
+ * @brief Writes a bits mask on a I/O port.
+ * @details This function is implemented by writing the PIO_ODSR register, the
+ * implementation has no side effects.
+ *
+ * @param[in] port the port identifier
+ * @param[in] bits the bits to be written on the specified port
+ *
+ * @note This function is not meant to be invoked directly by the application
+ * code.
+ */
+#define pal_lld_writeport(port, bits) { \
+ (port)->PIO_ODSR = (bits); \
+}
+
+/**
+ * @brief Sets a bits mask on a I/O port.
+ * @details This function is implemented by writing the PIO_SODR register, the
+ * implementation has no side effects.
+ *
+ * @param[in] port the port identifier
+ * @param[in] bits the bits to be ORed on the specified port
+ *
+ * @note This function is not meant to be invoked directly by the application
+ * code.
+ */
+#define pal_lld_setport(port, bits) { \
+ (port)->PIO_SODR = (bits); \
+}
+
+
+/**
+ * @brief Clears a bits mask on a I/O port.
+ * @details This function is implemented by writing the PIO_CODR register, the
+ * implementation has no side effects.
+ *
+ * @param[in] port the port identifier
+ * @param[in] bits the bits to be cleared on the specified port
+ *
+ * @note This function is not meant to be invoked directly by the application
+ * code.
+ */
+#define pal_lld_clearport(port, bits) { \
+ (port)->PIO_CODR = (bits); \
+}
+
+/**
+ * @brief Writes a group of bits.
+ * @details This function is implemented by writing the PIO_OWER, PIO_ODSR and
+ * PIO_OWDR registers, the implementation is not atomic because the
+ * multiple accesses.
+ *
+ * @param[in] port the port identifier
+ * @param[in] mask the group mask
+ * @param[in] offset the group bit offset within the port
+ * @param[in] bits the bits to be written. Values exceeding the group width
+ * are masked.
+ *
+ * @note This function is not meant to be invoked directly by the application
+ * code.
+ */
+#define pal_lld_writegroup(port, mask, offset, bits) { \
+ (port)->PIO_OWER = (mask) << (offset); \
+ (port)->PIO_ODSR = (bits) << (offset); \
+ (port)->PIO_OWDR = (mask) << (offset); \
+}
+
+/**
+ * @brief Pads group mode setup.
+ * @details This function programs a pads group belonging to the same port
+ * with the specified mode.
+ *
+ * @param[in] port the port identifier
+ * @param[in] mask the group mask
+ * @param[in] mode the mode
+ *
+ * @note This function is not meant to be invoked directly by the application
+ * code.
+ * @note @p PAL_MODE_UNCONNECTED is implemented as push pull output with high
+ * state.
+ */
+#define pal_lld_setgroupmode(port, mask, mode) \
+ _pal_lld_setgroupmode(port, mask, mode)
+
+/**
+ * @brief Writes a logical state on an output pad.
+ *
+ * @param[in] port the port identifier
+ * @param[in] pad the pad number within the port
+ * @param[out] bit the logical value, the value must be @p 0 or @p 1
+ *
+ * @note This function is not meant to be invoked directly by the application
+ * code.
+ */
+#define pal_lld_writepad(port, pad, bit) pal_lld_writegroup(port, 1, pad, bit)
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void _pal_lld_init(const AT91SAM7XPIOConfig *config);
+ void _pal_lld_setgroupmode(ioportid_t port,
+ ioportmask_t mask,
+ uint_fast8_t mode);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _PAL_LLD_H_ */
+
+/** @} */
diff --git a/os/ports/GCC/ARM7/AT91SAM7X/port.dox b/os/ports/GCC/ARM7/AT91SAM7X/port.dox
new file mode 100644
index 000000000..dac6ed181
--- /dev/null
+++ b/os/ports/GCC/ARM7/AT91SAM7X/port.dox
@@ -0,0 +1,73 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT 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 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT 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, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @defgroup AT91SAM7X AT91SAM7X Support
+ * @brief AT91SAM7X specific support.
+ * @details The AT91SAM7X support includes:
+ * - Buffered, interrupt driven, serial driver.
+ * - EMAC driver with MII support.
+ * - A demo supporting the kernel test suite.
+ * - A Web server demo using the uIP TCP/IP stack.
+ * .
+ * @ingroup ARM7
+ */
+
+/**
+ * @defgroup AT91SAM7X_PAL I/O Ports Support
+ * @brief I/O Ports peripherals support.
+ * @details This module supports the AT91SAM7X PIO controller. The controller
+ * supports the following features (see @ref PAL):
+ * - 32 bits wide ports.
+ * - Atomic set/reset functions.
+ * - Output latched regardless of the pad setting.
+ * - Direct read of input pads regardless of the pad setting.
+ * .
+ * <h2>Supported Setup Modes</h2>
+ * - @p PAL_MODE_RESET.
+ * - @p PAL_MODE_UNCONNECTED.
+ * - @p PAL_MODE_INPUT.
+ * - @p PAL_MODE_INPUT_PULLUP.
+ * - @p PAL_MODE_OUTPUT_PUSHPULL.
+ * - @p PAL_MODE_OUTPUT_OPENDRAIN.
+ * .
+ * Any attempt to setup an invalid mode is ignored.
+ *
+ * <h2>Suboptimal Behavior</h2>
+ * Some PIO features are less than optimal:
+ * - Pad/port toggling operations are not atomic.
+ * - Pad/group mode setup is not atomic.
+ * .
+ * @ingroup AT91SAM7X
+ */
+
+/**
+ * @defgroup AT91SAM7X_SERIAL USART Support
+ * @brief USART peripherals support.
+ * @details The serial driver supports the AT91SAM7X USART peripherals.
+ *
+ * @ingroup AT91SAM7X
+ */
+
+/**
+ * @defgroup AT91SAM7X_EMAC EMAC Support
+ * @brief EMAC peripheral support.
+ *
+ * @ingroup AT91SAM7X
+ */
diff --git a/os/ports/GCC/ARM7/AT91SAM7X/sam7x_emac.c b/os/ports/GCC/ARM7/AT91SAM7X/sam7x_emac.c
new file mode 100644
index 000000000..b0db11dca
--- /dev/null
+++ b/os/ports/GCC/ARM7/AT91SAM7X/sam7x_emac.c
@@ -0,0 +1,418 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT 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 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT 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, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file ports/ARM7-AT91SAM7X/sam7x_emac.c
+ * @brief AT91SAM7X EMAC driver code.
+ * @addtogroup AT91SAM7X_EMAC
+ * @{
+ */
+
+#include <string.h>
+
+#include <ch.h>
+
+#include "board.h"
+#include "sam7x_emac.h"
+#include "mii.h"
+#include "at91lib/aic.h"
+
+EventSource EMACFrameTransmitted; /* A frame was transmitted. */
+EventSource EMACFrameReceived; /* A frame was received. */
+
+#ifndef __DOXYGEN__
+//static int received; /* Buffered frames counter. */
+static bool_t link_up; /* Last from EMACGetLinkStatus()*/
+
+static uint8_t default_mac[] = {0xAA, 0x55, 0x13, 0x37, 0x01, 0x10};
+
+static BufDescriptorEntry rent[EMAC_RECEIVE_BUFFERS] __attribute__((aligned(8)));
+static uint8_t rbuffers[EMAC_RECEIVE_BUFFERS * EMAC_RECEIVE_BUFFERS_SIZE] __attribute__((aligned(8)));
+static BufDescriptorEntry *rxptr;
+
+static BufDescriptorEntry tent[EMAC_TRANSMIT_BUFFERS] __attribute__((aligned(8)));
+static uint8_t tbuffers[EMAC_TRANSMIT_BUFFERS * EMAC_TRANSMIT_BUFFERS_SIZE] __attribute__((aligned(8)));
+static BufDescriptorEntry *txptr;
+#endif
+
+#define AT91C_PB15_ERXDV AT91C_PB15_ERXDV_ECRSDV
+#define EMAC_PIN_MASK (AT91C_PB0_ETXCK_EREFCK | \
+ AT91C_PB1_ETXEN | AT91C_PB2_ETX0 | \
+ AT91C_PB3_ETX1 | AT91C_PB4_ECRS | \
+ AT91C_PB5_ERX0 | AT91C_PB6_ERX1 | \
+ AT91C_PB7_ERXER | AT91C_PB8_EMDC | \
+ AT91C_PB9_EMDIO | AT91C_PB10_ETX2 | \
+ AT91C_PB11_ETX3 | AT91C_PB12_ETXER | \
+ AT91C_PB13_ERX2 | AT91C_PB14_ERX3 | \
+ AT91C_PB15_ERXDV | AT91C_PB16_ECOL | \
+ AT91C_PB17_ERXCK)
+
+#define PHY_LATCHED_PINS (AT91C_PB4_ECRS | AT91C_PB5_ERX0 | AT91C_PB6_ERX1 | \
+ AT91C_PB7_ERXER | AT91C_PB13_ERX2 | AT91C_PB14_ERX3 | \
+ AT91C_PB15_ERXDV | AT91C_PB16_ECOL | PIOB_PHY_IRQ_MASK)
+
+/*
+ * PHY utilities.
+ */
+static uint32_t phy_get(uint8_t regno) {
+
+ AT91C_BASE_EMAC->EMAC_MAN = (1 << 30) | // SOF = 01
+ (2 << 28) | // RW = 10
+ (PHY_ADDRESS << 23) |
+ (regno << 18) |
+ (2 << 16); // CODE = 10
+ while (!( AT91C_BASE_EMAC->EMAC_NSR & AT91C_EMAC_IDLE))
+ ;
+ return AT91C_BASE_EMAC->EMAC_MAN & 0xFFFF;
+}
+
+/*static void phy_put(uint8_t regno, uint32_t val) {
+
+ AT91C_BASE_EMAC->EMAC_MAN = (1 << 30) | // SOF = 01
+ (1 << 28) | // RW = 01
+ (PHY_ADDRESS << 23) |
+ (regno << 18) |
+ (2 << 16) | // CODE = 10
+ val;
+ while (!( AT91C_BASE_EMAC->EMAC_NSR & AT91C_EMAC_IDLE))
+ ;
+}*/
+
+#define RSR_BITS (AT91C_EMAC_BNA | AT91C_EMAC_REC | AT91C_EMAC_OVR)
+#define TSR_BITS (AT91C_EMAC_UBR | AT91C_EMAC_COL | AT91C_EMAC_RLES | \
+ AT91C_EMAC_BEX | AT91C_EMAC_COMP | AT91C_EMAC_UND)
+
+__attribute__((noinline))
+static void ServeInterrupt(void) {
+ uint32_t isr, rsr, tsr;
+
+ /* Fix for the EMAC errata */
+ isr = AT91C_BASE_EMAC->EMAC_ISR;
+ rsr = AT91C_BASE_EMAC->EMAC_RSR;
+ tsr = AT91C_BASE_EMAC->EMAC_TSR;
+
+ if ((isr & AT91C_EMAC_RCOMP) || (rsr & RSR_BITS)) {
+ if (rsr & AT91C_EMAC_REC) {
+// received++;
+ chSysLockFromIsr();
+ chEvtBroadcastI(&EMACFrameReceived);
+ chSysUnlockFromIsr();
+ }
+ AT91C_BASE_EMAC->EMAC_RSR = RSR_BITS;
+ }
+
+ if ((isr & AT91C_EMAC_TCOMP) || (tsr & TSR_BITS)) {
+ if (tsr & AT91C_EMAC_COMP) {
+ chSysLockFromIsr();
+ chEvtBroadcastI(&EMACFrameTransmitted);
+ chSysUnlockFromIsr();
+ }
+ AT91C_BASE_EMAC->EMAC_TSR = TSR_BITS;
+ }
+ AT91C_BASE_AIC->AIC_EOICR = 0;
+}
+
+CH_IRQ_HANDLER(EMACIrqHandler) {
+
+ CH_IRQ_PROLOGUE();
+
+ ServeInterrupt();
+
+ CH_IRQ_EPILOGUE();
+}
+
+/*
+ * EMAC subsystem initialization.
+ */
+void emac_init(int prio) {
+ int i;
+
+ /*
+ * Buffers initialization.
+ */
+// received = 0;
+ for (i = 0; i < EMAC_RECEIVE_BUFFERS; i++) {
+ rent[i].w1 = (uint32_t)&rbuffers[i * EMAC_RECEIVE_BUFFERS_SIZE];
+ rent[i].w2 = 0;
+ }
+ rent[EMAC_RECEIVE_BUFFERS - 1].w1 |= W1_R_WRAP;
+ rxptr = rent;
+ for (i = 0; i < EMAC_TRANSMIT_BUFFERS; i++) {
+ tent[i].w1 = (uint32_t)&tbuffers[i * EMAC_TRANSMIT_BUFFERS_SIZE];
+ tent[i].w2 = EMAC_TRANSMIT_BUFFERS_SIZE | W2_T_USED;
+ }
+ tent[EMAC_TRANSMIT_BUFFERS - 1].w2 |= W2_T_WRAP;
+ txptr = tent;
+
+ /*
+ * Disables the pullups on all the pins that are latched on reset by the PHY.
+ * The status latched into the PHY is:
+ * PHYADDR = 00001
+ * PCS_LPBK = 0 (disabled)
+ * ISOLATE = 0 (disabled)
+ * RMIISEL = 0 (MII mode)
+ * RMIIBTB = 0 (BTB mode disabled)
+ * SPEED = 1 (100mbps)
+ * DUPLEX = 1 (full duplex)
+ * ANEG_EN = 1 (auto negotiation enabled)
+ */
+ AT91C_BASE_PIOB->PIO_PPUDR = PHY_LATCHED_PINS;
+
+ /*
+ * PHY power control.
+ */
+ AT91C_BASE_PIOB->PIO_OER = PIOB_PHY_PD_MASK; // Becomes an output.
+ AT91C_BASE_PIOB->PIO_PPUDR = PIOB_PHY_PD_MASK; // Default pullup disabled.
+ AT91C_BASE_PIOB->PIO_SODR = PIOB_PHY_PD_MASK; // Output to high level.
+
+ /*
+ * PHY reset by pulsing the NRST pin.
+ */
+ AT91C_BASE_RSTC->RSTC_RMR = 0xA5000100;
+ AT91C_BASE_RSTC->RSTC_RCR = 0xA5000000 | AT91C_RSTC_EXTRST;
+ while (!(AT91C_BASE_RSTC->RSTC_RSR & AT91C_RSTC_NRSTL))
+ ;
+
+ /*
+ * EMAC pins setup and clock enable. Note, PB18 is not included because it is
+ * used as #PD control and not as EF100.
+ */
+ AT91C_BASE_PMC->PMC_PCER = 1 << AT91C_ID_EMAC;
+ AT91C_BASE_PIOB->PIO_ASR = EMAC_PIN_MASK;
+ AT91C_BASE_PIOB->PIO_PDR = EMAC_PIN_MASK;
+ AT91C_BASE_PIOB->PIO_PPUDR = EMAC_PIN_MASK;
+
+ /*
+ * EMAC setup.
+ */
+ AT91C_BASE_EMAC->EMAC_NCR = 0; // Initial setting.
+ AT91C_BASE_EMAC->EMAC_NCFGR = 2 << 10; // MDC-CLK = MCK / 32
+ AT91C_BASE_EMAC->EMAC_USRIO = AT91C_EMAC_CLKEN; // Enable EMAC in MII mode
+ AT91C_BASE_EMAC->EMAC_RBQP = (AT91_REG)rent; // RX buffers list
+ AT91C_BASE_EMAC->EMAC_TBQP = (AT91_REG)tent; // TX buffers list
+ AT91C_BASE_EMAC->EMAC_RSR = AT91C_EMAC_OVR |
+ AT91C_EMAC_REC |
+ AT91C_EMAC_BNA; // Clears RSR
+ AT91C_BASE_EMAC->EMAC_NCFGR |= AT91C_EMAC_DRFCS; // Initial NCFGR settings
+ AT91C_BASE_EMAC->EMAC_NCR |= AT91C_EMAC_TE |
+ AT91C_EMAC_RE |
+ AT91C_EMAC_CLRSTAT; // Initial NCR settings
+ EMACSetAddress(default_mac);
+
+ /*
+ * PHY detection and settings.
+ */
+ AT91C_BASE_EMAC->EMAC_NCR |= AT91C_EMAC_MPE;
+ if ((phy_get(MII_PHYSID1) != (MII_MICREL_ID >> 16)) ||
+ ((phy_get(MII_PHYSID2) & 0xFFF0) != (MII_MICREL_ID & 0xFFF0)))
+ chSysHalt();
+
+ /*
+ * Waits for auto-negotiation to end and then detects the link status.
+ */
+ AT91C_BASE_EMAC->EMAC_NCR &= ~AT91C_EMAC_MPE;
+
+ /*
+ * Interrupt setup.
+ */
+ AT91C_BASE_EMAC->EMAC_IER = AT91C_EMAC_RCOMP | AT91C_EMAC_TCOMP;
+ AIC_ConfigureIT(AT91C_ID_EMAC,
+ AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL | prio,
+ EMACIrqHandler);
+ AIC_EnableIT(AT91C_ID_EMAC);
+
+ /*
+ * Event sources setup.
+ */
+ chEvtInit(&EMACFrameTransmitted);
+ chEvtInit(&EMACFrameReceived);
+}
+
+/*
+ * Set the MAC address.
+ */
+void EMACSetAddress(const uint8_t *eaddr) {
+
+ AT91C_BASE_EMAC->EMAC_SA1L = (AT91_REG)((eaddr[3] << 24) | (eaddr[2] << 16) |
+ (eaddr[1] << 8) | eaddr[0]);
+ AT91C_BASE_EMAC->EMAC_SA1H = (AT91_REG)((eaddr[5] << 8) | eaddr[4]);
+}
+
+/*
+ * Returns TRUE if the link is active. To be invoked at regular intervals in
+ * order to monitor the link.
+ * @note It is not thread-safe.
+ */
+bool_t EMACGetLinkStatus(void) {
+ uint32_t ncfgr, bmsr, bmcr, lpa;
+
+ AT91C_BASE_EMAC->EMAC_NCR |= AT91C_EMAC_MPE;
+ (void)phy_get(MII_BMSR);
+ bmsr = phy_get(MII_BMSR);
+ if (!(bmsr & BMSR_LSTATUS)) {
+ AT91C_BASE_EMAC->EMAC_NCR &= ~AT91C_EMAC_MPE;
+ return link_up = FALSE;
+ }
+
+ ncfgr = AT91C_BASE_EMAC->EMAC_NCFGR & ~(AT91C_EMAC_SPD | AT91C_EMAC_FD);
+ bmcr = phy_get(MII_BMCR);
+ if (bmcr & BMCR_ANENABLE) {
+ lpa = phy_get(MII_LPA);
+ if (lpa & (LPA_100HALF | LPA_100FULL | LPA_100BASE4))
+ ncfgr |= AT91C_EMAC_SPD;
+ if (lpa & (LPA_10FULL | LPA_100FULL))
+ ncfgr |= AT91C_EMAC_FD;
+ }
+ else {
+ if (bmcr & BMCR_SPEED100)
+ ncfgr |= AT91C_EMAC_SPD;
+ if (bmcr & BMCR_FULLDPLX)
+ ncfgr |= AT91C_EMAC_FD;
+ }
+ AT91C_BASE_EMAC->EMAC_NCFGR = ncfgr;
+ AT91C_BASE_EMAC->EMAC_NCR &= ~AT91C_EMAC_MPE;
+ return link_up = TRUE;
+}
+
+/*
+ * Allocates and locks a buffer for a transmission operation.
+ */
+BufDescriptorEntry *EMACGetTransmitBuffer(void) {
+ BufDescriptorEntry *cptr;
+
+ if (!link_up)
+ return NULL;
+
+ chSysLock();
+ cptr = txptr;
+ if (!(cptr->w2 & W2_T_USED) ||
+ (cptr->w2 & W2_T_LOCKED)) {
+ chSysUnlock();
+ return FALSE;
+ }
+ cptr->w2 |= W2_T_LOCKED; /* Locks the buffer while copying.*/
+ if (++txptr >= &tent[EMAC_TRANSMIT_BUFFERS])
+ txptr = tent;
+ chSysUnlock();
+ return cptr;
+}
+
+/*
+ * Transmits a previously allocated buffer and then releases it.
+ */
+void EMACTransmit(BufDescriptorEntry *cptr, size_t size) {
+
+ chDbgAssert(size <= EMAC_TRANSMIT_BUFFERS_SIZE,
+ "EMACTransmit(), #1",
+ "unexpected size");
+
+ chSysLock();
+ if (cptr < &tent[EMAC_TRANSMIT_BUFFERS - 1])
+ cptr->w2 = size | W2_T_LAST_BUFFER;
+ else
+ cptr->w2 = size | W2_T_LAST_BUFFER | W2_T_WRAP;
+ AT91C_BASE_EMAC->EMAC_NCR |= AT91C_EMAC_TSTART;
+ chSysUnlock();
+}
+
+/*
+ * Reads a buffered frame.
+ * Returns TRUE if a frame was present and read else FALSE.
+ * @note It is not thread-safe.
+ */
+bool_t EMACReceive(uint8_t *buf, size_t *sizep) {
+ unsigned n;
+ size_t size;
+ uint8_t *p;
+ bool_t overflow, found;
+
+// chSysLock();
+// if (received <= 0) {
+// chSysUnlock();
+// return FALSE;
+// }
+// received--;
+// chSysUnlock();
+
+ n = EMAC_RECEIVE_BUFFERS;
+
+ /*
+ * Skips unused buffers, if any.
+ */
+skip:
+ while (n && !(rxptr->w1 & W1_R_OWNERSHIP)) {
+ if (++rxptr >= &rent[EMAC_RECEIVE_BUFFERS])
+ rxptr = rent;
+ n--;
+ }
+
+ /*
+ * Skips fragments, if any.
+ */
+ while (n && (rxptr->w1 & W1_R_OWNERSHIP) && !(rxptr->w2 & W2_R_FRAME_START)) {
+ rxptr->w1 &= ~W1_R_OWNERSHIP;
+ if (++rxptr >= &rent[EMAC_RECEIVE_BUFFERS])
+ rxptr = rent;
+ n--;
+ }
+
+restart:
+ p = buf;
+ size = 0;
+ found = overflow = FALSE;
+ while (n && !found) {
+ size_t segsize;
+
+ if (!(rxptr->w1 & W1_R_OWNERSHIP))
+ goto skip; /* Empty buffer for some reason... */
+
+ if (size && (rxptr->w2 & W2_R_FRAME_START))
+ goto restart; /* Another start buffer for some reason... */
+
+ if (rxptr->w2 & W2_R_FRAME_END) {
+ segsize = (rxptr->w2 & W2_T_LENGTH_MASK) - size;
+ if (((rxptr->w2 & W2_T_LENGTH_MASK) > *sizep) ||
+ (segsize > EMAC_RECEIVE_BUFFERS_SIZE))
+ overflow = TRUE;
+ found = TRUE;
+ }
+ else {
+ segsize = EMAC_RECEIVE_BUFFERS_SIZE;
+ if (size + segsize > *sizep)
+ overflow = TRUE;
+ }
+
+ if (!overflow) {
+ chDbgAssert(segsize <= 128, "EMACReceive(), #1", "");
+ memcpy(p, (void *)(rxptr->w1 & W1_R_ADDRESS_MASK), segsize);
+ p += segsize;
+ size += segsize;
+ }
+
+ rxptr->w1 &= ~W1_R_OWNERSHIP;
+ if (++rxptr >= &rent[EMAC_RECEIVE_BUFFERS])
+ rxptr = rent;
+ n--;
+ }
+
+ *sizep = size;
+ return found && !overflow;
+}
+
+/** @} */
diff --git a/os/ports/GCC/ARM7/AT91SAM7X/sam7x_emac.h b/os/ports/GCC/ARM7/AT91SAM7X/sam7x_emac.h
new file mode 100644
index 000000000..d666ea6ef
--- /dev/null
+++ b/os/ports/GCC/ARM7/AT91SAM7X/sam7x_emac.h
@@ -0,0 +1,93 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT 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 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT 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, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file ports/ARM7-AT91SAM7X/sam7x_emac.h
+ * @brief AT91SAM7X EMAC driver macros and structures.
+ * @addtogroup AT91SAM7X_EMAC
+ * @{
+ */
+
+#ifndef _SAM7X_EMAC_H_
+#define _SAM7X_EMAC_H_
+
+#define PHY_ADDRESS 1
+
+#define EMAC_RECEIVE_BUFFERS 24
+#define EMAC_RECEIVE_BUFFERS_SIZE 128
+#define EMAC_TRANSMIT_BUFFERS 2
+#define EMAC_TRANSMIT_BUFFERS_SIZE 1518
+
+typedef struct {
+ uint32_t w1;
+ uint32_t w2;
+} BufDescriptorEntry;
+
+#define W1_R_OWNERSHIP 0x00000001
+#define W1_R_WRAP 0x00000002
+#define W1_R_ADDRESS_MASK 0xFFFFFFFC
+
+#define W2_R_LENGTH_MASK 0x00000FFF
+#define W2_R_FRAME_START 0x00004000
+#define W2_R_FRAME_END 0x00008000
+#define W2_R_CFI 0x00010000
+#define W2_R_VLAN_PRIO_MASK 0x000E0000
+#define W2_R_PRIO_TAG_DETECTED 0x00100000
+#define W2_R_VLAN_TAG_DETECTED 0x00200000
+#define W2_R_TYPE_ID_MATCH 0x00400000
+#define W2_R_ADDR4_MATCH 0x00800000
+#define W2_R_ADDR3_MATCH 0x01000000
+#define W2_R_ADDR2_MATCH 0x02000000
+#define W2_R_ADDR1_MATCH 0x04000000
+#define W2_R_RFU1 0x08000000
+#define W2_R_ADDR_EXT_MATCH 0x10000000
+#define W2_R_UNICAST_MATCH 0x20000000
+#define W2_R_MULTICAST_MATCH 0x40000000
+#define W2_R_BROADCAST_DETECTED 0x80000000
+
+#define W2_T_LENGTH_MASK 0x000007FF
+#define W2_T_LOCKED 0x00000800 /* Not an EMAC flag, used by the driver */
+#define W2_T_RFU1 0x00003000
+#define W2_T_LAST_BUFFER 0x00008000
+#define W2_T_NO_CRC 0x00010000
+#define W2_T_RFU2 0x07FE0000
+#define W2_T_BUFFERS_EXHAUSTED 0x08000000
+#define W2_T_TRANSMIT_UNDERRUN 0x10000000
+#define W2_T_RETRY_LIMIT_EXC 0x20000000
+#define W2_T_WRAP 0x40000000
+#define W2_T_USED 0x80000000
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void emac_init(int prio);
+ void EMACSetAddress(const uint8_t *eaddr);
+ bool_t EMACGetLinkStatus(void);
+ BufDescriptorEntry *EMACGetTransmitBuffer(void);
+ void EMACTransmit(BufDescriptorEntry *cptr, size_t size);
+ bool_t EMACReceive(uint8_t *buf, size_t *sizep);
+#ifdef __cplusplus
+}
+#endif
+
+extern EventSource EMACFrameTransmitted, EMACFrameReceived;
+
+#endif /* _SAM7X_EMAC_H_ */
+
+/** @} */
diff --git a/os/ports/GCC/ARM7/AT91SAM7X/sam7x_serial.c b/os/ports/GCC/ARM7/AT91SAM7X/sam7x_serial.c
new file mode 100644
index 000000000..91aaf2f0e
--- /dev/null
+++ b/os/ports/GCC/ARM7/AT91SAM7X/sam7x_serial.c
@@ -0,0 +1,224 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT 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 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT 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, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file ports/ARM7-AT91SAM7X/sam7x_serial.c
+ * @brief AT91SAM7X Serial driver code.
+ * @addtogroup AT91SAM7X_SERIAL
+ * @{
+ */
+
+#include <ch.h>
+
+#include "board.h"
+#include "sam7x_serial.h"
+#include "at91lib/aic.h"
+
+#if USE_SAM7X_USART0 || defined(__DOXYGEN__)
+/** @brief USART0 serial driver identifier.*/
+FullDuplexDriver COM1;
+
+static uint8_t ib1[SERIAL_BUFFERS_SIZE];
+static uint8_t ob1[SERIAL_BUFFERS_SIZE];
+#endif
+
+#if USE_SAM7X_USART1 || defined(__DOXYGEN__)
+/** @brief USART1 serial driver identifier.*/
+FullDuplexDriver COM2;
+
+static uint8_t ib2[SERIAL_BUFFERS_SIZE];
+static uint8_t ob2[SERIAL_BUFFERS_SIZE];
+#endif
+
+static void SetError(AT91_REG csr, FullDuplexDriver *com) {
+ dflags_t sts = 0;
+
+ if (csr & AT91C_US_OVRE)
+ sts |= SD_OVERRUN_ERROR;
+ if (csr & AT91C_US_PARE)
+ sts |= SD_PARITY_ERROR;
+ if (csr & AT91C_US_FRAME)
+ sts |= SD_FRAMING_ERROR;
+ if (csr & AT91C_US_RXBRK)
+ sts |= SD_BREAK_DETECTED;
+ chSysLockFromIsr();
+ chFDDAddFlagsI(com, sts);
+ chSysUnlockFromIsr();
+}
+
+/** @cond never*/
+__attribute__((noinline))
+/** @endcond*/
+/**
+ * @brief Common IRQ handler.
+ * @param[in] u pointer to an USART I/O block
+ * @param[in] com communication channel associated to the USART
+ */
+static void ServeInterrupt(AT91PS_USART u, FullDuplexDriver *com) {
+
+ if (u->US_CSR & AT91C_US_RXRDY) {
+ chSysLockFromIsr();
+ chFDDIncomingDataI(com, u->US_RHR);
+ chSysUnlockFromIsr();
+ }
+ if (u->US_CSR & AT91C_US_TXRDY) {
+ chSysLockFromIsr();
+ msg_t b = chFDDRequestDataI(com);
+ chSysUnlockFromIsr();
+ if (b < Q_OK)
+ u->US_IDR = AT91C_US_TXRDY;
+ else
+ u->US_THR = b;
+ }
+ if (u->US_CSR & (AT91C_US_OVRE | AT91C_US_FRAME | AT91C_US_PARE | AT91C_US_RXBRK)) {
+ SetError(u->US_CSR, com);
+ u->US_CR = AT91C_US_RSTSTA;
+ }
+ AT91C_BASE_AIC->AIC_EOICR = 0;
+}
+
+#if USE_SAM7X_USART0 || defined(__DOXYGEN__)
+CH_IRQ_HANDLER(USART0IrqHandler) {
+
+ CH_IRQ_PROLOGUE();
+
+ ServeInterrupt(AT91C_BASE_US0, &COM1);
+
+ CH_IRQ_EPILOGUE();
+}
+
+static void OutNotify1(void) {
+
+ AT91C_BASE_US0->US_IER = AT91C_US_TXRDY;
+}
+#endif
+
+#if USE_SAM7X_USART1 || defined(__DOXYGEN__)
+CH_IRQ_HANDLER(USART1IrqHandler) {
+
+ CH_IRQ_PROLOGUE();
+
+ ServeInterrupt(AT91C_BASE_US1, &COM2);
+
+ CH_IRQ_EPILOGUE();
+}
+
+static void OutNotify2(void) {
+
+ AT91C_BASE_US1->US_IER = AT91C_US_TXRDY;
+}
+#endif
+
+/**
+ * @brief USART setup.
+ * @param[in] u pointer to an UART I/O block
+ * @param[in] speed serial port speed in bits per second
+ * @param[in] mr the value for the @p MR register
+ * @note Must be invoked with interrupts disabled.
+ * @note Does not reset the I/O queues.
+ */
+void usart_setup(AT91PS_USART u, int speed, int mr) {
+
+ /* Disables IRQ sources and stop operations.*/
+ u->US_IDR = 0xFFFFFFFF;
+ u->US_CR = AT91C_US_RSTRX | AT91C_US_RSTTX | AT91C_US_RSTSTA;
+
+ /* New parameters setup.*/
+ if (mr & AT91C_US_OVER)
+ u->US_BRGR = MCK / (speed * 8);
+ else
+ u->US_BRGR = MCK / (speed * 16);
+ u->US_MR = mr;
+ u->US_RTOR = 0;
+ u->US_TTGR = 0;
+
+ /* Enables operations and IRQ sources.*/
+ u->US_CR = AT91C_US_RXEN | AT91C_US_TXEN | AT91C_US_DTREN | AT91C_US_RTSEN;
+ u->US_IER = AT91C_US_RXRDY | AT91C_US_OVRE | AT91C_US_FRAME | AT91C_US_PARE |
+ AT91C_US_RXBRK;
+}
+
+/**
+ * @brief Serial driver initialization.
+ * @param[in] prio0 priority to be assigned to the USART1 IRQ
+ * @param[in] prio1 priority to be assigned to the USART2 IRQ
+ * @note Handshake pads are not enabled inside this function because they
+ * may have another use, enable them externally if needed.
+ * RX and TX pads are handled inside.
+ */
+void serial_init(int prio0, int prio1) {
+
+#if USE_SAM7X_USART0 || defined(__DOXYGEN__)
+ /* I/O queue setup.*/
+ chFDDInit(&COM1, ib1, sizeof ib1, NULL, ob1, sizeof ob1, OutNotify1);
+
+ /* Switches the I/O pins to the peripheral function A, disables pullups.*/
+ AT91C_BASE_PIOA->PIO_PDR = AT91C_PA0_RXD0 | AT91C_PA1_TXD0;
+ AT91C_BASE_PIOA->PIO_ASR = AT91C_PIO_PA0 | AT91C_PIO_PA1;
+ AT91C_BASE_PIOA->PIO_PPUDR = AT91C_PIO_PA0 | AT91C_PIO_PA1;
+
+ /* Starts the clock and clears possible sources of immediate interrupts.*/
+ AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_US0);
+ AT91C_BASE_US0->US_CR = AT91C_US_RSTRX | AT91C_US_RSTTX | AT91C_US_RSTSTA;
+
+ /* Interrupts setup.*/
+ AIC_ConfigureIT(AT91C_ID_US0,
+ AT91C_AIC_SRCTYPE_HIGH_LEVEL | prio0,
+ USART0IrqHandler);
+ AIC_EnableIT(AT91C_ID_US0);
+
+ /* Default parameters.*/
+ usart_setup(AT91C_BASE_US0, DEFAULT_USART_BITRATE,
+ AT91C_US_USMODE_NORMAL |
+ AT91C_US_CLKS_CLOCK |
+ AT91C_US_CHRL_8_BITS |
+ AT91C_US_PAR_NONE |
+ AT91C_US_NBSTOP_1_BIT);
+#endif
+
+#if USE_SAM7X_USART1 || defined(__DOXYGEN__)
+ /* I/O queues setup.*/
+ chFDDInit(&COM2, ib2, sizeof ib2, NULL, ob2, sizeof ob2, OutNotify2);
+
+ /* Switches the I/O pins to the peripheral function A, disables pullups.*/
+ AT91C_BASE_PIOA->PIO_PDR = AT91C_PA5_RXD1 | AT91C_PA6_TXD1;
+ AT91C_BASE_PIOA->PIO_ASR = AT91C_PIO_PA5 | AT91C_PIO_PA6;
+ AT91C_BASE_PIOA->PIO_PPUDR = AT91C_PIO_PA5 | AT91C_PIO_PA6;
+
+ /* Starts the clock and clears possible sources of immediate interrupts.*/
+ AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_US1);
+ AT91C_BASE_US1->US_CR = AT91C_US_RSTRX | AT91C_US_RSTTX | AT91C_US_RSTSTA;
+
+ /* Interrupts setup.*/
+ AIC_ConfigureIT(AT91C_ID_US1,
+ AT91C_AIC_SRCTYPE_HIGH_LEVEL | prio1,
+ USART1IrqHandler);
+ AIC_EnableIT(AT91C_ID_US1);
+
+ /* Default parameters.*/
+ usart_setup(AT91C_BASE_US1, DEFAULT_USART_BITRATE,
+ AT91C_US_USMODE_NORMAL |
+ AT91C_US_CLKS_CLOCK |
+ AT91C_US_CHRL_8_BITS |
+ AT91C_US_PAR_NONE |
+ AT91C_US_NBSTOP_1_BIT);
+#endif
+}
+
+/** @} */
diff --git a/os/ports/GCC/ARM7/AT91SAM7X/sam7x_serial.h b/os/ports/GCC/ARM7/AT91SAM7X/sam7x_serial.h
new file mode 100644
index 000000000..1652ab69f
--- /dev/null
+++ b/os/ports/GCC/ARM7/AT91SAM7X/sam7x_serial.h
@@ -0,0 +1,86 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT 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 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT 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, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file ports/ARM7-AT91SAM7X/sam7x_serial.h
+ * @brief AT91SAM7X Serial driver macros and structures.
+ * @addtogroup AT91SAM7X_SERIAL
+ * @{
+ */
+
+#ifndef _SAM7X_SERIAL_H_
+#define _SAM7X_SERIAL_H_
+
+/**
+ * @brief Serial buffers size.
+ * @details Configuration parameter, you can change the depth of the queue
+ * buffers depending on the requirements of your application.
+ * @note The default is 128 bytes for both the transmission and receive buffers.
+ */
+#if !defined(SERIAL_BUFFERS_SIZE) || defined(__DOXYGEN__)
+#define SERIAL_BUFFERS_SIZE 128
+#endif
+
+/**
+ * @brief Default bit rate.
+ * @details Configuration parameter, at startup the UARTs are configured at
+ * this speed.
+ * @note It is possible to use @p SetUART() in order to change the working
+ * parameters at runtime.
+ */
+#if !defined(DEFAULT_USART_BITRATE) || defined(__DOXYGEN__)
+#define DEFAULT_USART_BITRATE 38400
+#endif
+
+/**
+ * @brief UART0 driver enable switch.
+ * @details If set to @p TRUE the support for USART1 is included.
+ * @note The default is @p TRUE.
+ */
+#if !defined(USE_SAM7X_USART0) || defined(__DOXYGEN__)
+#define USE_SAM7X_USART0 TRUE
+#endif
+
+/**
+ * @brief UART1 driver enable switch.
+ * @details If set to @p TRUE the support for USART2 is included.
+ * @note The default is @p TRUE.
+ */
+#if !defined(USE_SAM7X_USART1) || defined(__DOXYGEN__)
+#define USE_SAM7X_USART1 TRUE
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void serial_init(int prio0, int prio1);
+ void usart_setup(AT91PS_USART u, int speed, int mr);
+ CH_IRQ_HANDLER(UART0IrqHandler);
+ CH_IRQ_HANDLER(UART1IrqHandler);
+#ifdef __cplusplus
+}
+#endif
+
+/** @cond never*/
+extern FullDuplexDriver COM1, COM2;
+/** @endcond*/
+
+#endif /* _SAM7X_SERIAL_H_ */
+
+/** @} */
diff --git a/os/ports/GCC/ARM7/AT91SAM7X/vectors.s b/os/ports/GCC/ARM7/AT91SAM7X/vectors.s
new file mode 100644
index 000000000..29271daf1
--- /dev/null
+++ b/os/ports/GCC/ARM7/AT91SAM7X/vectors.s
@@ -0,0 +1,74 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT 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 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT 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, see <http://www.gnu.org/licenses/>.
+*/
+
+.section vectors
+.code 32
+.balign 4
+/*
+ * System entry points.
+ */
+_start:
+ ldr pc, _reset
+ ldr pc, _undefined
+ ldr pc, _swi
+ ldr pc, _prefetch
+ ldr pc, _abort
+ nop
+ ldr pc, [pc,#-0xF20] /* AIC - AIC_IVR */
+ ldr pc, [pc,#-0xF20] /* AIC - AIC_FVR */
+
+_reset:
+ .word ResetHandler /* In crt0.s */
+_undefined:
+ .word UndHandler
+_swi:
+ .word SwiHandler
+_prefetch:
+ .word PrefetchHandler
+_abort:
+ .word AbortHandler
+ .word 0
+ .word 0
+ .word 0
+
+.text
+.code 32
+.balign 4
+
+/*
+ * Default exceptions handlers. The handlers are declared weak in order to be
+ * replaced by the real handling code. Everything is defaulted to an infinite
+ * loop.
+ */
+.weak UndHandler
+UndHandler:
+
+.weak SwiHandler
+SwiHandler:
+
+.weak PrefetchHandler
+PrefetchHandler:
+
+.weak AbortHandler
+AbortHandler:
+
+.weak FiqHandler
+FiqHandler:
+
+.loop: b .loop
diff --git a/os/ports/GCC/ARM7/AT91SAM7X/wfi.h b/os/ports/GCC/ARM7/AT91SAM7X/wfi.h
new file mode 100644
index 000000000..5e2da044d
--- /dev/null
+++ b/os/ports/GCC/ARM7/AT91SAM7X/wfi.h
@@ -0,0 +1,35 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT 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 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _WFI_H_
+#define _WFI_H_
+
+#include "at91lib/AT91SAM7X256.h"
+
+#ifndef port_wait_for_interrupt
+#if ENABLE_WFI_IDLE != 0
+#define port_wait_for_interrupt() { \
+ AT91C_BASE_SYS->PMC_SCDR = AT91C_PMC_PCK; \
+}
+#else
+#define port_wait_for_interrupt()
+#endif
+#endif
+
+#endif /* _WFI_H_ */
diff --git a/os/ports/GCC/ARM7/LPC214x/lpc214x.h b/os/ports/GCC/ARM7/LPC214x/lpc214x.h
new file mode 100644
index 000000000..e260da713
--- /dev/null
+++ b/os/ports/GCC/ARM7/LPC214x/lpc214x.h
@@ -0,0 +1,523 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT 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 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT 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, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file lpc214x.h
+ * @brief LPC214x register definitions
+ */
+
+#ifndef _LPC214X_H_
+#define _LPC214X_H_
+
+typedef volatile unsigned char IOREG8;
+typedef volatile unsigned int IOREG32;
+
+/*
+ * System.
+ */
+#define MEMMAP (*((IOREG32 *)0xE01FC040))
+#define PCON (*((IOREG32 *)0xE01FC0C0))
+#define PCONP (*((IOREG32 *)0xE01FC0C4))
+#define VPBDIV (*((IOREG32 *)0xE01FC100))
+#define EXTINT (*((IOREG32 *)0xE01FC140))
+#define INTWAKE (*((IOREG32 *)0xE01FC144))
+#define EXTMODE (*((IOREG32 *)0xE01FC148))
+#define EXTPOLAR (*((IOREG32 *)0xE01FC14C))
+#define RSID (*((IOREG32 *)0xE01FC180))
+#define CSPR (*((IOREG32 *)0xE01FC184))
+#define SCS (*((IOREG32 *)0xE01FC1A0))
+
+#define VPD_D4 0
+#define VPD_D1 1
+#define VPD_D2 2
+#define VPD_RESERVED 3
+
+#define PCTIM0 (1 << 1)
+#define PCTIM1 (1 << 2)
+#define PCUART0 (1 << 3)
+#define PCUART1 (1 << 4)
+#define PCPWM0 (1 << 5)
+#define PCI2C0 (1 << 7)
+#define PCSPI0 (1 << 8)
+#define PCRTC (1 << 9)
+#define PCSPI1 (1 << 10)
+#define PCAD0 (1 << 12)
+#define PCI2C1 (1 << 19)
+#define PCAD1 (1 << 20)
+#define PCUSB (1 << 31)
+#define PCALL (PCTIM0 | PCTIM1 | PCUART0 | PCUART1 | \
+ PCPWM0 | PCI2C0 | PCSPI0 | PCRTC | PCSPI1 | \
+ PCAD0 | PCI2C1 | PCAD1 | PCUSB)
+
+#define EINT0 1
+#define EINT1 2
+#define EINT2 4
+#define EINT3 8
+
+#define EXTWAKE0 1
+#define EXTWAKE1 2
+#define EXTWAKE2 4
+#define EXTWAKE3 8
+#define USBWAKE 0x20
+#define BODWAKE 0x4000
+#define RTCWAKE 0x8000
+
+#define EXTMODE0 1
+#define EXTMODE1 2
+#define EXTMODE2 4
+#define EXTMODE3 8
+
+#define EXTPOLAR0 1
+#define EXTPOLAR1 2
+#define EXTPOLAR2 4
+#define EXTPOLAR3 8
+
+typedef struct {
+ IOREG32 PLL_CON;
+ IOREG32 PLL_CFG;
+ IOREG32 PLL_STAT;
+ IOREG32 PLL_FEED;
+} PLL;
+
+#define PLL0Base ((PLL *)0xE01FC080)
+#define PLL1Base ((PLL *)0xE01FC0A0)
+#define PLL0CON (PLL0Base->PLL_CON)
+#define PLL0CFG (PLL0Base->PLL_CFG)
+#define PLL0STAT (PLL0Base->PLL_STAT)
+#define PLL0FEED (PLL0Base->PLL_FEED)
+#define PLL1CON (PLL1Base->PLL_CON)
+#define PLL1CFG (PLL1Base->PLL_CFG)
+#define PLL1STAT (PLL1Base->PLL_STAT)
+#define PLL1FEED (PLL1Base->PLL_FEED)
+
+/*
+ * Pins.
+ */
+typedef struct {
+ IOREG32 PS_SEL0;
+ IOREG32 PS_SEL1;
+ IOREG32 PS_SEL2;
+} PS;
+
+#define PSBase ((PS *)0xE002C000)
+#define PINSEL0 (PSBase->PS_SEL0)
+#define PINSEL1 (PSBase->PS_SEL1)
+#define PINSEL2 (PSBase->PS_SEL2)
+
+/*
+ * VIC
+ */
+#define SOURCE_WDT 0
+#define SOURCE_ARMCore0 2
+#define SOURCE_ARMCore1 3
+#define SOURCE_Timer0 4
+#define SOURCE_Timer1 5
+#define SOURCE_UART0 6
+#define SOURCE_UART1 7
+#define SOURCE_PWM0 8
+#define SOURCE_I2C0 9
+#define SOURCE_SPI0 10
+#define SOURCE_SPI1 11
+#define SOURCE_PLL 12
+#define SOURCE_RTC 13
+#define SOURCE_EINT0 14
+#define SOURCE_EINT1 15
+#define SOURCE_EINT2 16
+#define SOURCE_EINT3 17
+#define SOURCE_ADC0 18
+#define SOURCE_I2C1 19
+#define SOURCE_BOD 20
+#define SOURCE_ADC1 21
+#define SOURCE_USB 22
+
+#define INTMASK(n) (1 << (n))
+#define ALLINTMASK (INTMASK(SOURCE_WDT) | INTMASK(SOURCE_ARMCore0) | \
+ INTMASK(SOURCE_ARMCore1) | INTMASK(SOURCE_Timer0) | \
+ INTMASK(SOURCE_Timer1) | INTMASK(SOURCE_UART0) | \
+ INTMASK(SOURCE_UART1) | INTMASK(SOURCE_PWM0) | \
+ INTMASK(SOURCE_I2C0) | INTMASK(SOURCE_SPI0) | \
+ INTMASK(SOURCE_SPI1) | INTMASK(SOURCE_PLL) | \
+ INTMASK(SOURCE_RTC) | INTMASK(SOURCE_EINT0) | \
+ INTMASK(SOURCE_EINT1) | INTMASK(SOURCE_EINT2) | \
+ INTMASK(SOURCE_EINT3) | INTMASK(SOURCE_ADC0) | \
+ INTMASK(SOURCE_I2C1) | INTMASK(SOURCE_BOD) | \
+ INTMASK(SOURCE_ADC1) | INTMASK(SOURCE_USB))
+
+typedef struct {
+ IOREG32 VIC_IRQStatus;
+ IOREG32 VIC_FIQStatus;
+ IOREG32 VIC_RawIntr;
+ IOREG32 VIC_IntSelect;
+ IOREG32 VIC_IntEnable;
+ IOREG32 VIC_IntEnClear;
+ IOREG32 VIC_SoftInt;
+ IOREG32 VIC_SoftIntClear;
+ IOREG32 VIC_Protection;
+ IOREG32 unused1[3];
+ IOREG32 VIC_VectAddr;
+ IOREG32 VIC_DefVectAddr;
+ IOREG32 unused2[50];
+ IOREG32 VIC_VectAddrs[16];
+ IOREG32 unused3[48];
+ IOREG32 VIC_VectCntls[16];
+} VIC;
+
+#define VICBase ((VIC *)0xFFFFF000)
+#define VICVectorsBase ((IOREG32 *)0xFFFFF100)
+#define VICControlsBase ((IOREG32 *)0xFFFFF200)
+
+#define VICIRQStatus (VICBase->VIC_IRQStatus)
+#define VICFIQStatus (VICBase->VIC_FIQStatus)
+#define VICRawIntr (VICBase->VIC_RawIntr)
+#define VICIntSelect (VICBase->VIC_IntSelect)
+#define VICIntEnable (VICBase->VIC_IntEnable)
+#define VICIntEnClear (VICBase->VIC_IntEnClear)
+#define VICSoftInt (VICBase->VIC_SoftInt)
+#define VICSoftIntClear (VICBase->VIC_SoftIntClear)
+#define VICProtection (VICBase->VIC_Protection)
+#define VICVectAddr (VICBase->VIC_VectAddr)
+#define VICDefVectAddr (VICBase->VIC_DefVectAddr)
+
+#define VICVectAddrs(n) (VICBase->VIC_VectAddrs[n])
+#define VICVectCntls(n) (VICBase->VIC_VectCntls[n])
+
+/*
+ * MAM.
+ */
+typedef struct {
+ IOREG32 MAM_Control;
+ IOREG32 MAM_Timing;
+} MAM;
+
+#define MAMBase ((MAM *)0xE01FC000)
+#define MAMCR (MAMBase->MAM_Control)
+#define MAMTIM (MAMBase->MAM_Timing)
+
+/*
+ * GPIO - FIO.
+ */
+typedef struct {
+ IOREG32 IO_PIN;
+ IOREG32 IO_SET;
+ IOREG32 IO_DIR;
+ IOREG32 IO_CLR;
+} GPIO;
+
+#define GPIO0Base ((GPIO *)0xE0028000)
+#define IO0PIN (GPIO0Base->IO_PIN)
+#define IO0SET (GPIO0Base->IO_SET)
+#define IO0DIR (GPIO0Base->IO_DIR)
+#define IO0CLR (GPIO0Base->IO_CLR)
+
+#define GPIO1Base ((GPIO *)0xE0028010)
+#define IO1PIN (GPIO1Base->IO_PIN)
+#define IO1SET (GPIO1Base->IO_SET)
+#define IO1DIR (GPIO1Base->IO_DIR)
+#define IO1CLR (GPIO1Base->IO_CLR)
+
+typedef struct {
+ IOREG32 FIO_DIR;
+ IOREG32 unused1;
+ IOREG32 unused2;
+ IOREG32 unused3;
+ IOREG32 FIO_MASK;
+ IOREG32 FIO_PIN;
+ IOREG32 FIO_SET;
+ IOREG32 FIO_CLR;
+} FIO;
+
+#define FIO0Base ((FIO *)0x3FFFC000)
+#define FIO0DIR (FIO0Base->FIO_DIR)
+#define FIO0MASK (FIO0Base->FIO_MASK)
+#define FIO0PIN (FIO0Base->FIO_PIN)
+#define FIO0SET (FIO0Base->FIO_SET)
+#define FIO0CLR (FIO0Base->FIO_CLR)
+
+#define FIO1Base ((FIO *)0x3FFFC020)
+#define FIO1DIR (FIO1Base->FIO_DIR)
+#define FIO1MASK (FIO1Base->FIO_MASK)
+#define FIO1PIN (FIO1Base->FIO_PIN)
+#define FIO1SET (FIO1Base->FIO_SET)
+#define FIO1CLR (FIO1Base->FIO_CLR)
+
+/*
+ * UART.
+ */
+typedef struct {
+ union {
+ IOREG32 UART_RBR;
+ IOREG32 UART_THR;
+ IOREG32 UART_DLL;
+ };
+ union {
+ IOREG32 UART_IER;
+ IOREG32 UART_DLM;
+ };
+ union {
+ IOREG32 UART_IIR;
+ IOREG32 UART_FCR;
+ };
+ IOREG32 UART_LCR;
+ IOREG32 UART_MCR; // UART1 only
+ IOREG32 UART_LSR;
+ IOREG32 unused18;
+ IOREG32 UART_SCR;
+ IOREG32 UART_ACR;
+ IOREG32 unused24;
+ IOREG32 UART_FDR;
+ IOREG32 unused2C;
+ IOREG32 UART_TER;
+} UART;
+
+#define U0Base ((UART *)0xE000C000)
+#define U0RBR (U0Base->UART_RBR)
+#define U0THR (U0Base->UART_THR)
+#define U0DLL (U0Base->UART_DLL)
+#define U0IER (U0Base->UART_IER)
+#define U0DLM (U0Base->UART_DLM)
+#define U0IIR (U0Base->UART_IIR)
+#define U0FCR (U0Base->UART_FCR)
+#define U0LCR (U0Base->UART_LCR)
+#define U0LSR (U0Base->UART_LSR)
+#define U0SCR (U0Base->UART_SCR)
+#define U0ACR (U0Base->UART_ACR)
+#define U0FDR (U0Base->UART_FDR)
+#define U0TER (U0Base->UART_TER)
+
+#define U1Base ((UART *)0xE0010000)
+#define U1RBR (U1Base->UART_RBR)
+#define U1THR (U1Base->UART_THR)
+#define U1DLL (U1Base->UART_DLL)
+#define U1IER (U1Base->UART_IER)
+#define U1DLM (U1Base->UART_DLM)
+#define U1IIR (U1Base->UART_IIR)
+#define U1FCR (U1Base->UART_FCR)
+#define U1MCR (U1Base->UART_MCR)
+#define U1LCR (U1Base->UART_LCR)
+#define U1LSR (U1Base->UART_LSR)
+#define U1SCR (U1Base->UART_SCR)
+#define U1ACR (U1Base->UART_ACR)
+#define U1FDR (U1Base->UART_FDR)
+#define U1TER (U1Base->UART_TER)
+
+#define IIR_SRC_MASK 0x0F
+#define IIR_SRC_NONE 0x01
+#define IIR_SRC_TX 0x02
+#define IIR_SRC_RX 0x04
+#define IIR_SRC_ERROR 0x06
+#define IIR_SRC_TIMEOUT 0x0C
+
+#define IER_RBR 1
+#define IER_THRE 2
+#define IER_STATUS 4
+
+#define IIR_INT_PENDING 1
+
+#define LCR_WL5 0
+#define LCR_WL6 1
+#define LCR_WL7 2
+#define LCR_WL8 3
+#define LCR_STOP1 0
+#define LCR_STOP2 4
+#define LCR_NOPARITY 0
+#define LCR_PARITYODD 0x08
+#define LCR_PARITYEVEN 0x18
+#define LCR_PARITYONE 0x28
+#define LCR_PARITYZERO 0x38
+#define LCR_BREAK_ON 0x40
+#define LCR_DLAB 0x80
+
+#define FCR_ENABLE 1
+#define FCR_RXRESET 2
+#define FCR_TXRESET 4
+#define FCR_TRIGGER0 0
+#define FCR_TRIGGER1 0x40
+#define FCR_TRIGGER2 0x80
+#define FCR_TRIGGER3 0xC0
+
+#define LSR_RBR_FULL 1
+#define LSR_OVERRUN 2
+#define LSR_PARITY 4
+#define LSR_FRAMING 8
+#define LSR_BREAK 0x10
+#define LSR_THRE 0x20
+#define LSR_TEMT 0x40
+#define LSR_RXFE 0x80
+
+#define TER_ENABLE 0x80
+
+/*
+ * SSP.
+ */
+typedef struct {
+ IOREG32 SSP_CR0;
+ IOREG32 SSP_CR1;
+ IOREG32 SSP_DR;
+ IOREG32 SSP_SR;
+ IOREG32 SSP_CPSR;
+ IOREG32 SSP_IMSC;
+ IOREG32 SSP_RIS;
+ IOREG32 SSP_MIS;
+ IOREG32 SSP_ICR;
+} SSP;
+
+#define SSPBase ((SSP *)0xE0068000)
+#define SSPCR0 (SSPBase->SSP_CR0)
+#define SSPCR1 (SSPBase->SSP_CR1)
+#define SSPDR (SSPBase->SSP_DR)
+#define SSPSR (SSPBase->SSP_SR)
+#define SSPCPSR (SSPBase->SSP_CPSR)
+#define SSPIMSC (SSPBase->SSP_IMSC)
+#define SSPRIS (SSPBase->SSP_RIS)
+#define SSPMIS (SSPBase->SSP_MIS)
+#define SSPICR (SSPBase->SSP_ICR)
+
+#define CR0_DSS4BIT 3
+#define CR0_DSS5BIT 4
+#define CR0_DSS6BIT 5
+#define CR0_DSS7BIT 6
+#define CR0_DSS8BIT 7
+#define CR0_DSS9BIT 8
+#define CR0_DSS10BIT 9
+#define CR0_DSS11BIT 0xA
+#define CR0_DSS12BIT 0xB
+#define CR0_DSS13BIT 0xC
+#define CR0_DSS14BIT 0xD
+#define CR0_DSS15BIT 0xE
+#define CR0_DSS16BIT 0xF
+#define CR0_FRFSPI 0
+#define CR0_FRFSSI 0x10
+#define CR0_FRFMW 0x20
+#define CR0_CPOL 0x40
+#define CR0_CPHA 0x80
+#define CR0_CLOCKRATE(n) ((n) << 8)
+
+#define CR1_LBM 1
+#define CR1_SSE 2
+#define CR1_MS 4
+#define CR1_SOD 8
+
+#define SR_TFE 1
+#define SR_TNF 2
+#define SR_RNE 4
+#define SR_RFF 8
+#define SR_BSY 0x10
+
+#define IMSC_ROR 1
+#define IMSC_RT 2
+#define IMSC_RX 4
+#define IMSC_TX 8
+
+#define RIS_ROR 1
+#define RIS_RT 2
+#define RIS_RX 4
+#define RIS_TX 8
+
+#define MIS_ROR 1
+#define MIS_RT 2
+#define MIS_RX 4
+#define MIS_TX 8
+
+#define ICR_ROR 1
+#define ICR_RT 2
+
+/*
+ * Timers/Counters.
+ */
+typedef struct {
+ IOREG32 TC_IR;
+ IOREG32 TC_TCR;
+ IOREG32 TC_TC;
+ IOREG32 TC_PR;
+ IOREG32 TC_PC;
+ IOREG32 TC_MCR;
+ IOREG32 TC_MR0;
+ IOREG32 TC_MR1;
+ IOREG32 TC_MR2;
+ IOREG32 TC_MR3;
+ IOREG32 TC_CCR;
+ IOREG32 TC_CR0;
+ IOREG32 TC_CR1;
+ IOREG32 TC_CR2;
+ IOREG32 TC_CR3;
+ IOREG32 TC_EMR;
+ IOREG32 TC_CTCR;
+} TC;
+
+#define T0Base ((TC *)0xE0004000)
+#define T0IR (T0Base->TC_IR)
+#define T0TCR (T0Base->TC_TCR)
+#define T0TC (T0Base->TC_TC)
+#define T0PR (T0Base->TC_PR)
+#define T0PC (T0Base->TC_PC)
+#define T0MCR (T0Base->TC_MCR)
+#define T0MR0 (T0Base->TC_MR0)
+#define T0MR1 (T0Base->TC_MR1)
+#define T0MR2 (T0Base->TC_MR2)
+#define T0MR3 (T0Base->TC_MR3)
+#define T0CCR (T0Base->TC_CCR)
+#define T0CR0 (T0Base->TC_CR0)
+#define T0CR1 (T0Base->TC_CR1)
+#define T0CR2 (T0Base->TC_CR2)
+#define T0CR3 (T0Base->TC_CR3)
+#define T0EMR (T0Base->TC_EMR)
+#define T0CTCR (T0Base->TC_CTCR)
+
+#define T1Base ((TC *)0xE0008000)
+#define T1IR (T1Base->TC_IR)
+#define T1TCR (T1Base->TC_TCR)
+#define T1TC (T1Base->TC_TC)
+#define T1PR (T1Base->TC_PR)
+#define T1PC (T1Base->TC_PC)
+#define T1MCR (T1Base->TC_MCR)
+#define T1MR0 (T1Base->TC_MR0)
+#define T1MR1 (T1Base->TC_MR1)
+#define T1MR2 (T1Base->TC_MR2)
+#define T1MR3 (T1Base->TC_MR3)
+#define T1CCR (T1Base->TC_CCR)
+#define T1CR0 (T1Base->TC_CR0)
+#define T1CR1 (T1Base->TC_CR1)
+#define T1CR2 (T1Base->TC_CR2)
+#define T1CR3 (T1Base->TC_CR3)
+#define T1EMR (T1Base->TC_EMR)
+#define T1CTCR (T1Base->TC_CTCR)
+
+/*
+ * Watchdog.
+ */
+typedef struct {
+ IOREG32 WD_MOD;
+ IOREG32 WD_TC;
+ IOREG32 WD_FEED;
+ IOREG32 WD_TV;
+} WD;
+
+#define WDBase ((WD *)0xE0000000)
+#define WDMOD (WDBase->WD_MOD)
+#define WDTC (WDBase->WD_TC)
+#define WDFEED (WDBase->WD_FEED)
+#define WDTV (WDBase->WD_TV)
+
+/*
+ * DAC.
+ */
+#define DACR (*((IOREG32 *)0xE006C000))
+
+#endif /* _LPC214X_H_ */
+
diff --git a/os/ports/GCC/ARM7/LPC214x/lpc214x_serial.c b/os/ports/GCC/ARM7/LPC214x/lpc214x_serial.c
new file mode 100644
index 000000000..e452cec8d
--- /dev/null
+++ b/os/ports/GCC/ARM7/LPC214x/lpc214x_serial.c
@@ -0,0 +1,268 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT 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 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT 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, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file ports/ARM7-LPC214x/lpc214x_serial.c
+ * @brief LPC214x Serial driver code.
+ * @addtogroup LPC214x_SERIAL
+ * @{
+ */
+
+#include <ch.h>
+
+#include "lpc214x.h"
+#include "vic.h"
+#include "lpc214x_serial.h"
+#include "board.h"
+
+#if USE_LPC214x_UART0 || defined(__DOXYGEN__)
+/** @brief UART0 serial driver identifier.*/
+FullDuplexDriver COM1;
+
+static uint8_t ib1[SERIAL_BUFFERS_SIZE];
+static uint8_t ob1[SERIAL_BUFFERS_SIZE];
+#endif
+
+#if USE_LPC214x_UART1 || defined(__DOXYGEN__)
+/** @brief UART1 serial driver identifier.*/
+FullDuplexDriver COM2;
+
+static uint8_t ib2[SERIAL_BUFFERS_SIZE];
+static uint8_t ob2[SERIAL_BUFFERS_SIZE];
+#endif
+
+/**
+ * @brief Error handling routine.
+ * @param[in] err UART LSR register value
+ * @param[in] com communication channel associated to the USART
+ */
+static void SetError(IOREG32 err, FullDuplexDriver *com) {
+ dflags_t sts = 0;
+
+ if (err & LSR_OVERRUN)
+ sts |= SD_OVERRUN_ERROR;
+ if (err & LSR_PARITY)
+ sts |= SD_PARITY_ERROR;
+ if (err & LSR_FRAMING)
+ sts |= SD_FRAMING_ERROR;
+ if (err & LSR_BREAK)
+ sts |= SD_BREAK_DETECTED;
+ chSysLockFromIsr();
+ chFDDAddFlagsI(com, sts);
+ chSysUnlockFromIsr();
+}
+
+/** @cond never*/
+__attribute__((noinline))
+/** @endcond*/
+/**
+ * @brief Common IRQ handler.
+ * @param[in] u pointer to an UART I/O block
+ * @param[in] com communication channel associated to the UART
+ * @note Tries hard to clear all the pending interrupt sources, we dont want to
+ * go through the whole ISR and have another interrupt soon after.
+ */
+static void ServeInterrupt(UART *u, FullDuplexDriver *com) {
+
+ while (TRUE) {
+
+ switch (u->UART_IIR & IIR_SRC_MASK) {
+ case IIR_SRC_NONE:
+ return;
+ case IIR_SRC_ERROR:
+ SetError(u->UART_LSR, com);
+ break;
+ case IIR_SRC_TIMEOUT:
+ case IIR_SRC_RX:
+ while (u->UART_LSR & LSR_RBR_FULL) {
+ chSysLockFromIsr();
+ if (chIQPutI(&com->d2.iqueue, u->UART_RBR) < Q_OK)
+ chFDDAddFlagsI(com, SD_OVERRUN_ERROR);
+ chSysUnlockFromIsr();
+ }
+ chSysLockFromIsr();
+ chEvtBroadcastI(&com->d1.ievent);
+ chSysUnlockFromIsr();
+ break;
+ case IIR_SRC_TX:
+ {
+#if UART_FIFO_PRELOAD > 0
+ int i = UART_FIFO_PRELOAD;
+ do {
+ chSysLockFromIsr();
+ msg_t b = chOQGetI(&com->d2.oqueue);
+ chSysUnlockFromIsr();
+ if (b < Q_OK) {
+ u->UART_IER &= ~IER_THRE;
+ chSysLockFromIsr();
+ chEvtBroadcastI(&com->d1.oevent);
+ chSysUnlockFromIsr();
+ break;
+ }
+ u->UART_THR = b;
+ } while (--i);
+#else
+ chSysLockFromIsr();
+ msg_t b = chFDDRequestDataI(com);
+ chSysUnlockFromIsr();
+ if (b < Q_OK)
+ u->UART_IER &= ~IER_THRE;
+ else
+ u->UART_THR = b;
+#endif
+ }
+ default:
+ u->UART_THR;
+ u->UART_RBR;
+ }
+ }
+}
+
+#if UART_FIFO_PRELOAD > 0
+static void preload(UART *u, FullDuplexDriver *com) {
+
+ if (u->UART_LSR & LSR_THRE) {
+ int i = UART_FIFO_PRELOAD;
+ do {
+ chSysLockFromIsr();
+ msg_t b = chOQGetI(&com->d2.oqueue);
+ chSysUnlockFromIsr();
+ if (b < Q_OK) {
+ chSysLockFromIsr();
+ chEvtBroadcastI(&com->d1.oevent);
+ chSysUnlockFromIsr();
+ return;
+ }
+ u->UART_THR = b;
+ } while (--i);
+ }
+ u->UART_IER |= IER_THRE;
+}
+#endif
+
+#if USE_LPC214x_UART0 || defined(__DOXYGEN__)
+CH_IRQ_HANDLER(UART0IrqHandler) {
+
+ CH_IRQ_PROLOGUE();
+
+ ServeInterrupt(U0Base, &COM1);
+ VICVectAddr = 0;
+
+ CH_IRQ_EPILOGUE();
+}
+
+static void OutNotify1(void) {
+#if UART_FIFO_PRELOAD > 0
+
+ preload(U0Base, &COM1);
+#else
+ UART *u = U0Base;
+
+ if (u->UART_LSR & LSR_THRE) {
+ chSysLockFromIsr();
+ u->UART_THR = chOQGetI(&COM1.sd_oqueue);
+ chSysUnlockFromIsr();
+ }
+ u->UART_IER |= IER_THRE;
+#endif
+}
+#endif
+
+#if USE_LPC214x_UART1 || defined(__DOXYGEN__)
+CH_IRQ_HANDLER(UART1IrqHandler) {
+
+ CH_IRQ_PROLOGUE();
+
+ ServeInterrupt(U1Base, &COM2);
+ VICVectAddr = 0;
+
+ CH_IRQ_EPILOGUE();
+}
+
+static void OutNotify2(void) {
+#if UART_FIFO_PRELOAD > 0
+
+ preload(U1Base, &COM2);
+#else
+ UART *u = U1Base;
+
+ if (u->UART_LSR & LSR_THRE)
+ u->UART_THR = chOQGetI(&COM2.sd_oqueue);
+ u->UART_IER |= IER_THRE;
+#endif
+}
+#endif
+
+/**
+ * @brief UART setup.
+ * @param[in] u pointer to an UART I/O block
+ * @param[in] speed serial port speed in bits per second
+ * @param[in] lcr the value for the @p LCR register
+ * @param[in] fcr the value for the @p FCR register
+ * @note Must be invoked with interrupts disabled.
+ * @note Does not reset the I/O queues.
+ */
+void uart_setup(UART *u, int speed, int lcr, int fcr) {
+
+ int div = PCLK / (speed << 4);
+ u->UART_LCR = lcr | LCR_DLAB;
+ u->UART_DLL = div;
+ u->UART_DLM = div >> 8;
+ u->UART_LCR = lcr;
+ u->UART_FCR = FCR_ENABLE | FCR_RXRESET | FCR_TXRESET | fcr;
+ u->UART_ACR = 0;
+ u->UART_FDR = 0x10;
+ u->UART_TER = TER_ENABLE;
+ u->UART_IER = IER_RBR | IER_STATUS;
+}
+
+/**
+ * @brief Serial driver initialization.
+ * @param[in] vector1 IRC vector to be used for UART0
+ * @param[in] vector2 IRC vector to be used for UART1
+ * @note Handshake pads are not enabled inside this function because they
+ * may have another use, enable them externally if needed.
+ * RX and TX pads are handled inside.
+ */
+void serial_init(int vector1, int vector2) {
+
+#if USE_LPC214x_UART0
+ SetVICVector(UART0IrqHandler, vector1, SOURCE_UART0);
+ PCONP = (PCONP & PCALL) | PCUART0;
+ chFDDInit(&COM1, ib1, sizeof ib1, NULL, ob1, sizeof ob1, OutNotify1);
+ uart_setup(U0Base,
+ DEFAULT_UART_BITRATE,
+ LCR_WL8 | LCR_STOP1 | LCR_NOPARITY,
+ FCR_TRIGGER0);
+ VICIntEnable = INTMASK(SOURCE_UART0);
+#endif
+
+#if USE_LPC214x_UART1
+ SetVICVector(UART1IrqHandler, vector2, SOURCE_UART1);
+ PCONP = (PCONP & PCALL) | PCUART1;
+ chFDDInit(&COM2, ib2, sizeof ib2, NULL, ob2, sizeof ob2, OutNotify2);
+ uart_setup(U1Base,
+ DEFAULT_UART_BITRATE,
+ LCR_WL8 | LCR_STOP1 | LCR_NOPARITY,
+ FCR_TRIGGER0);
+ VICIntEnable = INTMASK(SOURCE_UART0) | INTMASK(SOURCE_UART1);
+#endif
+}
+
+/** @} */
diff --git a/os/ports/GCC/ARM7/LPC214x/lpc214x_serial.h b/os/ports/GCC/ARM7/LPC214x/lpc214x_serial.h
new file mode 100644
index 000000000..021dbf6a1
--- /dev/null
+++ b/os/ports/GCC/ARM7/LPC214x/lpc214x_serial.h
@@ -0,0 +1,102 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT 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 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT 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, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file ports/ARM7-LPC214x/lpc214x_serial.h
+ * @brief LPC214x Serial driver macros and structures.
+ * @addtogroup LPC214x_SERIAL
+ * @{
+ */
+
+#ifndef _LPC214x_SERIAL_H_
+#define _LPC214x_SERIAL_H_
+
+/**
+ * @brief Serial buffers size.
+ * @details Configuration parameter, you can change the depth of the queue
+ * buffers depending on the requirements of your application.
+ * @note The default is 128 bytes for both the transmission and receive buffers.
+ */
+#if !defined(SERIAL_BUFFERS_SIZE) || defined(__DOXYGEN__)
+#define SERIAL_BUFFERS_SIZE 128
+#endif
+
+/**
+ * @brief Default bit rate.
+ * @details Configuration parameter, at startup the UARTs are configured at
+ * this speed.
+ * @note It is possible to use @p SetUART() in order to change the working
+ * parameters at runtime.
+ */
+#if !defined(DEFAULT_UART_BITRATE) || defined(__DOXYGEN__)
+#define DEFAULT_UART_BITRATE 38400
+#endif
+
+/**
+ * @brief FIFO preload parameter.
+ * @details Configuration parameter, this values defines how many bytes are
+ * preloaded in the HW transmit FIFO for each interrupt, the maximum value is
+ * 16 the minimum is 2, the value 0 disables the feature.
+ * @note An high value reduces the number of interrupts generated but can
+ * also increase the worst case interrupt response time because the
+ * preload loops.
+ * @note The value zero disables the feature and reverts to a simpler code
+ * that will generate an interrupt for each output byte but is much
+ * smaller and simpler.
+ */
+#if !defined(UART_FIFO_PRELOAD) || defined(__DOXYGEN__)
+#define UART_FIFO_PRELOAD 16
+#endif
+
+/**
+ * @brief UART0 driver enable switch.
+ * @details If set to @p TRUE the support for USART1 is included.
+ * @note The default is @p TRUE .
+ */
+#if !defined(USE_LPC214x_UART0) || defined(__DOXYGEN__)
+#define USE_LPC214x_UART0 TRUE
+#endif
+
+/**
+ * @brief UART1 driver enable switch.
+ * @details If set to @p TRUE the support for USART2 is included.
+ * @note The default is @p TRUE.
+ */
+#if !defined(USE_LPC214x_UART1) || defined(__DOXYGEN__)
+#define USE_LPC214x_UART1 TRUE
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void serial_init(int vector1, int vector2);
+ void uart_setup(UART *u, int speed, int lcr, int fcr);
+ CH_IRQ_HANDLER(UART0IrqHandler);
+ CH_IRQ_HANDLER(UART1IrqHandler);
+#ifdef __cplusplus
+}
+#endif
+
+/** @cond never*/
+extern FullDuplexDriver COM1, COM2;
+/** @endcond*/
+
+#endif /* _LPC214x_SERIAL_H_*/
+
+/** @} */
diff --git a/os/ports/GCC/ARM7/LPC214x/lpc214x_ssp.c b/os/ports/GCC/ARM7/LPC214x/lpc214x_ssp.c
new file mode 100644
index 000000000..790182576
--- /dev/null
+++ b/os/ports/GCC/ARM7/LPC214x/lpc214x_ssp.c
@@ -0,0 +1,133 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT 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 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT 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, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file ports/ARM7-LPC214x/lpc214x_ssp.c
+ * @brief LPC214x SSP driver code.
+ * @addtogroup LPC214x_SSP
+ * @{
+ */
+
+#include <ch.h>
+#include <pal.h>
+
+#include "lpc214x.h"
+#include "lpc214x_ssp.h"
+
+#if LPC214x_SSP_USE_MUTEX
+static Semaphore me;
+#endif
+
+/**
+ * @brief Aquires access to the SSP bus.
+ * @note This function also handles the mutual exclusion on the SSP bus if
+ * the @p LPC214x_SSP_USE_MUTEX option is enabled.
+ */
+void sspAcquireBus(void) {
+
+#if LPC214x_SSP_USE_MUTEX
+ chSemWait(&me);
+#endif
+ palClearPad(IOPORT_A, 20);
+}
+
+/**
+ * @brief Releases the SSP bus.
+ * @note This function also handles the mutual exclusion on the SSP bus if
+ * the @p LPC214x_SSP_USE_MUTEX option is enabled.
+ */
+void sspReleaseBus(void) {
+
+ palClearPad(IOPORT_A, 20);
+#if LPC214x_SSP_USE_MUTEX
+ chSemSignal(&me);
+#endif
+}
+
+/**
+ * @brief Synchronous SSP transfer.
+ * @param[in] in pointer to the incoming data buffer, if this parameter is set
+ * to @p NULL then the incoming data is discarded
+ * @param[out] out pointer to the outgoing data buffer, if this parameter is
+ * set to @p NULL then 0xFF bytes will be output
+ * @param[in] n the number of bytes to be transferred
+ * @note The transfer is performed in a software loop and is not interrupt
+ * driven for performance reasons, this function should be invoked
+ * by a low priority thread in order to "play nice" with the
+ * rest of the system. This kind of peripheral would really need a
+ * dedicated DMA channel.
+ */
+void sspRW(uint8_t *in, uint8_t *out, size_t n) {
+ int icnt, ocnt;
+
+ SSP *ssp = SSPBase;
+ icnt = ocnt = n;
+ while (icnt) {
+
+ if (ssp->SSP_SR & SR_RNE) {
+ if (in)
+ *in++ = ssp->SSP_DR;
+ else
+ ssp->SSP_DR;
+ icnt--;
+ continue; /* Priority over transmission. */
+ }
+
+ if (ocnt && (ssp->SSP_SR & SR_TNF)) {
+ if (out)
+ ssp->SSP_DR = *out++;
+ else
+ ssp->SSP_DR = 0xFF;
+ ocnt--;
+ }
+ }
+}
+
+/**
+ * @brief SSP setup.
+ * @param[in] cpsr the value for the @p CPSR register
+ * @param[in] cr0 the value for the @p CR0 register
+ * @param[in] cr1 the value for the @p CR1 register
+ */
+void ssp_setup(int cpsr, int cr0, int cr1) {
+
+ SSP *ssp = SSPBase;
+ ssp->SSP_CR1 = 0;
+ ssp->SSP_CR0 = cr0;
+ ssp->SSP_CPSR = cpsr;
+ ssp->SSP_CR1 = cr1 | CR1_SSE;
+}
+
+/**
+ * @brief SSP subsystem initialization.
+ */
+void ssp_init(void) {
+
+ /* Enables the SPI1 clock */
+ PCONP = (PCONP & PCALL) | PCSPI1;
+
+ /* Clock = PCLK / 2 (fastest). */
+ ssp_setup(2, CR0_DSS8BIT | CR0_FRFSPI | CR0_CLOCKRATE(0), 0);
+
+#if LPC214x_SSP_USE_MUTEX
+ chSemInit(&me, 1);
+#endif
+}
+
+/** @} */
diff --git a/os/ports/GCC/ARM7/LPC214x/lpc214x_ssp.h b/os/ports/GCC/ARM7/LPC214x/lpc214x_ssp.h
new file mode 100644
index 000000000..cae264a92
--- /dev/null
+++ b/os/ports/GCC/ARM7/LPC214x/lpc214x_ssp.h
@@ -0,0 +1,54 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT 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 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT 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, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file ports/ARM7-LPC214x/lpc214x_ssp.h
+ * @brief LPC214x SSP driver macros and structures.
+ * @addtogroup LPC214x_SSP
+ * @{
+ */
+
+#ifndef _LPC214x_SSP_H_
+#define _LPC214x_SSP_H_
+
+/**
+ * @brief SSP bus mutual exclusion control.
+ * @details Configuration parameter, if set to @p TRUE enforces mutual
+ * exclusion when invoking @p sspAcquireBus() and @p sspReleaseBus().
+ * @note The internally used synchronization mechanism is a @p Semaphore.
+ */
+#if !defined(LPC214x_SSP_USE_MUTEX) || defined(__DOXYGEN__)
+#define LPC214x_SSP_USE_MUTEX TRUE
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+ void ssp_init(void);
+ void ssp_setup(int cpsr, int cr0, int cr1);
+ void sspAcquireBus(void);
+ void sspReleaseBus(void);
+ void sspRW(uint8_t *in, uint8_t *out, size_t n);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _LPC214x_SSP_H_*/
+
+/** @} */
diff --git a/os/ports/GCC/ARM7/LPC214x/pal_lld.c b/os/ports/GCC/ARM7/LPC214x/pal_lld.c
new file mode 100644
index 000000000..e197a39fc
--- /dev/null
+++ b/os/ports/GCC/ARM7/LPC214x/pal_lld.c
@@ -0,0 +1,89 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT 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 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT 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, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file ports/ARM7-LPC214x/pal_lld.c
+ * @brief LPC214x FIO low level driver code
+ * @addtogroup LPC214x_PAL
+ * @{
+ */
+
+#include <ch.h>
+#include <pal.h>
+
+/**
+ * @brief LPC214x I/O ports configuration.
+ * @details FIO units and PINSEL registers initialization.
+ *
+ * @param[in] config the LPC214x ports configuration
+ */
+void _pal_lld_init(const LPC214xFIOConfig *config) {
+
+ /* Enables the access through the fast registers.*/
+ SCS = 3;
+
+ /* I/O pads initial assignment, device drivers may change this setup at a
+ * later time.*/
+ PINSEL0 = config->pinsel0;
+ PINSEL1 = config->pinsel1;
+ PINSEL2 = config->pinsel2;
+
+ /* I/O pads direction initial setting.*/
+ FIO0Base->FIO_MASK = 0;
+ FIO0Base->FIO_PIN = config->P0Data.pin;
+ FIO0Base->FIO_DIR = config->P0Data.dir;
+ FIO1Base->FIO_MASK = 0;
+ FIO1Base->FIO_PIN = config->P1Data.pin;
+ FIO1Base->FIO_DIR = config->P1Data.dir;
+}
+
+/**
+ * @brief Pads mode setup.
+ * @details This function programs a pads group belonging to the same port
+ * with the specified mode.
+ *
+ * @param[in] port the port identifier
+ * @param[in] mask the group mask
+ * @param[in] mode the mode
+ *
+ * @note This function is not meant to be invoked directly by the application
+ * code.
+ * @note @p PAL_MODE_UNCONNECTED is implemented as push pull output with high
+ * state.
+ * @note This function does not alter the @p PINSELx registers. Alternate
+ * functions setup must be handled by device-specific code.
+ */
+void _pal_lld_setgroupmode(ioportid_t port,
+ ioportmask_t mask,
+ uint_fast8_t mode) {
+
+ switch (mode) {
+ case PAL_MODE_RESET:
+ case PAL_MODE_INPUT:
+ port->FIO_DIR &= ~mask;
+ break;
+ case PAL_MODE_UNCONNECTED:
+ port->FIO_PIN |= mask;
+ case PAL_MODE_OUTPUT_PUSHPULL:
+ port->FIO_DIR |= mask;
+ break;
+ }
+}
+
+/** @} */
diff --git a/os/ports/GCC/ARM7/LPC214x/pal_lld.h b/os/ports/GCC/ARM7/LPC214x/pal_lld.h
new file mode 100644
index 000000000..143fc103f
--- /dev/null
+++ b/os/ports/GCC/ARM7/LPC214x/pal_lld.h
@@ -0,0 +1,252 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT 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 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT 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, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file ports/ARM7-LPC214x/pal_lld.h
+ * @brief LPC214x FIO low level driver header
+ * @addtogroup LPC214x_PAL
+ * @{
+ */
+
+#ifndef _PAL_LLD_H_
+#define _PAL_LLD_H_
+
+#include "lpc214x.h"
+
+/*===========================================================================*/
+/* Unsupported modes and specific modes */
+/*===========================================================================*/
+
+#undef PAL_MODE_INPUT_PULLUP
+#undef PAL_MODE_INPUT_PULLDOWN
+#undef PAL_MODE_OUTPUT_OPENDRAIN
+
+/*===========================================================================*/
+/* I/O Ports Types and constants. */
+/*===========================================================================*/
+
+/**
+ * @brief FIO port setup info.
+ */
+typedef struct {
+ /** Initial value for FIO_PIN register.*/
+ uint32_t pin;
+ /** Initial value for FIO_DIR register.*/
+ uint32_t dir;
+} lpc214x_fio_setup_t;
+
+/**
+ * @brief LPC214x FIO static initializer.
+ * @details An instance of this structure must be passed to @p palInit() at
+ * system startup time in order to initialized the digital I/O
+ * subsystem. This represents only the initial setup, specific pads
+ * or whole ports can be reprogrammed at later time.
+ */
+typedef struct {
+ /** @brief PINSEL0 initial value.*/
+ uint32_t pinsel0;
+ /** @brief PINSEL1 initial value.*/
+ uint32_t pinsel1;
+ /** @brief PINSEL2 initial value.*/
+ uint32_t pinsel2;
+ /** @brief Port 0 setup data.*/
+ lpc214x_fio_setup_t P0Data;
+ /** @brief Port 1 setup data.*/
+ lpc214x_fio_setup_t P1Data;
+} LPC214xFIOConfig;
+
+/**
+ * @brief Width, in bits, of an I/O port.
+ */
+#define PAL_IOPORTS_WIDTH 32
+
+/**
+ * @brief Digital I/O port sized unsigned type.
+ */
+typedef uint32_t ioportmask_t;
+
+/**
+ * @brief Port Identifier.
+ */
+typedef FIO * ioportid_t;
+
+/*===========================================================================*/
+/* I/O Ports Identifiers. */
+/*===========================================================================*/
+
+/**
+ * @brief FIO port 0 identifier.
+ */
+#define IOPORT_A FIO0Base
+
+/**
+ * @brief FIO port 1 identifier.
+ */
+#define IOPORT_B FIO1Base
+
+/*===========================================================================*/
+/* Implementation, some of the following macros could be implemented as */
+/* functions, please put them in a file named ioports_lld.c if so. */
+/*===========================================================================*/
+
+/**
+ * @brief FIO subsystem initialization.
+ * @details Enables the access through the fast registers.
+ */
+#define pal_lld_init(config) _pal_lld_init(config)
+
+/**
+ * @brief Reads an I/O port.
+ * @details This function is implemented by reading the FIO PIN register, the
+ * implementation has no side effects.
+ *
+ * @param[in] port the port identifier
+ * @return the port bits
+ *
+ * @note This function is not meant to be invoked directly by the application
+ * code.
+ */
+#define pal_lld_readport(port) ((port)->FIO_PIN)
+
+/**
+ * @brief Reads the output latch.
+ * @details This function is implemented by reading the FIO SET register, the
+ * implementation has no side effects.
+ *
+ * @param[in] port the port identifier
+ * @return The latched logical states.
+ *
+ * @note This function is not meant to be invoked directly by the application
+ * code.
+ */
+#define pal_lld_readlatch(port) ((port)->FIO_SET)
+
+/**
+ * @brief Writes a bits mask on a I/O port.
+ * @details This function is implemented by writing the FIO PIN register, the
+ * implementation has no side effects.
+ *
+ * @param[in] port the port identifier
+ * @param[in] bits the bits to be written on the specified port
+ *
+ * @note This function is not meant to be invoked directly by the application
+ * code.
+ */
+#define pal_lld_writeport(port, bits) ((port)->FIO_PIN = (bits))
+
+/**
+ * @brief Sets a bits mask on a I/O port.
+ * @details This function is implemented by writing the FIO SET register, the
+ * implementation has no side effects.
+ *
+ * @param[in] port the port identifier
+ * @param[in] bits the bits to be ORed on the specified port
+ *
+ * @note This function is not meant to be invoked directly by the application
+ * code.
+ */
+#define pal_lld_setport(port, bits) ((port)->FIO_SET = (bits))
+
+/**
+ * @brief Clears a bits mask on a I/O port.
+ * @details This function is implemented by writing the FIO CLR register, the
+ * implementation has no side effects.
+ *
+ * @param[in] port the port identifier
+ * @param[in] bits the bits to be cleared on the specified port
+ *
+ * @note This function is not meant to be invoked directly by the application
+ * code.
+ */
+#define pal_lld_clearport(port, bits) ((port)->FIO_CLR = (bits))
+
+/**
+ * @brief Writes a value on an I/O bus.
+ * @details This function is implemented by writing the FIO PIN and MASK
+ * registers, the implementation is not atomic because the multiple
+ * accesses.
+ *
+ * @param[in] port the port identifier
+ * @param[in] mask the group mask
+ * @param[in] offset the group bit offset within the port
+ * @param[in] bits the bits to be written. Values exceeding the group width
+ * are masked.
+ *
+ * @note This function is not meant to be invoked directly by the application
+ * code.
+ */
+#define pal_lld_writegroup(port, mask, offset, bits) { \
+ (port)->FIO_MASK = (mask) << (offset); \
+ (port)->FIO_PIN = (bits) << (offset); \
+ (port)->FIO_MASK = 0; \
+}
+
+/**
+ * @brief Pads group mode setup.
+ * @details This function programs a pads group belonging to the same port
+ * with the specified mode.
+ *
+ * @param[in] port the port identifier
+ * @param[in] mask the group mask
+ * @param[in] mode the mode
+ *
+ * @note This function is not meant to be invoked directly by the application
+ * code.
+ * @note @p PAL_MODE_UNCONNECTED is implemented as push pull output with high
+ * state.
+ * @note This function does not alter the @p PINSELx registers. Alternate
+ * functions setup must be handled by device-specific code.
+ */
+#define pal_lld_setgroupmode(port, mask, mode) \
+ _pal_lld_setgroupmode(port, mask, mode)
+
+/**
+ * @brief Writes a logical state on an output pad.
+ *
+ * @param[in] port the port identifier
+ * @param[in] pad the pad number within the port
+ * @param[out] bit the logical value, the value must be @p 0 or @p 1
+ *
+ * @note This function is not meant to be invoked directly by the application
+ * code.
+ */
+#define pal_lld_writepad(port, pad, bit) pal_lld_writegroup(port, 1, pad, bit)
+
+/**
+ * @brief FIO port setup.
+ * @details This function programs the pins direction within a port.
+ */
+#define pal_lld_lpc214x_set_direction(port, dir) { \
+ (port)->FIO_DIR = (dir); \
+}
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void _pal_lld_init(const LPC214xFIOConfig *config);
+ void _pal_lld_setgroupmode(ioportid_t port,
+ ioportmask_t mask,
+ uint_fast8_t mode);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _PAL_LLD_H_ */
+
+/** @} */
diff --git a/os/ports/GCC/ARM7/LPC214x/port.dox b/os/ports/GCC/ARM7/LPC214x/port.dox
new file mode 100644
index 000000000..e46ac4328
--- /dev/null
+++ b/os/ports/GCC/ARM7/LPC214x/port.dox
@@ -0,0 +1,83 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT 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 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT 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, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @defgroup LPC214x LPC214x Support
+ * @brief LPC214x specific support.
+ * @details The LPC214x support includes:
+ * - VIC support code.
+ * - I/O ports driver.
+ * - Buffered, interrupt driven, serial driver.
+ * - SSP driver.
+ * - A MMC/SD demo driver.
+ * - A timer driven buzzer demo driver.
+ * - A minimal demo, useful as project template.
+ * - A demo supporting the kernel test suite.
+ * - A C++ demo supporting the kernel test suite.
+ * .
+ * @ingroup ARM7
+ */
+
+/**
+ * @defgroup LPC214x_VIC VIC Support
+ * @brief VIC peripheral support.
+ *
+ * @ingroup LPC214x
+ */
+
+/**
+ * @defgroup LPC214x_PAL I/O Ports Support
+ * @brief I/O Ports peripherals support.
+ * @details This module supports the LPC214x FIO controller. The controller
+ * supports the following features (see @ref PAL):
+ * - 32 bits wide ports.
+ * - Atomic set/reset functions.
+ * - Output latched regardless of the pad setting.
+ * - Direct read of input pads regardless of the pad setting.
+ * .
+ * <h2>Supported Setup Modes</h2>
+ * - @p PAL_MODE_RESET.
+ * - @p PAL_MODE_UNCONNECTED.
+ * - @p PAL_MODE_INPUT.
+ * - @p PAL_MODE_OUTPUT_PUSHPULL.
+ * .
+ * Any attempt to setup an invalid mode is ignored.
+ *
+ * <h2>Suboptimal Behavior</h2>
+ * - Pad/port toggling operations are not atomic.
+ * - Pad/group mode setup is not atomic.
+ * .
+ * @ingroup LPC214x
+ */
+
+/**
+ * @defgroup LPC214x_SERIAL UART Support
+ * @brief UART peripherals support.
+ * @details The serial driver supports the LPC214x UART peripherals.
+ *
+ * @ingroup LPC214x
+ */
+
+/**
+ * @defgroup LPC214x_SSP SSP Support
+ * @brief SSP peripheral support.
+ * @details This SPI driver supports the LPC214x SSP peripheral.
+ *
+ * @ingroup LPC214x
+ */
diff --git a/os/ports/GCC/ARM7/LPC214x/vectors.s b/os/ports/GCC/ARM7/LPC214x/vectors.s
new file mode 100644
index 000000000..016a2f1de
--- /dev/null
+++ b/os/ports/GCC/ARM7/LPC214x/vectors.s
@@ -0,0 +1,71 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT 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 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT 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, see <http://www.gnu.org/licenses/>.
+*/
+
+.section vectors
+.code 32
+.balign 4
+/*
+ * System entry points.
+ */
+_start:
+ ldr pc, _reset
+ ldr pc, _undefined
+ ldr pc, _swi
+ ldr pc, _prefetch
+ ldr pc, _abort
+ nop
+ ldr pc, [pc,#-0xFF0] /* VIC - IRQ Vector Register */
+ ldr pc, _fiq
+
+_reset:
+ .word ResetHandler /* In crt0.s */
+_undefined:
+ .word UndHandler
+_swi:
+ .word SwiHandler
+_prefetch:
+ .word PrefetchHandler
+_abort:
+ .word AbortHandler
+_fiq:
+ .word FiqHandler
+ .word 0
+ .word 0
+
+/*
+ * Default exceptions handlers. The handlers are declared weak in order to be
+ * replaced by the real handling code. Everything is defaulted to an infinite
+ * loop.
+ */
+.weak UndHandler
+UndHandler:
+
+.weak SwiHandler
+SwiHandler:
+
+.weak PrefetchHandler
+PrefetchHandler:
+
+.weak AbortHandler
+AbortHandler:
+
+.weak FiqHandler
+FiqHandler:
+
+.loop: b .loop
diff --git a/os/ports/GCC/ARM7/LPC214x/vic.c b/os/ports/GCC/ARM7/LPC214x/vic.c
new file mode 100644
index 000000000..88e9814bb
--- /dev/null
+++ b/os/ports/GCC/ARM7/LPC214x/vic.c
@@ -0,0 +1,63 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT 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 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT 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, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file ports/ARM7-LPC214x/vic.c
+ * @brief LPC214x VIC peripheral support code.
+ * @addtogroup LPC214x_VIC
+ * @{
+ */
+
+#include <ch.h>
+
+#include "lpc214x.h"
+
+/**
+ * @brief VIC Initialization.
+ * @note Better reset everything in the VIC, it is a HUGE source of trouble.
+ */
+void vic_init(void) {
+ int i;
+
+ VIC *vic = VICBase;
+ vic->VIC_IntSelect = 0; /* All sources assigned to IRQ. */
+ vic->VIC_SoftIntClear = ALLINTMASK; /* No interrupts enforced */
+ vic->VIC_IntEnClear = ALLINTMASK; /* All sources disabled. */
+ for (i = 0; i < 16; i++) {
+ vic->VIC_VectCntls[i] = 0;
+ vic->VIC_VectAddrs[i] = 0;
+ vic->VIC_VectAddr = 0;
+ }
+}
+
+/**
+ * @brief Initializes a VIC vector.
+ * @details Set a vector for an interrupt source and enables it.
+ * @param[in] handler the pointer to the IRQ service routine
+ * @param[in] vector the vector number
+ * @param[in] source the IRQ source to be associated to the vector
+ */
+void SetVICVector(void *handler, int vector, int source) {
+
+ VIC *vicp = VICBase;
+ vicp->VIC_VectAddrs[vector] = (IOREG32)handler;
+ vicp->VIC_VectCntls[vector] = (IOREG32)(source | 0x20);
+}
+
+/** @} */
diff --git a/os/ports/GCC/ARM7/LPC214x/vic.h b/os/ports/GCC/ARM7/LPC214x/vic.h
new file mode 100644
index 000000000..b4b88948c
--- /dev/null
+++ b/os/ports/GCC/ARM7/LPC214x/vic.h
@@ -0,0 +1,41 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT 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 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT 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, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file ports/ARM7-LPC214x/vic.h
+ * @brief LPC214x VIC peripheral support code.
+ * @addtogroup LPC214x_VIC
+ * @{
+ */
+
+#ifndef _VIC_H_
+#define _VIC_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void vic_init(void);
+ void SetVICVector(void *handler, int vector, int source);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _VIC_H_ */
+
+/** @} */
diff --git a/os/ports/GCC/ARM7/LPC214x/wfi.h b/os/ports/GCC/ARM7/LPC214x/wfi.h
new file mode 100644
index 000000000..bd3b5e7cd
--- /dev/null
+++ b/os/ports/GCC/ARM7/LPC214x/wfi.h
@@ -0,0 +1,35 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT 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 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _WFI_H_
+#define _WFI_H_
+
+#include "lpc214x.h"
+
+#ifndef port_wait_for_interrupt
+#if ENABLE_WFI_IDLE != 0
+#define port_wait_for_interrupt() { \
+ PCON = 1; \
+}
+#else
+#define port_wait_for_interrupt()
+#endif
+#endif
+
+#endif /* _WFI_H_ */
diff --git a/os/ports/GCC/ARM7/chcore.c b/os/ports/GCC/ARM7/chcore.c
new file mode 100644
index 000000000..d0e0071bf
--- /dev/null
+++ b/os/ports/GCC/ARM7/chcore.c
@@ -0,0 +1,42 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT 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 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT 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, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file ports/ARM7/chcore.c
+ * @brief ARM7 architecture port code.
+ * @addtogroup ARM7_CORE
+ * @{
+ */
+
+#include <ch.h>
+
+/**
+ * Halts the system.
+ */
+/** @cond never */
+__attribute__((weak))
+/** @endcond */
+void port_halt(void) {
+
+ port_disable();
+ while (TRUE) {
+ }
+}
+
+/** @} */
diff --git a/os/ports/GCC/ARM7/chcore.h b/os/ports/GCC/ARM7/chcore.h
new file mode 100644
index 000000000..541207eef
--- /dev/null
+++ b/os/ports/GCC/ARM7/chcore.h
@@ -0,0 +1,331 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT 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 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT 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, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file ports/ARM7/chcore.h
+ * @brief ARM7 architecture port macros and structures.
+ * @addtogroup ARM7_CORE
+ * @{
+ */
+
+#ifndef _CHCORE_H_
+#define _CHCORE_H_
+
+/**
+ * If enabled allows the idle thread to enter a low power mode.
+ */
+#ifndef ENABLE_WFI_IDLE
+#define ENABLE_WFI_IDLE 0
+#endif
+#include <wfi.h>
+
+/**
+ * Macro defining the ARM7 architecture.
+ */
+#define CH_ARCHITECTURE_ARM7
+
+/**
+ * Name of the implemented architecture.
+ */
+#define CH_ARCHITECTURE_NAME "ARM7TDMI"
+
+/**
+ * 32 bit stack alignment.
+ */
+typedef uint32_t stkalign_t;
+
+/**
+ * Generic ARM register.
+ */
+typedef void *regarm_t;
+
+/** @cond never */
+/**
+ * This structure represents the stack frame saved during a preemption-capable
+ * interrupt handler.
+ */
+struct extctx {
+ regarm_t spsr_irq;
+ regarm_t lr_irq;
+ regarm_t r0;
+ regarm_t r1;
+ regarm_t r2;
+ regarm_t r3;
+ regarm_t r12;
+ regarm_t lr_usr;
+};
+/** @endcond */
+
+/** @cond never */
+/**
+ * This structure represents the inner stack frame during a context switching.
+ */
+struct intctx {
+ regarm_t r4;
+ regarm_t r5;
+ regarm_t r6;
+#ifndef CH_CURRP_REGISTER_CACHE
+ regarm_t r7;
+#endif
+ regarm_t r8;
+ regarm_t r9;
+ regarm_t r10;
+ regarm_t r11;
+ regarm_t lr;
+};
+/** @endcond */
+
+/** @cond never */
+/**
+ * In the ARM7 port this structure contains just the copy of the user mode
+ * stack pointer.
+ */
+struct context {
+ struct intctx *r13;
+};
+/** @endcond */
+
+/**
+ * Platform dependent part of the @p chThdInit() API.
+ */
+#define SETUP_CONTEXT(workspace, wsize, pf, arg) { \
+ tp->p_ctx.r13 = (struct intctx *)((uint8_t *)workspace + \
+ wsize - \
+ sizeof(struct intctx)); \
+ tp->p_ctx.r13->r4 = pf; \
+ tp->p_ctx.r13->r5 = arg; \
+ tp->p_ctx.r13->lr = _port_thread_start; \
+}
+
+/**
+ * Stack size for the system idle thread.
+ */
+#ifndef IDLE_THREAD_STACK_SIZE
+#define IDLE_THREAD_STACK_SIZE 0
+#endif
+
+/**
+ * Per-thread stack overhead for interrupts servicing, it is used in the
+ * calculation of the correct working area size.
+ * In this port 0x10 is a safe value, it can be reduced after careful generated
+ * code analysis.
+ */
+#ifndef INT_REQUIRED_STACK
+#define INT_REQUIRED_STACK 0x10
+#endif
+
+/**
+ * Enforces a correct alignment for a stack area size value.
+ */
+#define STACK_ALIGN(n) ((((n) - 1) | (sizeof(stkalign_t) - 1)) + 1)
+
+/**
+ * Computes the thread working area global size.
+ */
+#define THD_WA_SIZE(n) STACK_ALIGN(sizeof(Thread) + \
+ sizeof(struct intctx) + \
+ sizeof(struct extctx) + \
+ (n) + (INT_REQUIRED_STACK))
+
+/**
+ * Macro used to allocate a thread working area aligned as both position and
+ * size.
+ */
+#define WORKING_AREA(s, n) stkalign_t s[THD_WA_SIZE(n) / sizeof(stkalign_t)];
+
+/**
+ * IRQ prologue code, inserted at the start of all IRQ handlers enabled to
+ * invoke system APIs.
+ * @note This macro has a different implementation depending if compiled in
+ * ARM or THUMB mode.
+ * @note The THUMB implementation starts with ARM code because interrupt
+ * vectors are always invoked in ARM mode regardless the bit 0
+ * value. The switch in THUMB mode is done in the function prologue so
+ * it is transparent to the user code.
+ */
+#ifdef THUMB
+#define PORT_IRQ_PROLOGUE() { \
+ asm volatile (".code 32 \n\t" \
+ "stmfd sp!, {r0-r3, r12, lr} \n\t" \
+ "add r0, pc, #1 \n\t" \
+ "bx r0 \n\t" \
+ ".code 16"); \
+}
+#else /* !THUMB */
+#define PORT_IRQ_PROLOGUE() { \
+ asm volatile ("stmfd sp!, {r0-r3, r12, lr}"); \
+}
+#endif /* !THUMB */
+
+/**
+ * IRQ epilogue code, inserted at the end of all IRQ handlers enabled to
+ * invoke system APIs.
+ * @note This macro has a different implementation depending if compiled in
+ * ARM or THUMB mode.
+ */
+#ifdef THUMB
+#define PORT_IRQ_EPILOGUE() { \
+ asm volatile ("ldr r0, =_port_irq_common \n\t" \
+ "bx r0"); \
+}
+#else /* !THUMB */
+#define PORT_IRQ_EPILOGUE() { \
+ asm volatile ("b _port_irq_common"); \
+}
+#endif /* !THUMB */
+
+/**
+ * IRQ handler function declaration.
+ */
+#define PORT_IRQ_HANDLER(id) __attribute__((naked)) void id(void)
+
+/**
+ * This function is empty in this port.
+ */
+#define port_init()
+
+/**
+ * Disables the IRQ sources and keeps the FIQ sources enabled.
+ */
+#ifdef THUMB
+//#define port_lock() _port_lock_thumb()
+#define port_lock() { \
+ asm volatile ("bl _port_lock_thumb" : : : "r3", "lr"); \
+}
+#else /* !THUMB */
+#define port_lock() asm volatile ("msr CPSR_c, #0x9F")
+#endif /* !THUMB */
+
+/**
+ * Enables both the IRQ and FIQ sources.
+ */
+#ifdef THUMB
+//#define port_unlock() _port_unlock_thumb()
+#define port_unlock() { \
+ asm volatile ("bl _port_unlock_thumb" : : : "r3", "lr"); \
+}
+#else /* !THUMB */
+#define port_unlock() asm volatile ("msr CPSR_c, #0x1F")
+#endif /* !THUMB */
+
+/**
+ * This function is empty in this port.
+ */
+#define port_lock_from_isr()
+
+/**
+ * This function is empty in this port.
+ */
+#define port_unlock_from_isr()
+
+/**
+ * Disables both the IRQ and FIQ sources.
+ * @note Implements a workaround for spurious interrupts taken from the NXP
+ * LPC214x datasheet.
+ */
+#ifdef THUMB
+//#define port_disable() _port_disable_thumb()
+#define port_disable() { \
+ asm volatile ("bl _port_disable_thumb" : : : "r3", "lr"); \
+}
+#else /* !THUMB */
+#define port_disable() { \
+ asm volatile ("mrs r3, CPSR \n\t" \
+ "orr r3, #0x80 \n\t" \
+ "msr CPSR_c, r3 \n\t" \
+ "orr r3, #0x40 \n\t" \
+ "msr CPSR_c, r3" : : : "r3"); \
+}
+#endif /* !THUMB */
+
+/**
+ * Disables the IRQ sources and enables the FIQ sources.
+ */
+#ifdef THUMB
+#define port_suspend() { \
+ asm volatile ("bl _port_suspend_thumb" : : : "r3", "lr"); \
+}
+#else /* !THUMB */
+#define port_suspend() asm volatile ("msr CPSR_c, #0x9F")
+#endif /* !THUMB */
+
+/**
+ * Enables both the IRQ and FIQ sources.
+ */
+#ifdef THUMB
+#define port_enable() { \
+ asm volatile ("bl _port_enable_thumb" : : : "r3", "lr"); \
+}
+#else /* !THUMB */
+#define port_enable() asm volatile ("msr CPSR_c, #0x1F")
+#endif /* !THUMB */
+
+/**
+ * Performs a context switch between two threads.
+ * @param otp the thread to be switched out
+ * @param ntp the thread to be switched in
+ */
+#ifdef THUMB
+#if CH_DBG_ENABLE_STACK_CHECK
+#define port_switch(otp, ntp) { \
+ register Thread *_otp asm ("r0") = (otp); \
+ register Thread *_ntp asm ("r1") = (ntp); \
+ register char *sp asm ("sp"); \
+ if (sp - sizeof(struct intctx) - sizeof(Thread) < (char *)_otp) \
+ asm volatile ("mov r0, #0 \n\t" \
+ "ldr r1, =chDbgPanic \n\t" \
+ "bx r1"); \
+ _port_switch_thumb(_otp, _ntp); \
+}
+#else /* !CH_DBG_ENABLE_STACK_CHECK */
+#define port_switch(otp, ntp) _port_switch_thumb(otp, ntp)
+#endif /* !CH_DBG_ENABLE_STACK_CHECK */
+#else /* !THUMB */
+#if CH_DBG_ENABLE_STACK_CHECK
+#define port_switch(otp, ntp) { \
+ register Thread *_otp asm ("r0") = (otp); \
+ register Thread *_ntp asm ("r1") = (ntp); \
+ register char *sp asm ("sp"); \
+ if (sp - sizeof(struct intctx) - sizeof(Thread) < (char *)_otp) \
+ asm volatile ("mov r0, #0 \n\t" \
+ "b chDbgPanic"); \
+ _port_switch_arm(_otp, _ntp); \
+}
+#else /* !CH_DBG_ENABLE_STACK_CHECK */
+#define port_switch(otp, ntp) _port_switch_arm(otp, ntp)
+#endif /* !CH_DBG_ENABLE_STACK_CHECK */
+#endif /* !THUMB */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void port_halt(void);
+#ifdef THUMB
+ void _port_switch_thumb(Thread *otp, Thread *ntp);
+#else /* !THUMB */
+ void _port_switch_arm(Thread *otp, Thread *ntp);
+#endif /* !THUMB */
+ void _port_thread_start(void);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _CHCORE_H_ */
+
+/** @} */
diff --git a/os/ports/GCC/ARM7/chcore.lst b/os/ports/GCC/ARM7/chcore.lst
new file mode 100644
index 000000000..db8b7a12c
--- /dev/null
+++ b/os/ports/GCC/ARM7/chcore.lst
@@ -0,0 +1,48 @@
+ 1 .file "chcore.c"
+ 2 __SREG__ = 0x3f
+ 3 __SP_H__ = 0x3e
+ 4 __SP_L__ = 0x3d
+ 5 __CCP__ = 0x34
+ 6 __tmp_reg__ = 0
+ 7 __zero_reg__ = 1
+ 8 .global __do_copy_data
+ 9 .global __do_clear_bss
+ 17 .Ltext0:
+ 18 .weak port_halt
+ 20 port_halt:
+ 21 .LFB7:
+ 22 .LM1:
+ 23 ???? 3F92 push r3
+ 24 /* prologue: function */
+ 25 /* frame size = 0 */
+ 26 .LM2:
+ 27 /* #APP */
+ 28 ; 37 "../../os/ports/GCC/ARM7/chcore.c" 1
+ 29 mrs r3, CPSR
+ 30 orr r3, #0x80
+ 31 msr CPSR_c, r3
+ 32 orr r3, #0x40
+ 33 msr CPSR_c, r3
+ 34 ; 0 "" 2
+ 35 /* #NOAPP */
+ 36 .L2:
+ 37 ???? 00C0 rjmp .L2
+ 38 .LFE7:
+ 64 .Letext0:
+DEFINED SYMBOLS
+ *ABS*:00000000 chcore.c
+C:\DOCUME~1\Giovanni\IMPOST~1\Temp/ccjonuJz.s:2 *ABS*:0000003f __SREG__
+C:\DOCUME~1\Giovanni\IMPOST~1\Temp/ccjonuJz.s:3 *ABS*:0000003e __SP_H__
+C:\DOCUME~1\Giovanni\IMPOST~1\Temp/ccjonuJz.s:4 *ABS*:0000003d __SP_L__
+C:\DOCUME~1\Giovanni\IMPOST~1\Temp/ccjonuJz.s:5 *ABS*:00000034 __CCP__
+C:\DOCUME~1\Giovanni\IMPOST~1\Temp/ccjonuJz.s:6 *ABS*:00000000 __tmp_reg__
+C:\DOCUME~1\Giovanni\IMPOST~1\Temp/ccjonuJz.s:7 *ABS*:00000001 __zero_reg__
+C:\DOCUME~1\Giovanni\IMPOST~1\Temp/ccjonuJz.s:20 .text:00000000 port_halt
+C:\DOCUME~1\Giovanni\IMPOST~1\Temp/ccjonuJz.s:39 .text:00000000 L0
+C:\DOCUME~1\Giovanni\IMPOST~1\Temp/ccjonuJz.s:265 .debug_line:00000000 L0
+C:\DOCUME~1\Giovanni\IMPOST~1\Temp/ccjonuJz.s:265 .debug_line:0000001d L0
+C:\DOCUME~1\Giovanni\IMPOST~1\Temp/ccjonuJz.s:265 .debug_line:0000001d L0
+
+UNDEFINED SYMBOLS
+__do_copy_data
+__do_clear_bss
diff --git a/os/ports/GCC/ARM7/chcoreasm.s b/os/ports/GCC/ARM7/chcoreasm.s
new file mode 100644
index 000000000..932d39c04
--- /dev/null
+++ b/os/ports/GCC/ARM7/chcoreasm.s
@@ -0,0 +1,234 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT 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 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT 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, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file ports/ARM7/chcoreasm.s
+ * @brief ARM7 architecture port low level code.
+ * @addtogroup ARM7_CORE
+ * @{
+ */
+/** @cond never */
+
+#include <chconf.h>
+
+.set MODE_USR, 0x10
+.set MODE_FIQ, 0x11
+.set MODE_IRQ, 0x12
+.set MODE_SVC, 0x13
+.set MODE_ABT, 0x17
+.set MODE_UND, 0x1B
+.set MODE_SYS, 0x1F
+
+.equ I_BIT, 0x80
+.equ F_BIT, 0x40
+
+.text
+
+/*
+ * Interrupt enable/disable functions, only present if there is THUMB code in
+ * the system because those are inlined in ARM code.
+ */
+#ifdef THUMB_PRESENT
+.balign 16
+.code 16
+.thumb_func
+.global _port_disable_thumb
+_port_disable_thumb:
+ mov r3, pc
+ bx r3
+.code 32
+ mrs r3, CPSR
+ orr r3, #I_BIT
+ msr CPSR_c, r3
+ orr r3, #F_BIT
+ msr CPSR_c, r3
+ bx lr
+
+.balign 16
+.code 16
+.thumb_func
+.global _port_suspend_thumb
+_port_suspend_thumb:
+.thumb_func
+.global _port_lock_thumb
+_port_lock_thumb:
+ mov r3, pc
+ bx r3
+.code 32
+ msr CPSR_c, #MODE_SYS | I_BIT
+ bx lr
+
+.balign 16
+.code 16
+.thumb_func
+.global _port_enable_thumb
+_port_enable_thumb:
+.thumb_func
+.global _port_unlock_thumb
+_port_unlock_thumb:
+ mov r3, pc
+ bx r3
+.code 32
+ msr CPSR_c, #MODE_SYS
+ bx lr
+
+#endif
+
+.balign 16
+#ifdef THUMB_PRESENT
+.code 16
+.thumb_func
+.global _port_switch_thumb
+_port_switch_thumb:
+ mov r2, pc
+ bx r2
+ // Jumps into _port_switch_arm in ARM mode
+#endif
+.code 32
+.global _port_switch_arm
+_port_switch_arm:
+#ifdef CH_CURRP_REGISTER_CACHE
+ stmfd sp!, {r4, r5, r6, r8, r9, r10, r11, lr}
+ str sp, [r0, #16]
+ ldr sp, [r1, #16]
+#ifdef THUMB_PRESENT
+ ldmfd sp!, {r4, r5, r6, r8, r9, r10, r11, lr}
+ bx lr
+#else /* !THUMB_PRESENT */
+ ldmfd sp!, {r4, r5, r6, r8, r9, r10, r11, pc}
+#endif /* !THUMB_PRESENT */
+#else /* !CH_CURRP_REGISTER_CACHE */
+ stmfd sp!, {r4, r5, r6, r7, r8, r9, r10, r11, lr}
+ str sp, [r0, #16]
+ ldr sp, [r1, #16]
+#ifdef THUMB_PRESENT
+ ldmfd sp!, {r4, r5, r6, r7, r8, r9, r10, r11, lr}
+ bx lr
+#else /* !THUMB_PRESENT */
+ ldmfd sp!, {r4, r5, r6, r7, r8, r9, r10, r11, pc}
+#endif /* !THUMB_PRESENT */
+#endif /* !CH_CURRP_REGISTER_CACHE */
+
+/*
+ * Common exit point for all IRQ routines, it performs the rescheduling if
+ * required.
+ * System stack frame structure after a context switch in the
+ * interrupt handler:
+ *
+ * High +------------+
+ * | LR_USR | -+
+ * | R12 | |
+ * | R3 | |
+ * | R2 | | External context: IRQ handler frame
+ * | R1 | |
+ * | R0 | |
+ * | PC | | (user code return address)
+ * | PSR_USR | -+ (user code status)
+ * | .... | <- mk_DoRescheduleI() stack frame, optimize it for space
+ * | LR | -+ (system code return address)
+ * | R11 | |
+ * | R10 | |
+ * | R9 | |
+ * | R8 | | Internal context: mk_SwitchI() frame
+ * | (R7) | | (optional, see CH_CURRP_REGISTER_CACHE)
+ * | R6 | |
+ * | R5 | |
+ * SP-> | R4 | -+
+ * Low +------------+
+ */
+.balign 16
+#ifdef THUMB_NO_INTERWORKING
+.code 16
+.thumb_func
+.globl _port_irq_common
+_port_irq_common:
+ bl chSchRescRequiredI
+ mov lr, pc
+ bx lr
+.code 32
+#else /* !THUMB_NO_INTERWORKING */
+.code 32
+.globl _port_irq_common
+_port_irq_common:
+ bl chSchRescRequiredI
+#endif /* !THUMB_NO_INTERWORKING */
+ cmp r0, #0 // Simply returns if a
+ ldmeqfd sp!, {r0-r3, r12, lr} // reschedule is not
+ subeqs pc, lr, #4 // required.
+
+ // Saves the IRQ mode registers in the system stack.
+ ldmfd sp!, {r0-r3, r12, lr} // IRQ stack now empty.
+ msr CPSR_c, #MODE_SYS | I_BIT
+ stmfd sp!, {r0-r3, r12, lr} // Registers on System Stack.
+ msr CPSR_c, #MODE_IRQ | I_BIT
+ mrs r0, SPSR
+ mov r1, lr
+ msr CPSR_c, #MODE_SYS | I_BIT
+ stmfd sp!, {r0, r1} // Push R0=SPSR, R1=LR_IRQ.
+
+ // Context switch.
+#ifdef THUMB_NO_INTERWORKING
+ add r0, pc, #1
+ bx r0
+.code 16
+ bl chSchDoRescheduleI
+ mov lr, pc
+ bx lr
+.code 32
+#else /* !THUMB_NO_INTERWORKING */
+ bl chSchDoRescheduleI
+#endif /* !THUMB_NO_INTERWORKING */
+
+ // Re-establish the IRQ conditions again.
+ ldmfd sp!, {r0, r1} // Pop R0=SPSR, R1=LR_IRQ.
+ msr CPSR_c, #MODE_IRQ | I_BIT
+ msr SPSR_fsxc, r0
+ mov lr, r1
+ msr CPSR_c, #MODE_SYS | I_BIT
+ ldmfd sp!, {r0-r3, r12, lr}
+ msr CPSR_c, #MODE_IRQ | I_BIT
+ subs pc, lr, #4
+
+/*
+ * Threads trampoline code.
+ * NOTE: The threads always start in ARM mode then switch to the thread-function mode.
+ */
+.balign 16
+.code 32
+.globl _port_thread_start
+_port_thread_start:
+ msr CPSR_c, #MODE_SYS
+#ifndef THUMB_NO_INTERWORKING
+ mov r0, r5
+ mov lr, pc
+ bx r4
+ bl chThdExit
+#else /* !THUMB_NO_INTERWORKING */
+ add r0, pc, #1
+ bx r0
+.code 16
+ mov r0, r5
+ bl jmpr4
+ bl chThdExit
+jmpr4:
+ bx r4
+#endif /* !THUMB_NO_INTERWORKING */
+
+/** @endcond */
+/** @} */
diff --git a/os/ports/GCC/ARM7/chtypes.h b/os/ports/GCC/ARM7/chtypes.h
new file mode 100644
index 000000000..570c719da
--- /dev/null
+++ b/os/ports/GCC/ARM7/chtypes.h
@@ -0,0 +1,56 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT 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 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT 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, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file ports/ARM7/chtypes.h
+ * @brief ARM7 architecture port system types.
+ * @addtogroup ARM7_CORE
+ * @{
+ */
+
+#ifndef _CHTYPES_H_
+#define _CHTYPES_H_
+
+#define __need_NULL
+#define __need_size_t
+#define __need_ptrdiff_t
+#include <stddef.h>
+
+#if !defined(_STDINT_H) && !defined(__STDINT_H_)
+#include <stdint.h>
+#endif
+
+typedef int32_t bool_t; /**< Fast boolean type. */
+typedef uint8_t tmode_t; /**< Thread flags. */
+typedef uint8_t tstate_t; /**< Thread state. */
+typedef uint32_t tprio_t; /**< Thread priority. */
+typedef int32_t msg_t; /**< Inter-thread message. */
+typedef int32_t eventid_t; /**< Event Id. */
+typedef uint32_t eventmask_t; /**< Events mask. */
+typedef uint32_t systime_t; /**< System time. */
+typedef int32_t cnt_t; /**< Resources counter. */
+
+#define INLINE inline
+#define PACK_STRUCT_STRUCT __attribute__((packed))
+#define PACK_STRUCT_BEGIN
+#define PACK_STRUCT_END
+
+#endif /* _CHTYPES_H_ */
+
+/** @} */
diff --git a/os/ports/GCC/ARM7/crt0.lst b/os/ports/GCC/ARM7/crt0.lst
new file mode 100644
index 000000000..eed22b391
--- /dev/null
+++ b/os/ports/GCC/ARM7/crt0.lst
@@ -0,0 +1,218 @@
+GAS LISTING /cygdrive/c/DOCUME~1/Giovanni/IMPOST~1/Temp/ccgRWKd6.s page 1
+
+
+ 1 # 1 "../../os/ports/GCC/ARM7/crt0.s"
+ 2 # 1 "<built-in>"
+ 1 /*
+ 0
+ 0
+ 2 ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
+ 3
+ 4 This file is part of ChibiOS/RT.
+ 5
+ 6 ChibiOS/RT is free software; you can redistribute it and/or modify
+ 7 it under the terms of the GNU General Public License as published by
+ 8 the Free Software Foundation; either version 3 of the License, or
+ 9 (at your option) any later version.
+ 10
+ 11 ChibiOS/RT is distributed in the hope that it will be useful,
+ 12 but WITHOUT ANY WARRANTY; without even the implied warranty of
+ 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ 14 GNU General Public License for more details.
+ 15
+ 16 You should have received a copy of the GNU General Public License
+ 17 along with this program. If not, see <http://www.gnu.org/licenses/>.
+ 18 */
+ 19
+ 20 /**
+ 21 * @file ports/ARM7/crt0.s
+ 22 * @brief Generic ARM7 startup file for ChibiOS/RT.
+ 23 * @addtogroup ARM7_CORE
+ 24 * @{
+ 25 */
+ 26 /** @cond never */
+ 27
+ 28 .set MODE_USR, 0x10
+ 29 .set MODE_FIQ, 0x11
+ 30 .set MODE_IRQ, 0x12
+ 31 .set MODE_SVC, 0x13
+ 32 .set MODE_ABT, 0x17
+ 33 .set MODE_UND, 0x1B
+ 34 .set MODE_SYS, 0x1F
+ 35
+ 36 .equ I_BIT, 0x80
+ 37 .equ F_BIT, 0x40
+ 38
+ 39 .text
+ 40 .code 32
+ 41 .balign 4
+ 42
+ 43 /*
+ 44 * Reset handler.
+ 45 */
+ 46 .global ResetHandler
+ 47 ResetHandler:
+ 48 /*
+ 49 * Stack pointers initialization.
+ 50 */
+ 51 ldr r0, =__ram_end__
+ 52 /* Undefined */
+ 53 msr CPSR_c, #MODE_UND | I_BIT | F_BIT
+ GAS LISTING /cygdrive/c/DOCUME~1/Giovanni/IMPOST~1/Temp/ccgRWKd6.s page 2
+
+
+ 54 ???? 1040 0000 mov sp, r0
+ 55 ldr r1, =__und_stack_size__
+ 56 ???? 0080 sub r0, r0, r1
+ 57 /* Abort */
+ 58 msr CPSR_c, #MODE_ABT | I_BIT | F_BIT
+ 59 ???? 1040 0000 mov sp, r0
+ 60 ldr r1, =__abt_stack_size__
+ 61 ???? 0080 sub r0, r0, r1
+ 62 /* FIQ */
+ 63 msr CPSR_c, #MODE_FIQ | I_BIT | F_BIT
+ 64 ???? 1040 0000 mov sp, r0
+ 65 ldr r1, =__fiq_stack_size__
+ 66 ???? 0080 sub r0, r0, r1
+ 67 /* IRQ */
+ 68 msr CPSR_c, #MODE_IRQ | I_BIT | F_BIT
+ 69 ???? 1040 0000 mov sp, r0
+ 70 ldr r1, =__irq_stack_size__
+ 71 ???? 0080 sub r0, r0, r1
+ 72 /* Supervisor */
+ 73 msr CPSR_c, #MODE_SVC | I_BIT | F_BIT
+ 74 ???? 1040 0000 mov sp, r0
+ 75 ldr r1, =__svc_stack_size__
+ 76 ???? 0080 sub r0, r0, r1
+ 77 /* System */
+ 78 msr CPSR_c, #MODE_SYS | I_BIT | F_BIT
+ 79 ???? 1040 0000 mov sp, r0
+ 80 // ldr r1, =__sys_stack_size__
+ 81 // sub r0, r0, r1
+ 82 /*
+ 83 * Early initialization.
+ 84 */
+ 85 #ifndef THUMB_NO_INTERWORKING
+ 86 bl hwinit0
+ 87 #else
+ 88 add r0, pc, #1
+ 89 bx r0
+ 90 .code 16
+ 91 bl hwinit0
+ 92 mov r0, pc
+ 93 bx r0
+ 94 .code 32
+ 95 #endif
+ 96 /*
+ 97 * Data initialization.
+ 98 * NOTE: It assumes that the DATA size is a multiple of 4.
+ 99 */
+ 100 ldr r1, =_textdata
+ 101 ldr r2, =_data
+ 102 ldr r3, =_edata
+ 103 dataloop:
+ 104 ???? 0392 cmp r2, r3
+ 105 ldrlo r0, [r1], #4
+ 106 strlo r0, [r2], #4
+ 107 blo dataloop
+ 108 /*
+ 109 * BSS initialization.
+ 110 * NOTE: It assumes that the BSS size is a multiple of 4.
+ GAS LISTING /cygdrive/c/DOCUME~1/Giovanni/IMPOST~1/Temp/ccgRWKd6.s page 3
+
+
+ 111 */
+ 112 ???? 0340 mov r0, #0
+ 113 ldr r1, =_bss_start
+ 114 ldr r2, =_bss_end
+ 115 bssloop:
+ 116 ???? 0291 cmp r1, r2
+ 117 strlo r0, [r1], #4
+ 118 blo bssloop
+ 119 /*
+ 120 * Late initialization.
+ 121 */
+ 122 #ifdef THUMB_NO_INTERWORKING
+ 123 add r0, pc, #1
+ 124 bx r0
+ 125 .code 16
+ 126 bl hwinit1
+ 127 mov r0, #0
+ 128 mov r1, r0
+ 129 bl main
+ 130 ldr r1, =MainExitHandler
+ 131 bx r1
+ 132 .code 32
+ 133 #else
+ 134 bl hwinit1
+ 135 ???? 0340 mov r0, #0
+ 136 ???? 0041 mov r1, r0
+ 137 bl main
+ 138 b MainExitHandler
+ 139 #endif
+ 140
+ 141 /*
+ 142 * Default main function exit handler.
+ 143 */
+ 144 .weak MainExitHandler
+ 145 .globl MainExitHandler
+ 146 MainExitHandler:
+ 147
+ 148 .loop: b .loop
+ 149
+ 150 /*
+ 151 * Default early initialization code. It is declared weak in order to be
+ 152 * replaced by the real initialization code.
+ 153 * Early initialization is performed just after reset before BSS and DATA
+ 154 * segments initialization.
+ 155 */
+ 156 #ifdef THUMB_NO_INTERWORKING
+ 157 .thumb_func
+ 158 .code 16
+ 159 #endif
+ 160 .weak hwinit0
+ 161 hwinit0:
+ 162 bx lr
+ 163 .code 32
+ 164
+ 165 /*
+ 166 * Default late initialization code. It is declared weak in order to be
+ 167 * replaced by the real initialization code.
+ GAS LISTING /cygdrive/c/DOCUME~1/Giovanni/IMPOST~1/Temp/ccgRWKd6.s page 4
+
+
+ 168 * Late initialization is performed after BSS and DATA segments initialization
+ 169 * and before invoking the main() function.
+ 170 */
+ 171 #ifdef THUMB_NO_INTERWORKING
+ 172 .thumb_func
+ 173 .code 16
+ 174 #endif
+ 175 .weak hwinit1
+ 176 hwinit1:
+ 177 bx lr
+ 178 .code 32
+ GAS LISTING /cygdrive/c/DOCUME~1/Giovanni/IMPOST~1/Temp/ccgRWKd6.s page 5
+
+
+DEFINED SYMBOLS
+ *ABS*:00000000 ../../os/ports/GCC/ARM7/crt0.s
+../../os/ports/GCC/ARM7/crt0.s:28 *ABS*:00000010 MODE_USR
+../../os/ports/GCC/ARM7/crt0.s:29 *ABS*:00000011 MODE_FIQ
+../../os/ports/GCC/ARM7/crt0.s:30 *ABS*:00000012 MODE_IRQ
+../../os/ports/GCC/ARM7/crt0.s:31 *ABS*:00000013 MODE_SVC
+../../os/ports/GCC/ARM7/crt0.s:32 *ABS*:00000017 MODE_ABT
+../../os/ports/GCC/ARM7/crt0.s:33 *ABS*:0000001b MODE_UND
+../../os/ports/GCC/ARM7/crt0.s:34 *ABS*:0000001f MODE_SYS
+../../os/ports/GCC/ARM7/crt0.s:36 *ABS*:00000080 I_BIT
+../../os/ports/GCC/ARM7/crt0.s:37 *ABS*:00000040 F_BIT
+../../os/ports/GCC/ARM7/crt0.s:47 .text:00000000 ResetHandler
+../../os/ports/GCC/ARM7/crt0.s:103 .text:00000000 dataloop
+../../os/ports/GCC/ARM7/crt0.s:115 .text:00000000 bssloop
+../../os/ports/GCC/ARM7/crt0.s:146 .text:00000000 MainExitHandler
+../../os/ports/GCC/ARM7/crt0.s:148 .text:00000000 .loop
+../../os/ports/GCC/ARM7/crt0.s:161 .text:00000000 hwinit0
+../../os/ports/GCC/ARM7/crt0.s:176 .text:00000000 hwinit1
+
+UNDEFINED SYMBOLS
+sp
diff --git a/os/ports/GCC/ARM7/crt0.s b/os/ports/GCC/ARM7/crt0.s
new file mode 100644
index 000000000..91d07935b
--- /dev/null
+++ b/os/ports/GCC/ARM7/crt0.s
@@ -0,0 +1,181 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT 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 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT 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, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file ports/ARM7/crt0.s
+ * @brief Generic ARM7 startup file for ChibiOS/RT.
+ * @addtogroup ARM7_CORE
+ * @{
+ */
+/** @cond never */
+
+.set MODE_USR, 0x10
+.set MODE_FIQ, 0x11
+.set MODE_IRQ, 0x12
+.set MODE_SVC, 0x13
+.set MODE_ABT, 0x17
+.set MODE_UND, 0x1B
+.set MODE_SYS, 0x1F
+
+.equ I_BIT, 0x80
+.equ F_BIT, 0x40
+
+.text
+.code 32
+.balign 4
+
+/*
+ * Reset handler.
+ */
+.global ResetHandler
+ResetHandler:
+ /*
+ * Stack pointers initialization.
+ */
+ ldr r0, =__ram_end__
+ /* Undefined */
+ msr CPSR_c, #MODE_UND | I_BIT | F_BIT
+ mov sp, r0
+ ldr r1, =__und_stack_size__
+ sub r0, r0, r1
+ /* Abort */
+ msr CPSR_c, #MODE_ABT | I_BIT | F_BIT
+ mov sp, r0
+ ldr r1, =__abt_stack_size__
+ sub r0, r0, r1
+ /* FIQ */
+ msr CPSR_c, #MODE_FIQ | I_BIT | F_BIT
+ mov sp, r0
+ ldr r1, =__fiq_stack_size__
+ sub r0, r0, r1
+ /* IRQ */
+ msr CPSR_c, #MODE_IRQ | I_BIT | F_BIT
+ mov sp, r0
+ ldr r1, =__irq_stack_size__
+ sub r0, r0, r1
+ /* Supervisor */
+ msr CPSR_c, #MODE_SVC | I_BIT | F_BIT
+ mov sp, r0
+ ldr r1, =__svc_stack_size__
+ sub r0, r0, r1
+ /* System */
+ msr CPSR_c, #MODE_SYS | I_BIT | F_BIT
+ mov sp, r0
+// ldr r1, =__sys_stack_size__
+// sub r0, r0, r1
+ /*
+ * Early initialization.
+ */
+#ifndef THUMB_NO_INTERWORKING
+ bl hwinit0
+#else
+ add r0, pc, #1
+ bx r0
+.code 16
+ bl hwinit0
+ mov r0, pc
+ bx r0
+.code 32
+#endif
+ /*
+ * Data initialization.
+ * NOTE: It assumes that the DATA size is a multiple of 4.
+ */
+ ldr r1, =_textdata
+ ldr r2, =_data
+ ldr r3, =_edata
+dataloop:
+ cmp r2, r3
+ ldrlo r0, [r1], #4
+ strlo r0, [r2], #4
+ blo dataloop
+ /*
+ * BSS initialization.
+ * NOTE: It assumes that the BSS size is a multiple of 4.
+ */
+ mov r0, #0
+ ldr r1, =_bss_start
+ ldr r2, =_bss_end
+bssloop:
+ cmp r1, r2
+ strlo r0, [r1], #4
+ blo bssloop
+ /*
+ * Late initialization.
+ */
+#ifdef THUMB_NO_INTERWORKING
+ add r0, pc, #1
+ bx r0
+.code 16
+ bl hwinit1
+ mov r0, #0
+ mov r1, r0
+ bl main
+ ldr r1, =MainExitHandler
+ bx r1
+.code 32
+#else
+ bl hwinit1
+ mov r0, #0
+ mov r1, r0
+ bl main
+ b MainExitHandler
+#endif
+
+/*
+ * Default main function exit handler.
+ */
+.weak MainExitHandler
+.globl MainExitHandler
+MainExitHandler:
+
+.loop: b .loop
+
+/*
+ * Default early initialization code. It is declared weak in order to be
+ * replaced by the real initialization code.
+ * Early initialization is performed just after reset before BSS and DATA
+ * segments initialization.
+ */
+#ifdef THUMB_NO_INTERWORKING
+.thumb_func
+.code 16
+#endif
+.weak hwinit0
+hwinit0:
+ bx lr
+.code 32
+
+/*
+ * Default late initialization code. It is declared weak in order to be
+ * replaced by the real initialization code.
+ * Late initialization is performed after BSS and DATA segments initialization
+ * and before invoking the main() function.
+ */
+#ifdef THUMB_NO_INTERWORKING
+.thumb_func
+.code 16
+#endif
+.weak hwinit1
+hwinit1:
+ bx lr
+.code 32
+
+/** @endcond */
+/** @} */
diff --git a/os/ports/GCC/ARM7/port.dox b/os/ports/GCC/ARM7/port.dox
new file mode 100644
index 000000000..780c57083
--- /dev/null
+++ b/os/ports/GCC/ARM7/port.dox
@@ -0,0 +1,200 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT 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 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT 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, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @defgroup ARM7 ARM7TDMI
+ * @details The ARM7 architecture is quite complex for a microcontroller and
+ * some explanations are required about the port choices.
+ *
+ * @section ARM7_NOTES The ARM7 modes
+ * The ARM7 port supports three modes:
+ * - Pure ARM mode, this is the preferred mode for code speed. The code size
+ * is larger however. This mode is enabled when all the modules are compiled
+ * in ARM mode, see the Makefiles.
+ * - Pure THUMB mode, this is the preferred mode for code size. In this mode
+ * the execution speed is slower than the ARM mode. This mode is enabled
+ * when all the modules are compiled in THUMB mode, see the Makefiles.
+ * - Interworking mode, when in the system there are ARM modules mixed with
+ * THUMB modules then the interworking compiler option is enabled. This is
+ * usually the slowest mode and the code size is not as good as in pure
+ * THUMB mode.
+ * .
+ * @section ARM7_STATES Mapping of the System States in the ARM7 port
+ * The ChibiOS/RT logical @ref system_states are mapped as follow in the ARM7
+ * port:
+ * - <b>Init</b>. This state is represented by the startup code and the
+ * initialization code before @p chSysInit() is executed. It has not a
+ * special hardware state associated, usually the CPU goes through several
+ * hardware states during the startup phase.
+ * - <b>Normal</b>. This is the state the system has after executing
+ * @p chSysInit(). In this state the ARM7TDMI has both the interrupt sources
+ * (IRQ and FIQ) enabled and is running in ARM System Mode.
+ * - <b>Suspended</b>. In this state the IRQ sources are disabled but the FIQ
+ * sources are served, the core is running in ARM System Mode.
+ * - <b>Disabled</b>. Both the IRQ and FIQ sources are disabled, the core is
+ * running in ARM System Mode.
+ * - <b>Sleep</b>. The ARM7 code does not have any built-in low power mode but
+ * there are clock stop modes implemented in custom ways by the various
+ * silicon vendors. This state is implemented in each microcontroller support
+ * code in a different way, the core is running (or freezed...) in ARM
+ * System Mode.
+ * - <b>S-Locked</b>. IRQ sources disabled, core running in ARM System Mode.
+ * - <b>I-Locked</b>. IRQ sources disabled, core running in ARM IRQ Mode. Note
+ * that this state is not different from the SRI state in this port, the
+ * @p chSysLockI() and @p chSysUnlockI() APIs do nothing (still use them in
+ * order to formally change state because this may change).
+ * - <b>Serving Regular Interrupt</b>. IRQ sources disabled, core running in
+ * ARM IRQ Mode. See also the I-Locked state.
+ * - <b>Serving Fast Interrupt</b>. IRQ and FIQ sources disabled, core running
+ * in ARM FIQ Mode.
+ * - <b>Serving Non-Maskable Interrupt</b>. There are no asynchronous NMI
+ * sources in ARM7 architecture but synchronous SVC, ABT and UND exception
+ * handlers can be seen as belonging to this category.
+ * - <b>Halted</b>. Implemented as an infinite loop after disabling both IRQ
+ * and FIQ sources. The ARM state is whatever the processor was running when
+ * @p chSysHalt() was invoked.
+ * .
+ * @section ARM7_NOTES The ARM7 port notes
+ * The ARM7 port makes some assumptions on the application code organization:
+ * - The @p main() function is invoked in system mode.
+ * - Each thread has a private user/system stack, the system has a single
+ * interrupt stack where all the interrupts are processed.
+ * - The threads are started in system mode.
+ * - The threads code can run in system mode or user mode, however the
+ * code running in user mode cannot invoke the ChibiOS/RT APIs directly
+ * because privileged instructions are used inside.<br>
+ * The kernel APIs can be eventually invoked by using a SWI entry point
+ * that handles the switch in system mode and the return in user mode.
+ * - Other modes are not preempt-able because the system code assumes the
+ * threads running in system mode. When running in supervisor or other
+ * modes make sure that the interrupts are globally disabled.
+ * - Interrupts nesting is not supported in the ARM7 code because their
+ * implementation, even if possible, is not really efficient in this
+ * architecture.
+ * - FIQ sources can preempt the kernel (by design) so it is not possible to
+ * invoke the kernel APIs from inside a FIQ handler. FIQ handlers are not
+ * affected by the kernel activity so there is not added jitter.
+ * .
+ * @section ARM7_IH ARM7 Interrupt Handlers
+ * ARM7 Interrupt handlers do not save function-saved registers so you need to
+ * make sure your code saves them or does not use them (this happens
+ * because in the ARM7 port all the OS interrupt handler functions are declared
+ * naked).<br>
+ * Function-trashed registers (R0-R3, R12, LR, SR) are saved/restored by the
+ * system macros @p CH_IRQ_PROLOGUE() and @p CH_IRQ_EPILOGUE().<br>
+ * The easiest way to ensure this is to just invoke a normal function from
+ * within the interrupt handler, the function code will save all the required
+ * registers.<br>
+ * Example:
+ * @code
+ * CH_IRQ_HANDLER(irq_handler) {
+ * CH_IRQ_PROLOGUE();
+ *
+ * serve_interrupt();
+ *
+ * VICVectAddr = 0; // This is LPC214x-specific.
+ * CH_IRQ_EPILOGUE();
+ * }
+ * @endcode
+ * This is not a bug but an implementation choice, this solution allows to
+ * have interrupt handlers compiled in thumb mode without have to use an
+ * interworking mode (the mode switch is hidden in the macros), this
+ * greatly improves code efficiency and size. You can look at the serial
+ * driver for real examples of interrupt handlers.
+ *
+ * @ingroup Ports
+ */
+
+/**
+ * @defgroup ARM7_CONF Configuration Options
+ * @brief ARM7 specific configuration options.
+ * @details The ARM7 port allows some architecture-specific configurations
+ * settings that can be specified externally, as example on the compiler
+ * command line:
+ * - @p INT_REQUIRED_STACK, this value represent the amount of stack space used
+ * by an interrupt handler between the @p extctx and @p intctx
+ * structures.<br>
+ * In practice this value is the stack space used by the chSchDoReschedule()
+ * stack frame.<br>
+ * This value can be affected by a variety of external things like compiler
+ * version, compiler options, kernel settings (speed/size) and so on.<br>
+ * The default for this value is @p 0x10 which should be a safe value, you
+ * can trim this down by defining the macro externally. This would save
+ * some valuable RAM space for each thread present in the system.<br>
+ * The default value is set into <b>./ports/ARM7/chcore.h</b>.
+ * .
+ * @ingroup ARM7
+ */
+
+/**
+ * @defgroup ARM7_CORE Core Port Implementation
+ * @brief ARM7 specific port code, structures and macros.
+ *
+ * @ingroup ARM7
+ * @file ports/ARM7/chtypes.h Port types.
+ * @file ports/ARM7/chcore.h Port related structures and macros.
+ * @file ports/ARM7/chcore.c Port related code.
+ */
+
+/**
+ * @defgroup ARM7_STARTUP Startup Support
+ * @brief ARM7 startup code support.
+ * @details ChibiOS/RT provides its own generic startup file for the ARM7 port.
+ * Of course it is not mandatory to use it but care should be taken about the
+ * startup phase details.
+ *
+ * <h2>Startup Process</h2>
+ * The startup process, as implemented, is the following:
+ * -# The stacks are initialized by assigning them the sizes defined in the
+ * linker script (usually named @p ch.ld). Stack areas are allocated from
+ * the highest RAM location downward.
+ * -# The ARM state is switched to System with both IRQ and FIQ sources
+ * disabled.
+ * -# An early initialization routine @p hwinit0 is invoked, if the symbol is
+ * not defined then an empty default routine is executed (weak symbol).
+ * -# DATA and BSS segments are initialized.
+ * -# A late initialization routine @p hwinit1 is invoked, if the symbol not
+ * defined then an empty default routine is executed (weak symbol).<br>
+ * This late initialization function is also the proper place for a
+ * @a bootloader, if your application requires one.
+ * -# The @p main() function is invoked with the parameters @p argc and @p argv
+ * set to zero.
+ * -# Should the @p main() function return a branch is performed to the weak
+ * symbol MainExitHandler. The default code is an endless empty loop.
+ * .
+ * <h2>Expected linker symbols</h2>
+ * The startup code starts at the symbol @p ResetHandler and expects the
+ * following symbols to be defined in the linker script:
+ * - @p __ram_end__ RAM end location +1.
+ * - @p __und_stack_size__ Undefined Instruction stack size.
+ * - @p __abt_stack_size__ Memory Abort stack size.
+ * - @p __fiq_stack_size__ FIQ service stack size.
+ * - @p __irq_stack_size__ IRQ service stack size.
+ * - @p __svc_stack_size__ SVC service stack size.
+ * - @p __sys_stack_size__ System/User stack size. This is the stack area used
+ * by the @p main() function.
+ * - @p _textdata address of the data segment source read only data.
+ * - @p _data data segment start location.
+ * - @p _edata data segment end location +1.
+ * - @p _bss_start BSS start location.
+ * - @p _bss_end BSS end location +1.
+ * .
+ * @ingroup ARM7
+ * @file ports/ARM7/crt0.s Startup code.
+ */
diff --git a/os/ports/GCC/ARM7/port.mk b/os/ports/GCC/ARM7/port.mk
new file mode 100644
index 000000000..d81135981
--- /dev/null
+++ b/os/ports/GCC/ARM7/port.mk
@@ -0,0 +1,7 @@
+# List of the ChibiOS/RT Cortex-M3 port files.
+PORTSRC = ../../os/ports/GCC/ARM7/chcore.c
+
+PORTASM = ../../os/ports/GCC/ARM7/crt0.s \
+ ../../os/ports/GCC/ARM7/chcoreasm.s
+
+PORTINC = ../../os/ports/GCC/ARM7
diff --git a/os/ports/GCC/ARMCM3/STM32F103/pal_lld.c b/os/ports/GCC/ARMCM3/STM32F103/pal_lld.c
new file mode 100644
index 000000000..00688845d
--- /dev/null
+++ b/os/ports/GCC/ARMCM3/STM32F103/pal_lld.c
@@ -0,0 +1,158 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT 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 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT 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, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file ports/ARMCM3-STM32F103/pal_lld.c
+ * @brief STM32 GPIO low level driver code
+ * @addtogroup STM32F103_PAL
+ * @{
+ */
+
+#include <ch.h>
+#include <pal.h>
+
+#if defined(STM32F10X_LD)
+#define APB2_RST_MASK (RCC_APB2RSTR_IOPARST | RCC_APB2RSTR_IOPBRST | \
+ RCC_APB2RSTR_IOPCRST | RCC_APB2RSTR_IOPDRST | \
+ RCC_APB2RSTR_AFIORST)
+#define APB2_EN_MASK (RCC_APB2ENR_IOPAEN | RCC_APB2ENR_IOPBEN | \
+ RCC_APB2ENR_IOPCEN | RCC_APB2ENR_IOPDEN | \
+ RCC_APB2ENR_AFIOEN)
+#elif defined(STM32F10X_HD)
+#define APB2_RST_MASK (RCC_APB2RSTR_IOPARST | RCC_APB2RSTR_IOPBRST | \
+ RCC_APB2RSTR_IOPCRST | RCC_APB2RSTR_IOPDRST | \
+ RCC_APB2RSTR_IOPERST | RCC_APB2RSTR_IOPFRST | \
+ RCC_APB2RSTR_IOPGRST | RCC_APB2RSTR_AFIORST);
+#define APB2_EN_MASK (RCC_APB2ENR_IOPAEN | RCC_APB2ENR_IOPBEN | \
+ RCC_APB2ENR_IOPCEN | RCC_APB2ENR_IOPDEN | \
+ RCC_APB2ENR_IOPEEN | RCC_APB2ENR_IOPFEN | \
+ RCC_APB2ENR_IOPGEN | RCC_APB2ENR_AFIOEN)
+#else
+ /* Defaults on Medium Density devices.*/
+#define APB2_RST_MASK (RCC_APB2RSTR_IOPARST | RCC_APB2RSTR_IOPBRST | \
+ RCC_APB2RSTR_IOPCRST | RCC_APB2RSTR_IOPDRST | \
+ RCC_APB2RSTR_IOPERST | RCC_APB2RSTR_AFIORST);
+#define APB2_EN_MASK (RCC_APB2ENR_IOPAEN | RCC_APB2ENR_IOPBEN | \
+ RCC_APB2ENR_IOPCEN | RCC_APB2ENR_IOPDEN | \
+ RCC_APB2ENR_IOPEEN | RCC_APB2ENR_AFIOEN)
+#endif
+
+/**
+ * @brief STM32 I/O ports configuration.
+ * @details Ports A-D(E, F, G) clocks enabled, AFIO clock enabled.
+ *
+ * @param[in] config the STM32 ports configuration
+ */
+void _pal_lld_init(const STM32GPIOConfig *config) {
+
+ /*
+ * Enables the GPIO related clocks.
+ */
+ RCC->APB2ENR |= APB2_EN_MASK;
+
+ /*
+ * Resets the GPIO ports and AFIO.
+ */
+ RCC->APB2RSTR = APB2_RST_MASK;
+ RCC->APB2RSTR = 0;
+
+ IOPORT_A->ODR = config->PAData.odr;
+ IOPORT_A->CRH = config->PAData.crh;
+ IOPORT_A->CRL = config->PAData.crl;
+ IOPORT_B->ODR = config->PBData.odr;
+ IOPORT_B->CRH = config->PBData.crh;
+ IOPORT_B->CRL = config->PBData.crl;
+ IOPORT_C->ODR = config->PCData.odr;
+ IOPORT_C->CRH = config->PCData.crh;
+ IOPORT_C->CRL = config->PCData.crl;
+ IOPORT_D->ODR = config->PDData.odr;
+ IOPORT_D->CRH = config->PDData.crh;
+ IOPORT_D->CRL = config->PDData.crl;
+#if !defined(STM32F10X_LD) || defined(__DOXYGEN__)
+ IOPORT_E->ODR = config->PEData.odr;
+ IOPORT_E->CRH = config->PEData.crh;
+ IOPORT_E->CRL = config->PEData.crl;
+#endif
+#if defined(STM32F10X_HD) || defined(__DOXYGEN__)
+ IOPORT_F->ODR = config->PFData.odr;
+ IOPORT_F->CRH = config->PFData.crh;
+ IOPORT_F->CRL = config->PFData.crl;
+ IOPORT_G->ODR = config->PGData.odr;
+ IOPORT_G->CRH = config->PGData.crh;
+ IOPORT_G->CRL = config->PGData.crl;
+#endif
+}
+
+/**
+ * @brief Pads mode setup.
+ * @details This function programs a pads group belonging to the same port
+ * with the specified mode.
+ *
+ * @param[in] port the port identifier
+ * @param[in] mask the group mask
+ * @param[in] mode the mode
+ *
+ * @note This function is not meant to be invoked directly by the application
+ * code.
+ * @note @p PAL_MODE_UNCONNECTED is implemented as push pull output at 2MHz.
+ * @note Writing on pads programmed as pull-up or pull-down has the side
+ * effect to modify the resistor setting because the output latched data
+ * is used for the resistor selection.
+ */
+void _pal_lld_setgroupmode(ioportid_t port,
+ ioportmask_t mask,
+ uint_fast8_t mode) {
+ static const uint8_t cfgtab[] = {
+ 4, /* PAL_MODE_RESET, implemented as input.*/
+ 2, /* PAL_MODE_UNCONNECTED, implemented as push pull output 2MHz.*/
+ 4, /* PAL_MODE_INPUT */
+ 8, /* PAL_MODE_INPUT_PULLUP */
+ 8, /* PAL_MODE_INPUT_PULLDOWN */
+ 3, /* PAL_MODE_OUTPUT_PUSHPULL, 50MHz.*/
+ 7, /* PAL_MODE_OUTPUT_OPENDRAIN, 50MHz.*/
+ };
+ uint32_t mh, ml, crh, crl, cfg;
+ unsigned i;
+
+ if (mode == PAL_MODE_INPUT_PULLUP)
+ port->BSRR = mask;
+ else if (mode == PAL_MODE_INPUT_PULLDOWN)
+ port->BRR = mask;
+ cfg = cfgtab[mode];
+ mh = ml = crh = crl = 0;
+ for (i = 0; i < 8; i++) {
+ ml <<= 4;
+ mh <<= 4;
+ crl <<= 4;
+ crh <<= 4;
+ if ((mask & 1) == 0)
+ ml |= 0xf;
+ else
+ crl |= cfg;
+ if ((mask & 0x10000) == 0)
+ mh |= 0xf;
+ else
+ crh |= cfg;
+ mask >>= 1;
+ }
+ port->CRH = (port->CRH & mh) | crh;
+ port->CRL = (port->CRL & ml) | crl;
+}
+
+/** @} */
diff --git a/os/ports/GCC/ARMCM3/STM32F103/pal_lld.h b/os/ports/GCC/ARMCM3/STM32F103/pal_lld.h
new file mode 100644
index 000000000..9c66ab232
--- /dev/null
+++ b/os/ports/GCC/ARMCM3/STM32F103/pal_lld.h
@@ -0,0 +1,307 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT 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 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT 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, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file ports/ARMCM3-STM32F103/pal_lld.h
+ * @brief STM32 GPIO low level driver header
+ * @addtogroup STM32F103_PAL
+ * @{
+ */
+
+#ifndef _PAL_LLD_H_
+#define _PAL_LLD_H_
+
+/*
+ * Tricks required to make the TRUE/FALSE declaration inside the library
+ * compatible.
+ */
+#ifndef __STM32F10x_H
+#undef FALSE
+#undef TRUE
+#include <stm32f10x.h>
+#define FALSE 0
+#define TRUE (!FALSE)
+#endif
+
+/*===========================================================================*/
+/* I/O Ports Types and constants. */
+/*===========================================================================*/
+
+/**
+ * @brief GPIO port setup info.
+ */
+typedef struct {
+ /** Initial value for ODR register.*/
+ uint32_t odr;
+ /** Initial value for CRL register.*/
+ uint32_t crl;
+ /** Initial value for CRH register.*/
+ uint32_t crh;
+} stm32_gpio_setup_t;
+
+/**
+ * @brief STM32 GPIO static initializer.
+ * @details An instance of this structure must be passed to @p palInit() at
+ * system startup time in order to initialized the digital I/O
+ * subsystem. This represents only the initial setup, specific pads
+ * or whole ports can be reprogrammed at later time.
+ */
+typedef struct {
+ /** @brief Port A setup data.*/
+ stm32_gpio_setup_t PAData;
+ /** @brief Port B setup data.*/
+ stm32_gpio_setup_t PBData;
+ /** @brief Port C setup data.*/
+ stm32_gpio_setup_t PCData;
+ /** @brief Port D setup data.*/
+ stm32_gpio_setup_t PDData;
+#if !defined(STM32F10X_LD) || defined(__DOXYGEN__)
+ /** @brief Port E setup data.*/
+ stm32_gpio_setup_t PEData;
+#endif
+#if defined(STM32F10X_HD) || defined(__DOXYGEN__)
+ /** @brief Port F setup data.*/
+ stm32_gpio_setup_t PFData;
+ /** @brief Port G setup data.*/
+ stm32_gpio_setup_t PGData;
+#endif
+} STM32GPIOConfig;
+
+/**
+ * @brief Width, in bits, of an I/O port.
+ */
+#define PAL_IOPORTS_WIDTH 16
+
+/**
+ * @brief Whole port mask.
+ * @brief This macro specifies all the valid bits into a port.
+ */
+#define PAL_WHOLE_PORT ((ioportmask_t)0xFFFF)
+
+/**
+ * @brief Digital I/O port sized unsigned type.
+ */
+typedef uint32_t ioportmask_t;
+
+/**
+ * @brief Port Identifier.
+ * @details This type can be a scalar or some kind of pointer, do not make
+ * any assumption about it, use the provided macros when populating
+ * variables of this type.
+ */
+typedef GPIO_TypeDef * ioportid_t;
+
+/*===========================================================================*/
+/* I/O Ports Identifiers. */
+/* The low level driver wraps the definitions already present in the STM32 */
+/* firmware library. */
+/*===========================================================================*/
+
+/**
+ * @brief GPIO port A identifier.
+ */
+#define IOPORT_A GPIOA
+
+/**
+ * @brief GPIO port B identifier.
+ */
+#define IOPORT_B GPIOB
+
+/**
+ * @brief GPIO port C identifier.
+ */
+#define IOPORT_C GPIOC
+
+/**
+ * @brief GPIO port D identifier.
+ */
+#define IOPORT_D GPIOD
+
+/**
+ * @brief GPIO port E identifier.
+ */
+#if !defined(STM32F10X_LD) || defined(__DOXYGEN__)
+#define IOPORT_E GPIOE
+#endif
+
+/**
+ * @brief GPIO port F identifier.
+ */
+#if defined(STM32F10X_HD) || defined(__DOXYGEN__)
+#define IOPORT_F GPIOF
+
+/**
+ * @brief GPIO port G identifier.
+ */
+#define IOPORT_G GPIOG
+#endif
+
+/*===========================================================================*/
+/* Implementation, some of the following macros could be implemented as */
+/* functions, please put them in a file named ioports_lld.c if so. */
+/*===========================================================================*/
+
+/**
+ * @brief GPIO ports subsystem initialization.
+ */
+#define pal_lld_init(config) _pal_lld_init(config)
+
+/**
+ * @brief Reads an I/O port.
+ * @details This function is implemented by reading the GPIO IDR register, the
+ * implementation has no side effects.
+ *
+ * @param[in] port the port identifier
+ * @return the port bits
+ *
+ * @note This function is not meant to be invoked directly by the application
+ * code.
+ */
+#define pal_lld_readport(port) ((port)->IDR)
+
+/**
+ * @brief Reads the output latch.
+ * @details This function is implemented by reading the GPIO ODR register, the
+ * implementation has no side effects.
+ *
+ * @param[in] port the port identifier
+ * @return The latched logical states.
+ *
+ * @note This function is not meant to be invoked directly by the application
+ * code.
+ */
+#define pal_lld_readlatch(port) ((port)->ODR)
+
+/**
+ * @brief Writes on a I/O port.
+ * @details This function is implemented by writing the GPIO ODR register, the
+ * implementation has no side effects.
+ *
+ * @param[in] port the port identifier
+ * @param[in] bits the bits to be written on the specified port
+ *
+ * @note This function is not meant to be invoked directly by the application
+ * code.
+ * @note Writing on pads programmed as pull-up or pull-down has the side
+ * effect to modify the resistor setting because the output latched data
+ * is used for the resistor selection.
+ */
+#define pal_lld_writeport(port, bits) ((port)->ODR = (bits))
+
+/**
+ * @brief Sets a bits mask on a I/O port.
+ * @details This function is implemented by writing the GPIO BSRR register, the
+ * implementation has no side effects.
+ *
+ * @param[in] port the port identifier
+ * @param[in] bits the bits to be ORed on the specified port
+ *
+ * @note This function is not meant to be invoked directly by the application
+ * code.
+ * @note Writing on pads programmed as pull-up or pull-down has the side
+ * effect to modify the resistor setting because the output latched data
+ * is used for the resistor selection.
+ */
+#define pal_lld_setport(port, bits) ((port)->BSRR = (bits))
+
+/**
+ * @brief Clears a bits mask on a I/O port.
+ * @details This function is implemented by writing the GPIO BRR register, the
+ * implementation has no side effects.
+ *
+ * @param[in] port the port identifier
+ * @param[in] bits the bits to be cleared on the specified port
+ *
+ * @note This function is not meant to be invoked directly by the application
+ * code.
+ * @note Writing on pads programmed as pull-up or pull-down has the side
+ * effect to modify the resistor setting because the output latched data
+ * is used for the resistor selection.
+ */
+#define pal_lld_clearport(port, bits) ((port)->BRR = (bits))
+
+/**
+ * @brief Writes a group of bits.
+ * @details This function is implemented by writing the GPIO BSRR register, the
+ * implementation has no side effects.
+ *
+ * @param[in] port the port identifier
+ * @param[in] mask the group mask
+ * @param[in] offset the group bit offset within the port
+ * @param[in] bits the bits to be written. Values exceeding the group width
+ * are masked.
+ *
+ * @note This function is not meant to be invoked directly by the application
+ * code.
+ * @note Writing on pads programmed as pull-up or pull-down has the side
+ * effect to modify the resistor setting because the output latched data
+ * is used for the resistor selection.
+ */
+#define pal_lld_writegroup(port, mask, offset, bits) { \
+ (port)->BSRR = ((~(bits) & (mask)) << (16 + (offset))) | \
+ (((bits) & (mask)) << (offset)); \
+}
+
+/**
+ * @brief Pads group mode setup.
+ * @details This function programs a pads group belonging to the same port
+ * with the specified mode.
+ *
+ * @param[in] port the port identifier
+ * @param[in] mask the group mask
+ * @param[in] mode the mode
+ *
+ * @note This function is not meant to be invoked directly by the application
+ * code.
+ * @note Writing on pads programmed as pull-up or pull-down has the side
+ * effect to modify the resistor setting because the output latched data
+ * is used for the resistor selection.
+ */
+#define pal_lld_setgroupmode(port, mask, mode) \
+ _pal_lld_setgroupmode(port, mask, mode)
+
+/**
+ * @brief Writes a logical state on an output pad.
+ *
+ * @param[in] port the port identifier
+ * @param[in] pad the pad number within the port
+ * @param[out] bit the logical value, the value must be @p 0 or @p 1
+ *
+ * @note This function is not meant to be invoked directly by the application
+ * code.
+ * @note Writing on pads programmed as pull-up or pull-down has the side
+ * effect to modify the resistor setting because the output latched data
+ * is used for the resistor selection.
+ */
+#define pal_lld_writepad(port, pad, bit) pal_lld_writegroup(port, 1, pad, bit)
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void _pal_lld_init(const STM32GPIOConfig *config);
+ void _pal_lld_setgroupmode(ioportid_t port,
+ ioportmask_t mask,
+ uint_fast8_t mode);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _PAL_LLD_H_ */
+
+/** @} */
diff --git a/os/ports/GCC/ARMCM3/STM32F103/port.dox b/os/ports/GCC/ARMCM3/STM32F103/port.dox
new file mode 100644
index 000000000..b1828425c
--- /dev/null
+++ b/os/ports/GCC/ARMCM3/STM32F103/port.dox
@@ -0,0 +1,72 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT 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 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT 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, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @defgroup STM32F103 STM32F103 Support
+ * @brief STM32F103 specific support.
+ * @details The STM32F103 support includes:
+ * - I/O ports driver.
+ * - Buffered, interrupt driven, serial driver.
+ * - A demo supporting the kernel test suite.
+ * .
+ * @ingroup ARMCM3
+ */
+
+/**
+ * @defgroup STM32F103_PAL I/O Ports Support
+ * @brief I/O Ports peripherals support.
+ * @details This module supports the STM32F103 GPIO controller. The controller
+ * supports the following features (see @ref PAL):
+ * - 16 bits wide ports.
+ * - Atomic set/reset functions.
+ * - Atomic set+reset function (atomic bus operations).
+ * - Output latched regardless of the pad setting.
+ * - Direct read of input pads regardless of the pad setting.
+ * .
+ * <h2>Supported Setup Modes</h2>
+ * - @p PAL_MODE_RESET.
+ * - @p PAL_MODE_UNCONNECTED.
+ * - @p PAL_MODE_INPUT.
+ * - @p PAL_MODE_INPUT_PULLUP.
+ * - @p PAL_MODE_INPUT_PULLDOWN.
+ * - @p PAL_MODE_OUTPUT_PUSHPULL.
+ * - @p PAL_MODE_OUTPUT_OPENDRAIN.
+ * .
+ * Any attempt to setup an invalid mode is ignored.
+ *
+ * <h2>Suboptimal Behavior</h2>
+ * Some GPIO features are less than optimal:
+ * - Pad/port toggling operations are not atomic.
+ * - Pad/group mode setup is not atomic.
+ * - Writing on pads/groups/ports programmed as input with pull-up/down
+ * resistor can change the resistor setting because the output latch is
+ * used for resistor selection.
+ * .
+ * @ingroup STM32F103
+ */
+
+/**
+ * @defgroup STM32F103_SERIAL USART Support
+ * @brief USART peripherals support.
+ * @details The serial driver supports the STM32F103 USARTs in asynchronous
+ * mode.
+ *
+ * @ingroup STM32F103
+ */
+ \ No newline at end of file
diff --git a/os/ports/GCC/ARMCM3/STM32F103/stm32_can.c b/os/ports/GCC/ARMCM3/STM32F103/stm32_can.c
new file mode 100644
index 000000000..a5f343dee
--- /dev/null
+++ b/os/ports/GCC/ARMCM3/STM32F103/stm32_can.c
@@ -0,0 +1,27 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT 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 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT 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, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file ports/ARMCM3-STM32F103/stm32_can.c
+ * @brief STM32 CAN driver code
+ * @addtogroup STM32F103_CAN
+ * @{
+ */
+
+/** @} */
diff --git a/os/ports/GCC/ARMCM3/STM32F103/stm32_can.h b/os/ports/GCC/ARMCM3/STM32F103/stm32_can.h
new file mode 100644
index 000000000..69515758d
--- /dev/null
+++ b/os/ports/GCC/ARMCM3/STM32F103/stm32_can.h
@@ -0,0 +1,48 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT 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 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT 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, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file ports/ARMCM3-STM32F103/stm32_can.h
+ * @brief STM32 CAN driver header file
+ * @addtogroup STM32F103_CAN
+ * @{
+ */
+
+#ifndef _STM32_CAN_H_
+#define _STM32_CAN_H_
+
+typedef struct {
+} CANConfig;
+
+typedef struct {
+} CANMessage;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void canInit(CANConfig *config);
+ bool_t canReceive(CANMessage *canmsg);
+ bool_t canTransmit(CANMessage *canmsg);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _STM32_CAN_H_ */
+
+/** @} */
diff --git a/os/ports/GCC/ARMCM3/STM32F103/stm32_serial.c b/os/ports/GCC/ARMCM3/STM32F103/stm32_serial.c
new file mode 100644
index 000000000..4634d82a8
--- /dev/null
+++ b/os/ports/GCC/ARMCM3/STM32F103/stm32_serial.c
@@ -0,0 +1,222 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT 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 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT 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, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file ports/ARMCM3-STM32F103/stm32_serial.c
+ * @brief STM32F103 Serial driver code.
+ * @addtogroup STM32F103_SERIAL
+ * @{
+ */
+
+#include <ch.h>
+
+#include "board.h"
+#include "nvic.h"
+#include "stm32_serial.h"
+
+#if USE_STM32_USART1 || defined(__DOXYGEN__)
+/** @brief USART1 serial driver identifier.*/
+FullDuplexDriver COM1;
+
+static uint8_t ib1[SERIAL_BUFFERS_SIZE];
+static uint8_t ob1[SERIAL_BUFFERS_SIZE];
+#endif
+
+#if USE_STM32_USART2 || defined(__DOXYGEN__)
+/** @brief USART2 serial driver identifier.*/
+FullDuplexDriver COM2;
+
+static uint8_t ib2[SERIAL_BUFFERS_SIZE];
+static uint8_t ob2[SERIAL_BUFFERS_SIZE];
+#endif
+
+#if USE_STM32_USART3 || defined(__DOXYGEN__)
+/** @brief USART3 serial driver identifier.*/
+FullDuplexDriver COM3;
+
+static uint8_t ib3[SERIAL_BUFFERS_SIZE];
+static uint8_t ob3[SERIAL_BUFFERS_SIZE];
+#endif
+
+/**
+ * @brief Error handling routine.
+ * @param[in] sr USART SR register value
+ * @param[in] com communication channel associated to the USART
+ */
+static void SetError(uint16_t sr, FullDuplexDriver *com) {
+ dflags_t sts = 0;
+
+ if (sr & USART_SR_ORE)
+ sts |= SD_OVERRUN_ERROR;
+ if (sr & USART_SR_PE)
+ sts |= SD_PARITY_ERROR;
+ if (sr & USART_SR_FE)
+ sts |= SD_FRAMING_ERROR;
+ if (sr & USART_SR_LBD)
+ sts |= SD_BREAK_DETECTED;
+ chSysLockFromIsr();
+ chFDDAddFlagsI(com, sts);
+ chSysUnlockFromIsr();
+}
+
+/**
+ * @brief Common IRQ handler.
+ * @param[in] u pointer to an USART I/O block
+ * @param[in] com communication channel associated to the USART
+ */
+static void ServeInterrupt(USART_TypeDef *u, FullDuplexDriver *com) {
+ uint16_t sr = u->SR;
+
+ if (sr & (USART_SR_ORE | USART_SR_FE | USART_SR_PE | USART_SR_LBD))
+ SetError(sr, com);
+ if (sr & USART_SR_RXNE) {
+ chSysLockFromIsr();
+ chFDDIncomingDataI(com, u->DR);
+ chSysUnlockFromIsr();
+ }
+ if (sr & USART_SR_TXE) {
+ chSysLockFromIsr();
+ msg_t b = chFDDRequestDataI(com);
+ chSysUnlockFromIsr();
+ if (b < Q_OK)
+ u->CR1 &= ~USART_CR1_TXEIE;
+ else
+ u->DR = b;
+ }
+}
+
+#if USE_STM32_USART1 || defined(__DOXYGEN__)
+CH_IRQ_HANDLER(VectorD4) {
+
+ CH_IRQ_PROLOGUE();
+
+ ServeInterrupt(USART1, &COM1);
+
+ CH_IRQ_EPILOGUE();
+}
+
+static void OutNotify1(void) {
+
+ USART1->CR1 |= USART_CR1_TXEIE;
+}
+#endif
+
+#if USE_STM32_USART2 || defined(__DOXYGEN__)
+CH_IRQ_HANDLER(VectorD8) {
+
+ CH_IRQ_PROLOGUE();
+
+ ServeInterrupt(USART2, &COM2);
+
+ CH_IRQ_EPILOGUE();
+}
+
+static void OutNotify2(void) {
+
+ USART2->CR1 |= USART_CR1_TXEIE;
+}
+#endif
+
+#if USE_STM32_USART3 || defined(__DOXYGEN__)
+CH_IRQ_HANDLER(VectorDC) {
+
+ CH_IRQ_PROLOGUE();
+
+ ServeInterrupt(USART3, &COM3);
+
+ CH_IRQ_EPILOGUE();
+}
+
+static void OutNotify3(void) {
+
+ USART3->CR1 |= USART_CR1_TXEIE;
+}
+#endif
+
+/**
+ * @brief USART1 setup.
+ * @details This function must be invoked with interrupts disabled.
+ * @param[in] u pointer to an USART I/O block
+ * @param[in] speed serial port speed in bits per second
+ * @param[in] cr1 the value for the @p CR1 register
+ * @param[in] cr2 the value for the @p CR2 register
+ * @param[in] cr3 the value for the @p CR3 register
+ * @note Must be invoked with interrupts disabled.
+ * @note Does not reset the I/O queues.
+ */
+void usart_setup(USART_TypeDef *u, uint32_t speed, uint16_t cr1,
+ uint16_t cr2, uint16_t cr3) {
+
+ /*
+ * Baud rate setting.
+ */
+ if (u == USART1)
+ u->BRR = APB2CLK / speed;
+ else
+ u->BRR = APB1CLK / speed;
+
+ /*
+ * Note that some bits are enforced.
+ */
+ u->CR1 = cr1 | USART_CR1_UE | USART_CR1_PEIE | USART_CR1_RXNEIE |
+ USART_CR1_TE | USART_CR1_RE;
+ u->CR2 = cr2;
+ u->CR3 = cr3 | USART_CR3_EIE;
+}
+
+/**
+ * @brief Serial driver initialization.
+ * @param[in] prio1 priority to be assigned to the USART1 IRQ
+ * @param[in] prio2 priority to be assigned to the USART2 IRQ
+ * @param[in] prio3 priority to be assigned to the USART3 IRQ
+ * @note Handshake pads are not enabled inside this function because they
+ * may have another use, enable them externally if needed.
+ * RX and TX pads are handled inside.
+ */
+void serial_init(uint32_t prio1, uint32_t prio2, uint32_t prio3) {
+
+#if USE_STM32_USART1
+ chFDDInit(&COM1, ib1, sizeof ib1, NULL, ob1, sizeof ob1, OutNotify1);
+ RCC->APB2ENR |= RCC_APB2ENR_USART1EN;
+ usart_setup(USART1, DEFAULT_USART_BITRATE, 0,
+ USART_CR2_STOP1_BITS | USART_CR2_LINEN, 0);
+ GPIOA->CRH = (GPIOA->CRH & 0xFFFFF00F) | 0x000004B0;
+ NVICEnableVector(USART1_IRQn, prio1);
+#endif
+
+#if USE_STM32_USART2
+ chFDDInit(&COM2, ib2, sizeof ib2, NULL, ob2, sizeof ob2, OutNotify2);
+ RCC->APB1ENR |= RCC_APB1ENR_USART2EN;
+ usart_setup(USART2, DEFAULT_USART_BITRATE, 0,
+ USART_CR2_STOP1_BITS | USART_CR2_LINEN, 0);
+ GPIOA->CRL = (GPIOA->CRL & 0xFFFF00FF) | 0x00004B00;
+ NVICEnableVector(USART2_IRQn, prio2);
+#endif
+
+#if USE_STM32_USART3
+ chFDDInit(&COM3, ib3, sizeof ib3, NULL, ob3, sizeof ob3, OutNotify3);
+ RCC->APB1ENR |= RCC_APB1ENR_USART3EN;
+ usart_setup(USART3, DEFAULT_USART_BITRATE, 0,
+ USART_CR2_STOP1_BITS | USART_CR2_LINEN, 0);
+ GPIOB->CRH = (GPIOB->CRH & 0xFFFF00FF) | 0x00004B00;
+ NVICEnableVector(USART3_IRQn, prio3);
+#endif
+}
+
+/** @} */
diff --git a/os/ports/GCC/ARMCM3/STM32F103/stm32_serial.h b/os/ports/GCC/ARMCM3/STM32F103/stm32_serial.h
new file mode 100644
index 000000000..421cf00fe
--- /dev/null
+++ b/os/ports/GCC/ARMCM3/STM32F103/stm32_serial.h
@@ -0,0 +1,122 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT 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 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT 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, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file ports/ARMCM3-STM32F103/stm32_serial.h
+ * @brief STM32F103 Serial driver macros and structures.
+ * @addtogroup STM32F103_SERIAL
+ * @{
+ */
+
+#ifndef _STM32_SERIAL_H_
+#define _STM32_SERIAL_H_
+
+/*
+ * Tricks required to make the TRUE/FALSE declaration inside the library
+ * compatible.
+ */
+#ifndef __STM32F10x_H
+#undef FALSE
+#undef TRUE
+#include <stm32f10x.h>
+#define FALSE 0
+#define TRUE (!FALSE)
+#endif
+
+/**
+ * @brief Serial buffers size.
+ * @details Configuration parameter, you can change the depth of the queue
+ * buffers depending on the requirements of your application.
+ * @note The default is 128 bytes for both the transmission and receive buffers.
+ */
+#if !defined(SERIAL_BUFFERS_SIZE) || defined(__DOXYGEN__)
+#define SERIAL_BUFFERS_SIZE 128
+#endif
+
+/**
+ * @brief Default bit rate.
+ * @details Configuration parameter, at startup the USARTs are configured at
+ * this speed.
+ * @note It is possible to use @p SetUSART() in order to change the working
+ * parameters at runtime.
+ */
+#if !defined(DEFAULT_USART_BITRATE) || defined(__DOXYGEN__)
+#define DEFAULT_USART_BITRATE 38400
+#endif
+
+/**
+ * @brief USART1 driver enable switch.
+ * @details If set to @p TRUE the support for USART1 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(USE_STM32_USART1) || defined(__DOXYGEN__)
+#define USE_STM32_USART1 FALSE
+#endif
+
+/**
+ * @brief USART2 driver enable switch.
+ * @details If set to @p TRUE the support for USART2 is included.
+ * @note The default is @p TRUE.
+ */
+#if !defined(USE_STM32_USART2) || defined(__DOXYGEN__)
+#define USE_STM32_USART2 TRUE
+#endif
+
+/**
+ * @brief USART3 driver enable switch.
+ * @details If set to @p TRUE the support for USART3 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(USE_STM32_USART3) || defined(__DOXYGEN__)
+#define USE_STM32_USART3 FALSE
+#endif
+
+/*
+ * Extra USARTs definitions here (missing from the ST header file).
+ */
+#define USART_CR2_STOP1_BITS (0 << 12) /**< @brief CR2 1 stop bit value.*/
+#define USART_CR2_STOP0P5_BITS (1 << 12) /**< @brief CR2 0.5 stop bit value.*/
+#define USART_CR2_STOP2_BITS (2 << 12) /**< @brief CR2 2 stop bit value.*/
+#define USART_CR2_STOP1P5_BITS (3 << 12) /**< @brief CR2 1.5 stop bit value.*/
+
+/** @cond never*/
+#if USE_STM32_USART1
+extern FullDuplexDriver COM1;
+#endif
+#if USE_STM32_USART2
+extern FullDuplexDriver COM2;
+#endif
+#if USE_STM32_USART3
+extern FullDuplexDriver COM3;
+#endif
+/** @endcond*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void serial_init(uint32_t prio1, uint32_t prio2, uint32_t prio3);
+ void usart_setup(USART_TypeDef *u, uint32_t speed, uint16_t cr1,
+ uint16_t cr2, uint16_t cr3);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _STM32_SERIAL_H_ */
+
+/** @} */
diff --git a/os/ports/GCC/ARMCM3/STM32F103/stm32f10x.h b/os/ports/GCC/ARMCM3/STM32F103/stm32f10x.h
new file mode 100644
index 000000000..ec8f6f43e
--- /dev/null
+++ b/os/ports/GCC/ARMCM3/STM32F103/stm32f10x.h
@@ -0,0 +1,7851 @@
+/**
+ ******************************************************************************
+ * @file stm32f10x.h
+ * @author MCD Application Team
+ * @version V3.1.0
+ * @date 06/19/2009
+ * @brief CMSIS Cortex-M3 Device Peripheral Access Layer Header File.
+ * This file contains all the peripheral register's definitions, bits
+ * definitions and memory mapping for STM32F10x Connectivity line, High
+ * density, Medium density and Low density devices.
+ ******************************************************************************
+ *
+ * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+ * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
+ * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
+ * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
+ * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
+ * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+ *
+ * <h2><center>&copy; COPYRIGHT 2009 STMicroelectronics</center></h2>
+ ******************************************************************************
+ */
+
+/** @addtogroup CMSIS
+ * @{
+ */
+
+/** @addtogroup stm32f10x
+ * @{
+ */
+
+#ifndef __STM32F10x_H
+#define __STM32F10x_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/** @addtogroup Library_configuration_section
+ * @{
+ */
+
+/* Uncomment the line below according to the target STM32 device used in your
+ application
+ */
+
+#if !defined (STM32F10X_LD) && !defined (STM32F10X_MD) && !defined (STM32F10X_HD) && !defined (STM32F10X_CL)
+ /* #define STM32F10X_LD */ /*!< STM32F10X_LD: STM32 Low density devices */
+ /* #define STM32F10X_MD */ /*!< STM32F10X_MD: STM32 Medium density devices */
+ /* #define STM32F10X_HD */ /*!< STM32F10X_HD: STM32 High density devices */
+ #define STM32F10X_CL /*!< STM32F10X_CL: STM32 Connectivity line devices */
+#endif
+/* Tip: To avoid modifying this file each time you need to switch between these
+ devices, you can define the device in your toolchain compiler preprocessor.
+
+ - Low density devices are STM32F101xx, STM32F102xx and STM32F103xx microcontrollers
+ where the Flash memory density ranges between 16 and 32 Kbytes.
+ - Medium density devices are STM32F101xx, STM32F102xx and STM32F103xx microcontrollers
+ where the Flash memory density ranges between 64 and 128 Kbytes.
+ - High density devices are STM32F101xx and STM32F103xx microcontrollers where
+ the Flash memory density ranges between 256 and 512 Kbytes.
+ - Connectivity line devices are STM32F105xx and STM32F107xx microcontrollers.
+ */
+
+#if !defined USE_STDPERIPH_DRIVER
+/**
+ * @brief Comment the line below if you will not use the peripherals drivers.
+ In this case, these drivers will not be included and the application code will
+ be based on direct access to peripherals registers
+ */
+ /*#define USE_STDPERIPH_DRIVER*/
+#endif
+
+/**
+ * @brief In the following line adjust the value of External High Speed oscillator (HSE)
+ used in your application
+
+ Tip: To avoid modifying this file each time you need to use different HSE, you
+ can define the HSE value in your toolchain compiler preprocessor.
+ */
+#if !defined HSE_Value
+ #ifdef STM32F10X_CL
+ #define HSE_Value ((uint32_t)25000000) /*!< Value of the External oscillator in Hz */
+ #else
+ #define HSE_Value ((uint32_t)8000000) /*!< Value of the External oscillator in Hz */
+ #endif /* STM32F10X_CL */
+#endif /* HSE_Value */
+
+
+/**
+ * @brief In the following line adjust the External High Speed oscillator (HSE) Startup
+ Timeout value
+ */
+#define HSEStartUp_TimeOut ((uint16_t)0x0500) /*!< Time out for HSE start up */
+
+#define HSI_Value ((uint32_t)8000000) /*!< Value of the Internal oscillator in Hz*/
+
+/**
+ * @brief STM32F10x Standard Peripheral Library version number
+ */
+#define __STM32F10X_STDPERIPH_VERSION_MAIN (0x03) /*!< [31:16] STM32F10x Standard Peripheral Library main version */
+#define __STM32F10X_STDPERIPH_VERSION_SUB1 (0x01) /*!< [15:8] STM32F10x Standard Peripheral Library sub1 version */
+#define __STM32F10X_STDPERIPH_VERSION_SUB2 (0x00) /*!< [7:0] STM32F10x Standard Peripheral Library sub2 version */
+#define __STM32F10X_STDPERIPH_VERSION ((__STM32F10X_STDPERIPH_VERSION_MAIN << 16)\
+ | (__STM32F10X_STDPERIPH_VERSION_SUB1 << 8)\
+ | __STM32F10X_STDPERIPH_VERSION_SUB2)
+
+/**
+ * @}
+ */
+
+/** @addtogroup Configuration_section_for_CMSIS
+ * @{
+ */
+
+/**
+ * @brief Configuration of the Cortex-M3 Processor and Core Peripherals
+ */
+#define __MPU_PRESENT 0 /*!< STM32 does not provide an MPU */
+#define __NVIC_PRIO_BITS 4 /*!< STM32 uses 4 Bits for the Priority Levels */
+#define __Vendor_SysTickConfig 0 /*!< Set to 1 if different SysTick Config is used */
+
+/**
+ * @brief STM32F10x Interrupt Number Definition, according to the selected device
+ * in @ref Library_configuration_section
+ */
+typedef enum IRQn
+{
+/****** Cortex-M3 Processor Exceptions Numbers ***************************************************/
+ NonMaskableInt_IRQn = -14, /*!< 2 Non Maskable Interrupt */
+ MemoryManagement_IRQn = -12, /*!< 4 Cortex-M3 Memory Management Interrupt */
+ BusFault_IRQn = -11, /*!< 5 Cortex-M3 Bus Fault Interrupt */
+ UsageFault_IRQn = -10, /*!< 6 Cortex-M3 Usage Fault Interrupt */
+ SVCall_IRQn = -5, /*!< 11 Cortex-M3 SV Call Interrupt */
+ DebugMonitor_IRQn = -4, /*!< 12 Cortex-M3 Debug Monitor Interrupt */
+ PendSV_IRQn = -2, /*!< 14 Cortex-M3 Pend SV Interrupt */
+ SysTick_IRQn = -1, /*!< 15 Cortex-M3 System Tick Interrupt */
+
+/****** STM32 specific Interrupt Numbers *********************************************************/
+ WWDG_IRQn = 0, /*!< Window WatchDog Interrupt */
+ PVD_IRQn = 1, /*!< PVD through EXTI Line detection Interrupt */
+ TAMPER_IRQn = 2, /*!< Tamper Interrupt */
+ RTC_IRQn = 3, /*!< RTC global Interrupt */
+ FLASH_IRQn = 4, /*!< FLASH global Interrupt */
+ RCC_IRQn = 5, /*!< RCC global Interrupt */
+ EXTI0_IRQn = 6, /*!< EXTI Line0 Interrupt */
+ EXTI1_IRQn = 7, /*!< EXTI Line1 Interrupt */
+ EXTI2_IRQn = 8, /*!< EXTI Line2 Interrupt */
+ EXTI3_IRQn = 9, /*!< EXTI Line3 Interrupt */
+ EXTI4_IRQn = 10, /*!< EXTI Line4 Interrupt */
+ DMA1_Channel1_IRQn = 11, /*!< DMA1 Channel 1 global Interrupt */
+ DMA1_Channel2_IRQn = 12, /*!< DMA1 Channel 2 global Interrupt */
+ DMA1_Channel3_IRQn = 13, /*!< DMA1 Channel 3 global Interrupt */
+ DMA1_Channel4_IRQn = 14, /*!< DMA1 Channel 4 global Interrupt */
+ DMA1_Channel5_IRQn = 15, /*!< DMA1 Channel 5 global Interrupt */
+ DMA1_Channel6_IRQn = 16, /*!< DMA1 Channel 6 global Interrupt */
+ DMA1_Channel7_IRQn = 17, /*!< DMA1 Channel 7 global Interrupt */
+ ADC1_2_IRQn = 18, /*!< ADC1 and ADC2 global Interrupt */
+
+#ifdef STM32F10X_LD
+ USB_HP_CAN1_TX_IRQn = 19, /*!< USB Device High Priority or CAN1 TX Interrupts */
+ USB_LP_CAN1_RX0_IRQn = 20, /*!< USB Device Low Priority or CAN1 RX0 Interrupts */
+ CAN1_RX1_IRQn = 21, /*!< CAN1 RX1 Interrupt */
+ CAN1_SCE_IRQn = 22, /*!< CAN1 SCE Interrupt */
+ EXTI9_5_IRQn = 23, /*!< External Line[9:5] Interrupts */
+ TIM1_BRK_IRQn = 24, /*!< TIM1 Break Interrupt */
+ TIM1_UP_IRQn = 25, /*!< TIM1 Update Interrupt */
+ TIM1_TRG_COM_IRQn = 26, /*!< TIM1 Trigger and Commutation Interrupt */
+ TIM1_CC_IRQn = 27, /*!< TIM1 Capture Compare Interrupt */
+ TIM2_IRQn = 28, /*!< TIM2 global Interrupt */
+ TIM3_IRQn = 29, /*!< TIM3 global Interrupt */
+ I2C1_EV_IRQn = 31, /*!< I2C1 Event Interrupt */
+ I2C1_ER_IRQn = 32, /*!< I2C1 Error Interrupt */
+ SPI1_IRQn = 35, /*!< SPI1 global Interrupt */
+ USART1_IRQn = 37, /*!< USART1 global Interrupt */
+ USART2_IRQn = 38, /*!< USART2 global Interrupt */
+ EXTI15_10_IRQn = 40, /*!< External Line[15:10] Interrupts */
+ RTCAlarm_IRQn = 41, /*!< RTC Alarm through EXTI Line Interrupt */
+ USBWakeUp_IRQn = 42, /*!< USB Device WakeUp from suspend through EXTI Line Interrupt */
+#endif /* STM32F10X_LD */
+
+#ifdef STM32F10X_MD
+ USB_HP_CAN1_TX_IRQn = 19, /*!< USB Device High Priority or CAN1 TX Interrupts */
+ USB_LP_CAN1_RX0_IRQn = 20, /*!< USB Device Low Priority or CAN1 RX0 Interrupts */
+ CAN1_RX1_IRQn = 21, /*!< CAN1 RX1 Interrupt */
+ CAN1_SCE_IRQn = 22, /*!< CAN1 SCE Interrupt */
+ EXTI9_5_IRQn = 23, /*!< External Line[9:5] Interrupts */
+ TIM1_BRK_IRQn = 24, /*!< TIM1 Break Interrupt */
+ TIM1_UP_IRQn = 25, /*!< TIM1 Update Interrupt */
+ TIM1_TRG_COM_IRQn = 26, /*!< TIM1 Trigger and Commutation Interrupt */
+ TIM1_CC_IRQn = 27, /*!< TIM1 Capture Compare Interrupt */
+ TIM2_IRQn = 28, /*!< TIM2 global Interrupt */
+ TIM3_IRQn = 29, /*!< TIM3 global Interrupt */
+ TIM4_IRQn = 30, /*!< TIM4 global Interrupt */
+ I2C1_EV_IRQn = 31, /*!< I2C1 Event Interrupt */
+ I2C1_ER_IRQn = 32, /*!< I2C1 Error Interrupt */
+ I2C2_EV_IRQn = 33, /*!< I2C2 Event Interrupt */
+ I2C2_ER_IRQn = 34, /*!< I2C2 Error Interrupt */
+ SPI1_IRQn = 35, /*!< SPI1 global Interrupt */
+ SPI2_IRQn = 36, /*!< SPI2 global Interrupt */
+ USART1_IRQn = 37, /*!< USART1 global Interrupt */
+ USART2_IRQn = 38, /*!< USART2 global Interrupt */
+ USART3_IRQn = 39, /*!< USART3 global Interrupt */
+ EXTI15_10_IRQn = 40, /*!< External Line[15:10] Interrupts */
+ RTCAlarm_IRQn = 41, /*!< RTC Alarm through EXTI Line Interrupt */
+ USBWakeUp_IRQn = 42, /*!< USB Device WakeUp from suspend through EXTI Line Interrupt */
+#endif /* STM32F10X_MD */
+
+#ifdef STM32F10X_HD
+ USB_HP_CAN1_TX_IRQn = 19, /*!< USB Device High Priority or CAN1 TX Interrupts */
+ USB_LP_CAN1_RX0_IRQn = 20, /*!< USB Device Low Priority or CAN1 RX0 Interrupts */
+ CAN1_RX1_IRQn = 21, /*!< CAN1 RX1 Interrupt */
+ CAN1_SCE_IRQn = 22, /*!< CAN1 SCE Interrupt */
+ EXTI9_5_IRQn = 23, /*!< External Line[9:5] Interrupts */
+ TIM1_BRK_IRQn = 24, /*!< TIM1 Break Interrupt */
+ TIM1_UP_IRQn = 25, /*!< TIM1 Update Interrupt */
+ TIM1_TRG_COM_IRQn = 26, /*!< TIM1 Trigger and Commutation Interrupt */
+ TIM1_CC_IRQn = 27, /*!< TIM1 Capture Compare Interrupt */
+ TIM2_IRQn = 28, /*!< TIM2 global Interrupt */
+ TIM3_IRQn = 29, /*!< TIM3 global Interrupt */
+ TIM4_IRQn = 30, /*!< TIM4 global Interrupt */
+ I2C1_EV_IRQn = 31, /*!< I2C1 Event Interrupt */
+ I2C1_ER_IRQn = 32, /*!< I2C1 Error Interrupt */
+ I2C2_EV_IRQn = 33, /*!< I2C2 Event Interrupt */
+ I2C2_ER_IRQn = 34, /*!< I2C2 Error Interrupt */
+ SPI1_IRQn = 35, /*!< SPI1 global Interrupt */
+ SPI2_IRQn = 36, /*!< SPI2 global Interrupt */
+ USART1_IRQn = 37, /*!< USART1 global Interrupt */
+ USART2_IRQn = 38, /*!< USART2 global Interrupt */
+ USART3_IRQn = 39, /*!< USART3 global Interrupt */
+ EXTI15_10_IRQn = 40, /*!< External Line[15:10] Interrupts */
+ RTCAlarm_IRQn = 41, /*!< RTC Alarm through EXTI Line Interrupt */
+ USBWakeUp_IRQn = 42, /*!< USB Device WakeUp from suspend through EXTI Line Interrupt */
+ TIM8_BRK_IRQn = 43, /*!< TIM8 Break Interrupt */
+ TIM8_UP_IRQn = 44, /*!< TIM8 Update Interrupt */
+ TIM8_TRG_COM_IRQn = 45, /*!< TIM8 Trigger and Commutation Interrupt */
+ TIM8_CC_IRQn = 46, /*!< TIM8 Capture Compare Interrupt */
+ ADC3_IRQn = 47, /*!< ADC3 global Interrupt */
+ FSMC_IRQn = 48, /*!< FSMC global Interrupt */
+ SDIO_IRQn = 49, /*!< SDIO global Interrupt */
+ TIM5_IRQn = 50, /*!< TIM5 global Interrupt */
+ SPI3_IRQn = 51, /*!< SPI3 global Interrupt */
+ UART4_IRQn = 52, /*!< UART4 global Interrupt */
+ UART5_IRQn = 53, /*!< UART5 global Interrupt */
+ TIM6_IRQn = 54, /*!< TIM6 global Interrupt */
+ TIM7_IRQn = 55, /*!< TIM7 global Interrupt */
+ DMA2_Channel1_IRQn = 56, /*!< DMA2 Channel 1 global Interrupt */
+ DMA2_Channel2_IRQn = 57, /*!< DMA2 Channel 2 global Interrupt */
+ DMA2_Channel3_IRQn = 58, /*!< DMA2 Channel 3 global Interrupt */
+ DMA2_Channel4_5_IRQn = 59 /*!< DMA2 Channel 4 and Channel 5 global Interrupt */
+#endif /* STM32F10X_HD */
+
+#ifdef STM32F10X_CL
+ CAN1_TX_IRQn = 19, /*!< USB Device High Priority or CAN1 TX Interrupts */
+ CAN1_RX0_IRQn = 20, /*!< USB Device Low Priority or CAN1 RX0 Interrupts */
+ CAN1_RX1_IRQn = 21, /*!< CAN1 RX1 Interrupt */
+ CAN1_SCE_IRQn = 22, /*!< CAN1 SCE Interrupt */
+ EXTI9_5_IRQn = 23, /*!< External Line[9:5] Interrupts */
+ TIM1_BRK_IRQn = 24, /*!< TIM1 Break Interrupt */
+ TIM1_UP_IRQn = 25, /*!< TIM1 Update Interrupt */
+ TIM1_TRG_COM_IRQn = 26, /*!< TIM1 Trigger and Commutation Interrupt */
+ TIM1_CC_IRQn = 27, /*!< TIM1 Capture Compare Interrupt */
+ TIM2_IRQn = 28, /*!< TIM2 global Interrupt */
+ TIM3_IRQn = 29, /*!< TIM3 global Interrupt */
+ TIM4_IRQn = 30, /*!< TIM4 global Interrupt */
+ I2C1_EV_IRQn = 31, /*!< I2C1 Event Interrupt */
+ I2C1_ER_IRQn = 32, /*!< I2C1 Error Interrupt */
+ I2C2_EV_IRQn = 33, /*!< I2C2 Event Interrupt */
+ I2C2_ER_IRQn = 34, /*!< I2C2 Error Interrupt */
+ SPI1_IRQn = 35, /*!< SPI1 global Interrupt */
+ SPI2_IRQn = 36, /*!< SPI2 global Interrupt */
+ USART1_IRQn = 37, /*!< USART1 global Interrupt */
+ USART2_IRQn = 38, /*!< USART2 global Interrupt */
+ USART3_IRQn = 39, /*!< USART3 global Interrupt */
+ EXTI15_10_IRQn = 40, /*!< External Line[15:10] Interrupts */
+ RTCAlarm_IRQn = 41, /*!< RTC Alarm through EXTI Line Interrupt */
+ OTG_FS_WKUP_IRQn = 42, /*!< USB OTG FS WakeUp from suspend through EXTI Line Interrupt */
+ TIM5_IRQn = 50, /*!< TIM5 global Interrupt */
+ SPI3_IRQn = 51, /*!< SPI3 global Interrupt */
+ UART4_IRQn = 52, /*!< UART4 global Interrupt */
+ UART5_IRQn = 53, /*!< UART5 global Interrupt */
+ TIM6_IRQn = 54, /*!< TIM6 global Interrupt */
+ TIM7_IRQn = 55, /*!< TIM7 global Interrupt */
+ DMA2_Channel1_IRQn = 56, /*!< DMA2 Channel 1 global Interrupt */
+ DMA2_Channel2_IRQn = 57, /*!< DMA2 Channel 2 global Interrupt */
+ DMA2_Channel3_IRQn = 58, /*!< DMA2 Channel 3 global Interrupt */
+ DMA2_Channel4_IRQn = 59, /*!< DMA2 Channel 4 global Interrupt */
+ DMA2_Channel5_IRQn = 60, /*!< DMA2 Channel 5 global Interrupt */
+ ETH_IRQn = 61, /*!< Ethernet global Interrupt */
+ ETH_WKUP_IRQn = 62, /*!< Ethernet Wakeup through EXTI line Interrupt */
+ CAN2_TX_IRQn = 63, /*!< CAN2 TX Interrupt */
+ CAN2_RX0_IRQn = 64, /*!< CAN2 RX0 Interrupt */
+ CAN2_RX1_IRQn = 65, /*!< CAN2 RX1 Interrupt */
+ CAN2_SCE_IRQn = 66, /*!< CAN2 SCE Interrupt */
+ OTG_FS_IRQn = 67 /*!< USB OTG FS global Interrupt */
+#endif /* STM32F10X_CL */
+} IRQn_Type;
+
+/**
+ * @}
+ */
+
+#include "core_cm3.h"
+//#include "system_stm32f10x.h"
+#include <stdint.h>
+
+/** @addtogroup Exported_types
+ * @{
+ */
+
+/*!< STM32F10x Standard Peripheral Library old types (maintained for legacy purpose) */
+typedef int32_t s32;
+typedef int16_t s16;
+typedef int8_t s8;
+
+typedef const int32_t sc32; /*!< Read Only */
+typedef const int16_t sc16; /*!< Read Only */
+typedef const int8_t sc8; /*!< Read Only */
+
+typedef __IO int32_t vs32;
+typedef __IO int16_t vs16;
+typedef __IO int8_t vs8;
+
+typedef __I int32_t vsc32; /*!< Read Only */
+typedef __I int16_t vsc16; /*!< Read Only */
+typedef __I int8_t vsc8; /*!< Read Only */
+
+typedef uint32_t u32;
+typedef uint16_t u16;
+typedef uint8_t u8;
+
+typedef const uint32_t uc32; /*!< Read Only */
+typedef const uint16_t uc16; /*!< Read Only */
+typedef const uint8_t uc8; /*!< Read Only */
+
+typedef __IO uint32_t vu32;
+typedef __IO uint16_t vu16;
+typedef __IO uint8_t vu8;
+
+typedef __I uint32_t vuc32; /*!< Read Only */
+typedef __I uint16_t vuc16; /*!< Read Only */
+typedef __I uint8_t vuc8; /*!< Read Only */
+
+#ifndef __cplusplus
+typedef enum {FALSE = 0, TRUE = !FALSE} bool;
+#endif
+
+typedef enum {RESET = 0, SET = !RESET} FlagStatus, ITStatus;
+
+typedef enum {DISABLE = 0, ENABLE = !DISABLE} FunctionalState;
+#define IS_FUNCTIONAL_STATE(STATE) (((STATE) == DISABLE) || ((STATE) == ENABLE))
+
+typedef enum {ERROR = 0, SUCCESS = !ERROR} ErrorStatus;
+
+/**
+ * @}
+ */
+
+/** @addtogroup Peripheral_registers_structures
+ * @{
+ */
+
+/**
+ * @brief Analog to Digital Converter
+ */
+
+typedef struct
+{
+ __IO uint32_t SR;
+ __IO uint32_t CR1;
+ __IO uint32_t CR2;
+ __IO uint32_t SMPR1;
+ __IO uint32_t SMPR2;
+ __IO uint32_t JOFR1;
+ __IO uint32_t JOFR2;
+ __IO uint32_t JOFR3;
+ __IO uint32_t JOFR4;
+ __IO uint32_t HTR;
+ __IO uint32_t LTR;
+ __IO uint32_t SQR1;
+ __IO uint32_t SQR2;
+ __IO uint32_t SQR3;
+ __IO uint32_t JSQR;
+ __IO uint32_t JDR1;
+ __IO uint32_t JDR2;
+ __IO uint32_t JDR3;
+ __IO uint32_t JDR4;
+ __IO uint32_t DR;
+} ADC_TypeDef;
+
+/**
+ * @brief Backup Registers
+ */
+
+typedef struct
+{
+ uint32_t RESERVED0;
+ __IO uint16_t DR1;
+ uint16_t RESERVED1;
+ __IO uint16_t DR2;
+ uint16_t RESERVED2;
+ __IO uint16_t DR3;
+ uint16_t RESERVED3;
+ __IO uint16_t DR4;
+ uint16_t RESERVED4;
+ __IO uint16_t DR5;
+ uint16_t RESERVED5;
+ __IO uint16_t DR6;
+ uint16_t RESERVED6;
+ __IO uint16_t DR7;
+ uint16_t RESERVED7;
+ __IO uint16_t DR8;
+ uint16_t RESERVED8;
+ __IO uint16_t DR9;
+ uint16_t RESERVED9;
+ __IO uint16_t DR10;
+ uint16_t RESERVED10;
+ __IO uint16_t RTCCR;
+ uint16_t RESERVED11;
+ __IO uint16_t CR;
+ uint16_t RESERVED12;
+ __IO uint16_t CSR;
+ uint16_t RESERVED13[5];
+ __IO uint16_t DR11;
+ uint16_t RESERVED14;
+ __IO uint16_t DR12;
+ uint16_t RESERVED15;
+ __IO uint16_t DR13;
+ uint16_t RESERVED16;
+ __IO uint16_t DR14;
+ uint16_t RESERVED17;
+ __IO uint16_t DR15;
+ uint16_t RESERVED18;
+ __IO uint16_t DR16;
+ uint16_t RESERVED19;
+ __IO uint16_t DR17;
+ uint16_t RESERVED20;
+ __IO uint16_t DR18;
+ uint16_t RESERVED21;
+ __IO uint16_t DR19;
+ uint16_t RESERVED22;
+ __IO uint16_t DR20;
+ uint16_t RESERVED23;
+ __IO uint16_t DR21;
+ uint16_t RESERVED24;
+ __IO uint16_t DR22;
+ uint16_t RESERVED25;
+ __IO uint16_t DR23;
+ uint16_t RESERVED26;
+ __IO uint16_t DR24;
+ uint16_t RESERVED27;
+ __IO uint16_t DR25;
+ uint16_t RESERVED28;
+ __IO uint16_t DR26;
+ uint16_t RESERVED29;
+ __IO uint16_t DR27;
+ uint16_t RESERVED30;
+ __IO uint16_t DR28;
+ uint16_t RESERVED31;
+ __IO uint16_t DR29;
+ uint16_t RESERVED32;
+ __IO uint16_t DR30;
+ uint16_t RESERVED33;
+ __IO uint16_t DR31;
+ uint16_t RESERVED34;
+ __IO uint16_t DR32;
+ uint16_t RESERVED35;
+ __IO uint16_t DR33;
+ uint16_t RESERVED36;
+ __IO uint16_t DR34;
+ uint16_t RESERVED37;
+ __IO uint16_t DR35;
+ uint16_t RESERVED38;
+ __IO uint16_t DR36;
+ uint16_t RESERVED39;
+ __IO uint16_t DR37;
+ uint16_t RESERVED40;
+ __IO uint16_t DR38;
+ uint16_t RESERVED41;
+ __IO uint16_t DR39;
+ uint16_t RESERVED42;
+ __IO uint16_t DR40;
+ uint16_t RESERVED43;
+ __IO uint16_t DR41;
+ uint16_t RESERVED44;
+ __IO uint16_t DR42;
+ uint16_t RESERVED45;
+} BKP_TypeDef;
+
+/**
+ * @brief Controller Area Network TxMailBox
+ */
+
+typedef struct
+{
+ __IO uint32_t TIR;
+ __IO uint32_t TDTR;
+ __IO uint32_t TDLR;
+ __IO uint32_t TDHR;
+} CAN_TxMailBox_TypeDef;
+
+/**
+ * @brief Controller Area Network FIFOMailBox
+ */
+
+typedef struct
+{
+ __IO uint32_t RIR;
+ __IO uint32_t RDTR;
+ __IO uint32_t RDLR;
+ __IO uint32_t RDHR;
+} CAN_FIFOMailBox_TypeDef;
+
+/**
+ * @brief Controller Area Network FilterRegister
+ */
+
+typedef struct
+{
+ __IO uint32_t FR1;
+ __IO uint32_t FR2;
+} CAN_FilterRegister_TypeDef;
+
+/**
+ * @brief Controller Area Network
+ */
+
+typedef struct
+{
+ __IO uint32_t MCR;
+ __IO uint32_t MSR;
+ __IO uint32_t TSR;
+ __IO uint32_t RF0R;
+ __IO uint32_t RF1R;
+ __IO uint32_t IER;
+ __IO uint32_t ESR;
+ __IO uint32_t BTR;
+ uint32_t RESERVED0[88];
+ CAN_TxMailBox_TypeDef sTxMailBox[3];
+ CAN_FIFOMailBox_TypeDef sFIFOMailBox[2];
+ uint32_t RESERVED1[12];
+ __IO uint32_t FMR;
+ __IO uint32_t FM1R;
+ uint32_t RESERVED2;
+ __IO uint32_t FS1R;
+ uint32_t RESERVED3;
+ __IO uint32_t FFA1R;
+ uint32_t RESERVED4;
+ __IO uint32_t FA1R;
+ uint32_t RESERVED5[8];
+#ifndef STM32F10X_CL
+ CAN_FilterRegister_TypeDef sFilterRegister[14];
+#else
+ CAN_FilterRegister_TypeDef sFilterRegister[28];
+#endif /* STM32F10X_CL */
+} CAN_TypeDef;
+
+/**
+ * @brief CRC calculation unit
+ */
+
+typedef struct
+{
+ __IO uint32_t DR;
+ __IO uint8_t IDR;
+ uint8_t RESERVED0;
+ uint16_t RESERVED1;
+ __IO uint32_t CR;
+} CRC_TypeDef;
+
+/**
+ * @brief Digital to Analog Converter
+ */
+
+typedef struct
+{
+ __IO uint32_t CR;
+ __IO uint32_t SWTRIGR;
+ __IO uint32_t DHR12R1;
+ __IO uint32_t DHR12L1;
+ __IO uint32_t DHR8R1;
+ __IO uint32_t DHR12R2;
+ __IO uint32_t DHR12L2;
+ __IO uint32_t DHR8R2;
+ __IO uint32_t DHR12RD;
+ __IO uint32_t DHR12LD;
+ __IO uint32_t DHR8RD;
+ __IO uint32_t DOR1;
+ __IO uint32_t DOR2;
+} DAC_TypeDef;
+
+/**
+ * @brief Debug MCU
+ */
+
+typedef struct
+{
+ __IO uint32_t IDCODE;
+ __IO uint32_t CR;
+}DBGMCU_TypeDef;
+
+/**
+ * @brief DMA Controller
+ */
+
+typedef struct
+{
+ __IO uint32_t CCR;
+ __IO uint32_t CNDTR;
+ __IO uint32_t CPAR;
+ __IO uint32_t CMAR;
+} DMA_Channel_TypeDef;
+
+typedef struct
+{
+ __IO uint32_t ISR;
+ __IO uint32_t IFCR;
+} DMA_TypeDef;
+
+/**
+ * @brief Ethernet MAC
+ */
+
+typedef struct
+{
+ __IO uint32_t MACCR;
+ __IO uint32_t MACFFR;
+ __IO uint32_t MACHTHR;
+ __IO uint32_t MACHTLR;
+ __IO uint32_t MACMIIAR;
+ __IO uint32_t MACMIIDR;
+ __IO uint32_t MACFCR;
+ __IO uint32_t MACVLANTR; /* 8 */
+ uint32_t RESERVED0[2];
+ __IO uint32_t MACRWUFFR; /* 11 */
+ __IO uint32_t MACPMTCSR;
+ uint32_t RESERVED1[2];
+ __IO uint32_t MACSR; /* 15 */
+ __IO uint32_t MACIMR;
+ __IO uint32_t MACA0HR;
+ __IO uint32_t MACA0LR;
+ __IO uint32_t MACA1HR;
+ __IO uint32_t MACA1LR;
+ __IO uint32_t MACA2HR;
+ __IO uint32_t MACA2LR;
+ __IO uint32_t MACA3HR;
+ __IO uint32_t MACA3LR; /* 24 */
+ uint32_t RESERVED2[40];
+ __IO uint32_t MMCCR; /* 65 */
+ __IO uint32_t MMCRIR;
+ __IO uint32_t MMCTIR;
+ __IO uint32_t MMCRIMR;
+ __IO uint32_t MMCTIMR; /* 69 */
+ uint32_t RESERVED3[14];
+ __IO uint32_t MMCTGFSCCR; /* 84 */
+ __IO uint32_t MMCTGFMSCCR;
+ uint32_t RESERVED4[5];
+ __IO uint32_t MMCTGFCR;
+ uint32_t RESERVED5[10];
+ __IO uint32_t MMCRFCECR;
+ __IO uint32_t MMCRFAECR;
+ uint32_t RESERVED6[10];
+ __IO uint32_t MMCRGUFCR;
+ uint32_t RESERVED7[334];
+ __IO uint32_t PTPTSCR;
+ __IO uint32_t PTPSSIR;
+ __IO uint32_t PTPTSHR;
+ __IO uint32_t PTPTSLR;
+ __IO uint32_t PTPTSHUR;
+ __IO uint32_t PTPTSLUR;
+ __IO uint32_t PTPTSAR;
+ __IO uint32_t PTPTTHR;
+ __IO uint32_t PTPTTLR;
+ uint32_t RESERVED8[567];
+ __IO uint32_t DMABMR;
+ __IO uint32_t DMATPDR;
+ __IO uint32_t DMARPDR;
+ __IO uint32_t DMARDLAR;
+ __IO uint32_t DMATDLAR;
+ __IO uint32_t DMASR;
+ __IO uint32_t DMAOMR;
+ __IO uint32_t DMAIER;
+ __IO uint32_t DMAMFBOCR;
+ uint32_t RESERVED9[9];
+ __IO uint32_t DMACHTDR;
+ __IO uint32_t DMACHRDR;
+ __IO uint32_t DMACHTBAR;
+ __IO uint32_t DMACHRBAR;
+} ETH_TypeDef;
+
+/**
+ * @brief External Interrupt/Event Controller
+ */
+
+typedef struct
+{
+ __IO uint32_t IMR;
+ __IO uint32_t EMR;
+ __IO uint32_t RTSR;
+ __IO uint32_t FTSR;
+ __IO uint32_t SWIER;
+ __IO uint32_t PR;
+} EXTI_TypeDef;
+
+/**
+ * @brief FLASH Registers
+ */
+
+typedef struct
+{
+ __IO uint32_t ACR;
+ __IO uint32_t KEYR;
+ __IO uint32_t OPTKEYR;
+ __IO uint32_t SR;
+ __IO uint32_t CR;
+ __IO uint32_t AR;
+ __IO uint32_t RESERVED;
+ __IO uint32_t OBR;
+ __IO uint32_t WRPR;
+} FLASH_TypeDef;
+
+/**
+ * @brief Option Bytes Registers
+ */
+
+typedef struct
+{
+ __IO uint16_t RDP;
+ __IO uint16_t USER;
+ __IO uint16_t Data0;
+ __IO uint16_t Data1;
+ __IO uint16_t WRP0;
+ __IO uint16_t WRP1;
+ __IO uint16_t WRP2;
+ __IO uint16_t WRP3;
+} OB_TypeDef;
+
+/**
+ * @brief Flexible Static Memory Controller
+ */
+
+typedef struct
+{
+ __IO uint32_t BTCR[8];
+} FSMC_Bank1_TypeDef;
+
+/**
+ * @brief Flexible Static Memory Controller Bank1E
+ */
+
+typedef struct
+{
+ __IO uint32_t BWTR[7];
+} FSMC_Bank1E_TypeDef;
+
+/**
+ * @brief Flexible Static Memory Controller Bank2
+ */
+
+typedef struct
+{
+ __IO uint32_t PCR2;
+ __IO uint32_t SR2;
+ __IO uint32_t PMEM2;
+ __IO uint32_t PATT2;
+ uint32_t RESERVED0;
+ __IO uint32_t ECCR2;
+} FSMC_Bank2_TypeDef;
+
+/**
+ * @brief Flexible Static Memory Controller Bank3
+ */
+
+typedef struct
+{
+ __IO uint32_t PCR3;
+ __IO uint32_t SR3;
+ __IO uint32_t PMEM3;
+ __IO uint32_t PATT3;
+ uint32_t RESERVED0;
+ __IO uint32_t ECCR3;
+} FSMC_Bank3_TypeDef;
+
+/**
+ * @brief Flexible Static Memory Controller Bank4
+ */
+
+typedef struct
+{
+ __IO uint32_t PCR4;
+ __IO uint32_t SR4;
+ __IO uint32_t PMEM4;
+ __IO uint32_t PATT4;
+ __IO uint32_t PIO4;
+} FSMC_Bank4_TypeDef;
+
+/**
+ * @brief General Purpose I/O
+ */
+
+typedef struct
+{
+ __IO uint32_t CRL;
+ __IO uint32_t CRH;
+ __IO uint32_t IDR;
+ __IO uint32_t ODR;
+ __IO uint32_t BSRR;
+ __IO uint32_t BRR;
+ __IO uint32_t LCKR;
+} GPIO_TypeDef;
+
+/**
+ * @brief Alternate Function I/O
+ */
+
+typedef struct
+{
+ __IO uint32_t EVCR;
+ __IO uint32_t MAPR;
+ __IO uint32_t EXTICR[4];
+} AFIO_TypeDef;
+/**
+ * @brief Inter-integrated Circuit Interface
+ */
+
+typedef struct
+{
+ __IO uint16_t CR1;
+ uint16_t RESERVED0;
+ __IO uint16_t CR2;
+ uint16_t RESERVED1;
+ __IO uint16_t OAR1;
+ uint16_t RESERVED2;
+ __IO uint16_t OAR2;
+ uint16_t RESERVED3;
+ __IO uint16_t DR;
+ uint16_t RESERVED4;
+ __IO uint16_t SR1;
+ uint16_t RESERVED5;
+ __IO uint16_t SR2;
+ uint16_t RESERVED6;
+ __IO uint16_t CCR;
+ uint16_t RESERVED7;
+ __IO uint16_t TRISE;
+ uint16_t RESERVED8;
+} I2C_TypeDef;
+
+/**
+ * @brief Independent WATCHDOG
+ */
+
+typedef struct
+{
+ __IO uint32_t KR;
+ __IO uint32_t PR;
+ __IO uint32_t RLR;
+ __IO uint32_t SR;
+} IWDG_TypeDef;
+
+/**
+ * @brief Power Control
+ */
+
+typedef struct
+{
+ __IO uint32_t CR;
+ __IO uint32_t CSR;
+} PWR_TypeDef;
+
+/**
+ * @brief Reset and Clock Control
+ */
+
+typedef struct
+{
+ __IO uint32_t CR;
+ __IO uint32_t CFGR;
+ __IO uint32_t CIR;
+ __IO uint32_t APB2RSTR;
+ __IO uint32_t APB1RSTR;
+ __IO uint32_t AHBENR;
+ __IO uint32_t APB2ENR;
+ __IO uint32_t APB1ENR;
+ __IO uint32_t BDCR;
+ __IO uint32_t CSR;
+#ifdef STM32F10X_CL
+ __IO uint32_t AHBRSTR;
+ __IO uint32_t CFGR2;
+#endif /* STM32F10X_CL */
+} RCC_TypeDef;
+
+/**
+ * @brief Real-Time Clock
+ */
+
+typedef struct
+{
+ __IO uint16_t CRH;
+ uint16_t RESERVED0;
+ __IO uint16_t CRL;
+ uint16_t RESERVED1;
+ __IO uint16_t PRLH;
+ uint16_t RESERVED2;
+ __IO uint16_t PRLL;
+ uint16_t RESERVED3;
+ __IO uint16_t DIVH;
+ uint16_t RESERVED4;
+ __IO uint16_t DIVL;
+ uint16_t RESERVED5;
+ __IO uint16_t CNTH;
+ uint16_t RESERVED6;
+ __IO uint16_t CNTL;
+ uint16_t RESERVED7;
+ __IO uint16_t ALRH;
+ uint16_t RESERVED8;
+ __IO uint16_t ALRL;
+ uint16_t RESERVED9;
+} RTC_TypeDef;
+
+/**
+ * @brief SD host Interface
+ */
+
+typedef struct
+{
+ __IO uint32_t POWER;
+ __IO uint32_t CLKCR;
+ __IO uint32_t ARG;
+ __IO uint32_t CMD;
+ __I uint32_t RESPCMD;
+ __I uint32_t RESP1;
+ __I uint32_t RESP2;
+ __I uint32_t RESP3;
+ __I uint32_t RESP4;
+ __IO uint32_t DTIMER;
+ __IO uint32_t DLEN;
+ __IO uint32_t DCTRL;
+ __I uint32_t DCOUNT;
+ __I uint32_t STA;
+ __IO uint32_t ICR;
+ __IO uint32_t MASK;
+ uint32_t RESERVED0[2];
+ __I uint32_t FIFOCNT;
+ uint32_t RESERVED1[13];
+ __IO uint32_t FIFO;
+} SDIO_TypeDef;
+
+/**
+ * @brief Serial Peripheral Interface
+ */
+
+typedef struct
+{
+ __IO uint16_t CR1;
+ uint16_t RESERVED0;
+ __IO uint16_t CR2;
+ uint16_t RESERVED1;
+ __IO uint16_t SR;
+ uint16_t RESERVED2;
+ __IO uint16_t DR;
+ uint16_t RESERVED3;
+ __IO uint16_t CRCPR;
+ uint16_t RESERVED4;
+ __IO uint16_t RXCRCR;
+ uint16_t RESERVED5;
+ __IO uint16_t TXCRCR;
+ uint16_t RESERVED6;
+ __IO uint16_t I2SCFGR;
+ uint16_t RESERVED7;
+ __IO uint16_t I2SPR;
+ uint16_t RESERVED8;
+} SPI_TypeDef;
+
+/**
+ * @brief TIM
+ */
+
+typedef struct
+{
+ __IO uint16_t CR1;
+ uint16_t RESERVED0;
+ __IO uint16_t CR2;
+ uint16_t RESERVED1;
+ __IO uint16_t SMCR;
+ uint16_t RESERVED2;
+ __IO uint16_t DIER;
+ uint16_t RESERVED3;
+ __IO uint16_t SR;
+ uint16_t RESERVED4;
+ __IO uint16_t EGR;
+ uint16_t RESERVED5;
+ __IO uint16_t CCMR1;
+ uint16_t RESERVED6;
+ __IO uint16_t CCMR2;
+ uint16_t RESERVED7;
+ __IO uint16_t CCER;
+ uint16_t RESERVED8;
+ __IO uint16_t CNT;
+ uint16_t RESERVED9;
+ __IO uint16_t PSC;
+ uint16_t RESERVED10;
+ __IO uint16_t ARR;
+ uint16_t RESERVED11;
+ __IO uint16_t RCR;
+ uint16_t RESERVED12;
+ __IO uint16_t CCR1;
+ uint16_t RESERVED13;
+ __IO uint16_t CCR2;
+ uint16_t RESERVED14;
+ __IO uint16_t CCR3;
+ uint16_t RESERVED15;
+ __IO uint16_t CCR4;
+ uint16_t RESERVED16;
+ __IO uint16_t BDTR;
+ uint16_t RESERVED17;
+ __IO uint16_t DCR;
+ uint16_t RESERVED18;
+ __IO uint16_t DMAR;
+ uint16_t RESERVED19;
+} TIM_TypeDef;
+
+/**
+ * @brief Universal Synchronous Asynchronous Receiver Transmitter
+ */
+
+typedef struct
+{
+ __IO uint16_t SR;
+ uint16_t RESERVED0;
+ __IO uint16_t DR;
+ uint16_t RESERVED1;
+ __IO uint16_t BRR;
+ uint16_t RESERVED2;
+ __IO uint16_t CR1;
+ uint16_t RESERVED3;
+ __IO uint16_t CR2;
+ uint16_t RESERVED4;
+ __IO uint16_t CR3;
+ uint16_t RESERVED5;
+ __IO uint16_t GTPR;
+ uint16_t RESERVED6;
+} USART_TypeDef;
+
+/**
+ * @brief Window WATCHDOG
+ */
+
+typedef struct
+{
+ __IO uint32_t CR;
+ __IO uint32_t CFR;
+ __IO uint32_t SR;
+} WWDG_TypeDef;
+
+/**
+ * @}
+ */
+
+/** @addtogroup Peripheral_memory_map
+ * @{
+ */
+
+#define PERIPH_BB_BASE ((uint32_t)0x42000000) /*!< Peripheral base address in the alias region */
+#define SRAM_BB_BASE ((uint32_t)0x22000000) /*!< SRAM base address in the alias region */
+
+#define SRAM_BASE ((uint32_t)0x20000000) /*!< Peripheral base address in the bit-band region */
+#define PERIPH_BASE ((uint32_t)0x40000000) /*!< SRAM base address in the bit-band region */
+
+#define FSMC_R_BASE ((uint32_t)0xA0000000) /*!< FSMC registers base address */
+
+/*!< Peripheral memory map */
+#define APB1PERIPH_BASE PERIPH_BASE
+#define APB2PERIPH_BASE (PERIPH_BASE + 0x10000)
+#define AHBPERIPH_BASE (PERIPH_BASE + 0x20000)
+
+#define TIM2_BASE (APB1PERIPH_BASE + 0x0000)
+#define TIM3_BASE (APB1PERIPH_BASE + 0x0400)
+#define TIM4_BASE (APB1PERIPH_BASE + 0x0800)
+#define TIM5_BASE (APB1PERIPH_BASE + 0x0C00)
+#define TIM6_BASE (APB1PERIPH_BASE + 0x1000)
+#define TIM7_BASE (APB1PERIPH_BASE + 0x1400)
+#define RTC_BASE (APB1PERIPH_BASE + 0x2800)
+#define WWDG_BASE (APB1PERIPH_BASE + 0x2C00)
+#define IWDG_BASE (APB1PERIPH_BASE + 0x3000)
+#define SPI2_BASE (APB1PERIPH_BASE + 0x3800)
+#define SPI3_BASE (APB1PERIPH_BASE + 0x3C00)
+#define USART2_BASE (APB1PERIPH_BASE + 0x4400)
+#define USART3_BASE (APB1PERIPH_BASE + 0x4800)
+#define UART4_BASE (APB1PERIPH_BASE + 0x4C00)
+#define UART5_BASE (APB1PERIPH_BASE + 0x5000)
+#define I2C1_BASE (APB1PERIPH_BASE + 0x5400)
+#define I2C2_BASE (APB1PERIPH_BASE + 0x5800)
+#define CAN1_BASE (APB1PERIPH_BASE + 0x6400)
+#define CAN2_BASE (APB1PERIPH_BASE + 0x6800)
+#define BKP_BASE (APB1PERIPH_BASE + 0x6C00)
+#define PWR_BASE (APB1PERIPH_BASE + 0x7000)
+#define DAC_BASE (APB1PERIPH_BASE + 0x7400)
+
+#define AFIO_BASE (APB2PERIPH_BASE + 0x0000)
+#define EXTI_BASE (APB2PERIPH_BASE + 0x0400)
+#define GPIOA_BASE (APB2PERIPH_BASE + 0x0800)
+#define GPIOB_BASE (APB2PERIPH_BASE + 0x0C00)
+#define GPIOC_BASE (APB2PERIPH_BASE + 0x1000)
+#define GPIOD_BASE (APB2PERIPH_BASE + 0x1400)
+#define GPIOE_BASE (APB2PERIPH_BASE + 0x1800)
+#define GPIOF_BASE (APB2PERIPH_BASE + 0x1C00)
+#define GPIOG_BASE (APB2PERIPH_BASE + 0x2000)
+#define ADC1_BASE (APB2PERIPH_BASE + 0x2400)
+#define ADC2_BASE (APB2PERIPH_BASE + 0x2800)
+#define TIM1_BASE (APB2PERIPH_BASE + 0x2C00)
+#define SPI1_BASE (APB2PERIPH_BASE + 0x3000)
+#define TIM8_BASE (APB2PERIPH_BASE + 0x3400)
+#define USART1_BASE (APB2PERIPH_BASE + 0x3800)
+#define ADC3_BASE (APB2PERIPH_BASE + 0x3C00)
+
+#define SDIO_BASE (PERIPH_BASE + 0x18000)
+
+#define DMA1_BASE (AHBPERIPH_BASE + 0x0000)
+#define DMA1_Channel1_BASE (AHBPERIPH_BASE + 0x0008)
+#define DMA1_Channel2_BASE (AHBPERIPH_BASE + 0x001C)
+#define DMA1_Channel3_BASE (AHBPERIPH_BASE + 0x0030)
+#define DMA1_Channel4_BASE (AHBPERIPH_BASE + 0x0044)
+#define DMA1_Channel5_BASE (AHBPERIPH_BASE + 0x0058)
+#define DMA1_Channel6_BASE (AHBPERIPH_BASE + 0x006C)
+#define DMA1_Channel7_BASE (AHBPERIPH_BASE + 0x0080)
+#define DMA2_BASE (AHBPERIPH_BASE + 0x0400)
+#define DMA2_Channel1_BASE (AHBPERIPH_BASE + 0x0408)
+#define DMA2_Channel2_BASE (AHBPERIPH_BASE + 0x041C)
+#define DMA2_Channel3_BASE (AHBPERIPH_BASE + 0x0430)
+#define DMA2_Channel4_BASE (AHBPERIPH_BASE + 0x0444)
+#define DMA2_Channel5_BASE (AHBPERIPH_BASE + 0x0458)
+#define RCC_BASE (AHBPERIPH_BASE + 0x1000)
+#define CRC_BASE (AHBPERIPH_BASE + 0x3000)
+
+#define FLASH_R_BASE (AHBPERIPH_BASE + 0x2000) /*!< Flash registers base address */
+#define OB_BASE ((uint32_t)0x1FFFF800) /*!< Flash Option Bytes base address */
+
+#define ETH_BASE (AHBPERIPH_BASE + 0x8000)
+#define ETH_MAC_BASE (ETH_BASE)
+#define ETH_MMC_BASE (ETH_BASE + 0x0100)
+#define ETH_PTP_BASE (ETH_BASE + 0x0700)
+#define ETH_DMA_BASE (ETH_BASE + 0x1000)
+
+#define FSMC_Bank1_R_BASE (FSMC_R_BASE + 0x0000) /*!< FSMC Bank1 registers base address */
+#define FSMC_Bank1E_R_BASE (FSMC_R_BASE + 0x0104) /*!< FSMC Bank1E registers base address */
+#define FSMC_Bank2_R_BASE (FSMC_R_BASE + 0x0060) /*!< FSMC Bank2 registers base address */
+#define FSMC_Bank3_R_BASE (FSMC_R_BASE + 0x0080) /*!< FSMC Bank3 registers base address */
+#define FSMC_Bank4_R_BASE (FSMC_R_BASE + 0x00A0) /*!< FSMC Bank4 registers base address */
+
+#define DBGMCU_BASE ((uint32_t)0xE0042000) /*!< Debug MCU registers base address */
+
+/**
+ * @}
+ */
+
+/** @addtogroup Peripheral_declaration
+ * @{
+ */
+
+#define TIM2 ((TIM_TypeDef *) TIM2_BASE)
+#define TIM3 ((TIM_TypeDef *) TIM3_BASE)
+#define TIM4 ((TIM_TypeDef *) TIM4_BASE)
+#define TIM5 ((TIM_TypeDef *) TIM5_BASE)
+#define TIM6 ((TIM_TypeDef *) TIM6_BASE)
+#define TIM7 ((TIM_TypeDef *) TIM7_BASE)
+#define RTC ((RTC_TypeDef *) RTC_BASE)
+#define WWDG ((WWDG_TypeDef *) WWDG_BASE)
+#define IWDG ((IWDG_TypeDef *) IWDG_BASE)
+#define SPI2 ((SPI_TypeDef *) SPI2_BASE)
+#define SPI3 ((SPI_TypeDef *) SPI3_BASE)
+#define USART2 ((USART_TypeDef *) USART2_BASE)
+#define USART3 ((USART_TypeDef *) USART3_BASE)
+#define UART4 ((USART_TypeDef *) UART4_BASE)
+#define UART5 ((USART_TypeDef *) UART5_BASE)
+#define I2C1 ((I2C_TypeDef *) I2C1_BASE)
+#define I2C2 ((I2C_TypeDef *) I2C2_BASE)
+#define CAN1 ((CAN_TypeDef *) CAN1_BASE)
+#define CAN2 ((CAN_TypeDef *) CAN2_BASE)
+#define BKP ((BKP_TypeDef *) BKP_BASE)
+#define PWR ((PWR_TypeDef *) PWR_BASE)
+#define DAC ((DAC_TypeDef *) DAC_BASE)
+#define AFIO ((AFIO_TypeDef *) AFIO_BASE)
+#define EXTI ((EXTI_TypeDef *) EXTI_BASE)
+#define GPIOA ((GPIO_TypeDef *) GPIOA_BASE)
+#define GPIOB ((GPIO_TypeDef *) GPIOB_BASE)
+#define GPIOC ((GPIO_TypeDef *) GPIOC_BASE)
+#define GPIOD ((GPIO_TypeDef *) GPIOD_BASE)
+#define GPIOE ((GPIO_TypeDef *) GPIOE_BASE)
+#define GPIOF ((GPIO_TypeDef *) GPIOF_BASE)
+#define GPIOG ((GPIO_TypeDef *) GPIOG_BASE)
+#define ADC1 ((ADC_TypeDef *) ADC1_BASE)
+#define ADC2 ((ADC_TypeDef *) ADC2_BASE)
+#define TIM1 ((TIM_TypeDef *) TIM1_BASE)
+#define SPI1 ((SPI_TypeDef *) SPI1_BASE)
+#define TIM8 ((TIM_TypeDef *) TIM8_BASE)
+#define USART1 ((USART_TypeDef *) USART1_BASE)
+#define ADC3 ((ADC_TypeDef *) ADC3_BASE)
+#define SDIO ((SDIO_TypeDef *) SDIO_BASE)
+#define DMA1 ((DMA_TypeDef *) DMA1_BASE)
+#define DMA2 ((DMA_TypeDef *) DMA2_BASE)
+#define DMA1_Channel1 ((DMA_Channel_TypeDef *) DMA1_Channel1_BASE)
+#define DMA1_Channel2 ((DMA_Channel_TypeDef *) DMA1_Channel2_BASE)
+#define DMA1_Channel3 ((DMA_Channel_TypeDef *) DMA1_Channel3_BASE)
+#define DMA1_Channel4 ((DMA_Channel_TypeDef *) DMA1_Channel4_BASE)
+#define DMA1_Channel5 ((DMA_Channel_TypeDef *) DMA1_Channel5_BASE)
+#define DMA1_Channel6 ((DMA_Channel_TypeDef *) DMA1_Channel6_BASE)
+#define DMA1_Channel7 ((DMA_Channel_TypeDef *) DMA1_Channel7_BASE)
+#define DMA2_Channel1 ((DMA_Channel_TypeDef *) DMA2_Channel1_BASE)
+#define DMA2_Channel2 ((DMA_Channel_TypeDef *) DMA2_Channel2_BASE)
+#define DMA2_Channel3 ((DMA_Channel_TypeDef *) DMA2_Channel3_BASE)
+#define DMA2_Channel4 ((DMA_Channel_TypeDef *) DMA2_Channel4_BASE)
+#define DMA2_Channel5 ((DMA_Channel_TypeDef *) DMA2_Channel5_BASE)
+#define RCC ((RCC_TypeDef *) RCC_BASE)
+#define CRC ((CRC_TypeDef *) CRC_BASE)
+#define FLASH ((FLASH_TypeDef *) FLASH_R_BASE)
+#define OB ((OB_TypeDef *) OB_BASE)
+#define ETH ((ETH_TypeDef *) ETH_BASE)
+#define FSMC_Bank1 ((FSMC_Bank1_TypeDef *) FSMC_Bank1_R_BASE)
+#define FSMC_Bank1E ((FSMC_Bank1E_TypeDef *) FSMC_Bank1E_R_BASE)
+#define FSMC_Bank2 ((FSMC_Bank2_TypeDef *) FSMC_Bank2_R_BASE)
+#define FSMC_Bank3 ((FSMC_Bank3_TypeDef *) FSMC_Bank3_R_BASE)
+#define FSMC_Bank4 ((FSMC_Bank4_TypeDef *) FSMC_Bank4_R_BASE)
+#define DBGMCU ((DBGMCU_TypeDef *) DBGMCU_BASE)
+
+/**
+ * @}
+ */
+
+/** @addtogroup Exported_constants
+ * @{
+ */
+
+ /** @addtogroup Peripheral_Registers_Bits_Definition
+ * @{
+ */
+
+/******************************************************************************/
+/* Peripheral Registers_Bits_Definition */
+/******************************************************************************/
+
+/******************************************************************************/
+/* */
+/* CRC calculation unit */
+/* */
+/******************************************************************************/
+
+/******************* Bit definition for CRC_DR register *********************/
+#define CRC_DR_DR ((uint32_t)0xFFFFFFFF) /*!< Data register bits */
+
+
+/******************* Bit definition for CRC_IDR register ********************/
+#define CRC_IDR_IDR ((uint8_t)0xFF) /*!< General-purpose 8-bit data register bits */
+
+
+/******************** Bit definition for CRC_CR register ********************/
+#define CRC_CR_RESET ((uint8_t)0x01) /*!< RESET bit */
+
+/******************************************************************************/
+/* */
+/* Power Control */
+/* */
+/******************************************************************************/
+
+/******************** Bit definition for PWR_CR register ********************/
+#define PWR_CR_LPDS ((uint16_t)0x0001) /*!< Low-Power Deepsleep */
+#define PWR_CR_PDDS ((uint16_t)0x0002) /*!< Power Down Deepsleep */
+#define PWR_CR_CWUF ((uint16_t)0x0004) /*!< Clear Wakeup Flag */
+#define PWR_CR_CSBF ((uint16_t)0x0008) /*!< Clear Standby Flag */
+#define PWR_CR_PVDE ((uint16_t)0x0010) /*!< Power Voltage Detector Enable */
+
+#define PWR_CR_PLS ((uint16_t)0x00E0) /*!< PLS[2:0] bits (PVD Level Selection) */
+#define PWR_CR_PLS_0 ((uint16_t)0x0020) /*!< Bit 0 */
+#define PWR_CR_PLS_1 ((uint16_t)0x0040) /*!< Bit 1 */
+#define PWR_CR_PLS_2 ((uint16_t)0x0080) /*!< Bit 2 */
+
+/*!< PVD level configuration */
+#define PWR_CR_PLS_2V2 ((uint16_t)0x0000) /*!< PVD level 2.2V */
+#define PWR_CR_PLS_2V3 ((uint16_t)0x0020) /*!< PVD level 2.3V */
+#define PWR_CR_PLS_2V4 ((uint16_t)0x0040) /*!< PVD level 2.4V */
+#define PWR_CR_PLS_2V5 ((uint16_t)0x0060) /*!< PVD level 2.5V */
+#define PWR_CR_PLS_2V6 ((uint16_t)0x0080) /*!< PVD level 2.6V */
+#define PWR_CR_PLS_2V7 ((uint16_t)0x00A0) /*!< PVD level 2.7V */
+#define PWR_CR_PLS_2V8 ((uint16_t)0x00C0) /*!< PVD level 2.8V */
+#define PWR_CR_PLS_2V9 ((uint16_t)0x00E0) /*!< PVD level 2.9V */
+
+#define PWR_CR_DBP ((uint16_t)0x0100) /*!< Disable Backup Domain write protection */
+
+
+/******************* Bit definition for PWR_CSR register ********************/
+#define PWR_CSR_WUF ((uint16_t)0x0001) /*!< Wakeup Flag */
+#define PWR_CSR_SBF ((uint16_t)0x0002) /*!< Standby Flag */
+#define PWR_CSR_PVDO ((uint16_t)0x0004) /*!< PVD Output */
+#define PWR_CSR_EWUP ((uint16_t)0x0100) /*!< Enable WKUP pin */
+
+/******************************************************************************/
+/* */
+/* Backup registers */
+/* */
+/******************************************************************************/
+
+/******************* Bit definition for BKP_DR1 register ********************/
+#define BKP_DR1_D ((uint16_t)0xFFFF) /*!< Backup data */
+
+/******************* Bit definition for BKP_DR2 register ********************/
+#define BKP_DR2_D ((uint16_t)0xFFFF) /*!< Backup data */
+
+/******************* Bit definition for BKP_DR3 register ********************/
+#define BKP_DR3_D ((uint16_t)0xFFFF) /*!< Backup data */
+
+/******************* Bit definition for BKP_DR4 register ********************/
+#define BKP_DR4_D ((uint16_t)0xFFFF) /*!< Backup data */
+
+/******************* Bit definition for BKP_DR5 register ********************/
+#define BKP_DR5_D ((uint16_t)0xFFFF) /*!< Backup data */
+
+/******************* Bit definition for BKP_DR6 register ********************/
+#define BKP_DR6_D ((uint16_t)0xFFFF) /*!< Backup data */
+
+/******************* Bit definition for BKP_DR7 register ********************/
+#define BKP_DR7_D ((uint16_t)0xFFFF) /*!< Backup data */
+
+/******************* Bit definition for BKP_DR8 register ********************/
+#define BKP_DR8_D ((uint16_t)0xFFFF) /*!< Backup data */
+
+/******************* Bit definition for BKP_DR9 register ********************/
+#define BKP_DR9_D ((uint16_t)0xFFFF) /*!< Backup data */
+
+/******************* Bit definition for BKP_DR10 register *******************/
+#define BKP_DR10_D ((uint16_t)0xFFFF) /*!< Backup data */
+
+/******************* Bit definition for BKP_DR11 register *******************/
+#define BKP_DR11_D ((uint16_t)0xFFFF) /*!< Backup data */
+
+/******************* Bit definition for BKP_DR12 register *******************/
+#define BKP_DR12_D ((uint16_t)0xFFFF) /*!< Backup data */
+
+/******************* Bit definition for BKP_DR13 register *******************/
+#define BKP_DR13_D ((uint16_t)0xFFFF) /*!< Backup data */
+
+/******************* Bit definition for BKP_DR14 register *******************/
+#define BKP_DR14_D ((uint16_t)0xFFFF) /*!< Backup data */
+
+/******************* Bit definition for BKP_DR15 register *******************/
+#define BKP_DR15_D ((uint16_t)0xFFFF) /*!< Backup data */
+
+/******************* Bit definition for BKP_DR16 register *******************/
+#define BKP_DR16_D ((uint16_t)0xFFFF) /*!< Backup data */
+
+/******************* Bit definition for BKP_DR17 register *******************/
+#define BKP_DR17_D ((uint16_t)0xFFFF) /*!< Backup data */
+
+/****************** Bit definition for BKP_DR18 register ********************/
+#define BKP_DR18_D ((uint16_t)0xFFFF) /*!< Backup data */
+
+/******************* Bit definition for BKP_DR19 register *******************/
+#define BKP_DR19_D ((uint16_t)0xFFFF) /*!< Backup data */
+
+/******************* Bit definition for BKP_DR20 register *******************/
+#define BKP_DR20_D ((uint16_t)0xFFFF) /*!< Backup data */
+
+/******************* Bit definition for BKP_DR21 register *******************/
+#define BKP_DR21_D ((uint16_t)0xFFFF) /*!< Backup data */
+
+/******************* Bit definition for BKP_DR22 register *******************/
+#define BKP_DR22_D ((uint16_t)0xFFFF) /*!< Backup data */
+
+/******************* Bit definition for BKP_DR23 register *******************/
+#define BKP_DR23_D ((uint16_t)0xFFFF) /*!< Backup data */
+
+/******************* Bit definition for BKP_DR24 register *******************/
+#define BKP_DR24_D ((uint16_t)0xFFFF) /*!< Backup data */
+
+/******************* Bit definition for BKP_DR25 register *******************/
+#define BKP_DR25_D ((uint16_t)0xFFFF) /*!< Backup data */
+
+/******************* Bit definition for BKP_DR26 register *******************/
+#define BKP_DR26_D ((uint16_t)0xFFFF) /*!< Backup data */
+
+/******************* Bit definition for BKP_DR27 register *******************/
+#define BKP_DR27_D ((uint16_t)0xFFFF) /*!< Backup data */
+
+/******************* Bit definition for BKP_DR28 register *******************/
+#define BKP_DR28_D ((uint16_t)0xFFFF) /*!< Backup data */
+
+/******************* Bit definition for BKP_DR29 register *******************/
+#define BKP_DR29_D ((uint16_t)0xFFFF) /*!< Backup data */
+
+/******************* Bit definition for BKP_DR30 register *******************/
+#define BKP_DR30_D ((uint16_t)0xFFFF) /*!< Backup data */
+
+/******************* Bit definition for BKP_DR31 register *******************/
+#define BKP_DR31_D ((uint16_t)0xFFFF) /*!< Backup data */
+
+/******************* Bit definition for BKP_DR32 register *******************/
+#define BKP_DR32_D ((uint16_t)0xFFFF) /*!< Backup data */
+
+/******************* Bit definition for BKP_DR33 register *******************/
+#define BKP_DR33_D ((uint16_t)0xFFFF) /*!< Backup data */
+
+/******************* Bit definition for BKP_DR34 register *******************/
+#define BKP_DR34_D ((uint16_t)0xFFFF) /*!< Backup data */
+
+/******************* Bit definition for BKP_DR35 register *******************/
+#define BKP_DR35_D ((uint16_t)0xFFFF) /*!< Backup data */
+
+/******************* Bit definition for BKP_DR36 register *******************/
+#define BKP_DR36_D ((uint16_t)0xFFFF) /*!< Backup data */
+
+/******************* Bit definition for BKP_DR37 register *******************/
+#define BKP_DR37_D ((uint16_t)0xFFFF) /*!< Backup data */
+
+/******************* Bit definition for BKP_DR38 register *******************/
+#define BKP_DR38_D ((uint16_t)0xFFFF) /*!< Backup data */
+
+/******************* Bit definition for BKP_DR39 register *******************/
+#define BKP_DR39_D ((uint16_t)0xFFFF) /*!< Backup data */
+
+/******************* Bit definition for BKP_DR40 register *******************/
+#define BKP_DR40_D ((uint16_t)0xFFFF) /*!< Backup data */
+
+/******************* Bit definition for BKP_DR41 register *******************/
+#define BKP_DR41_D ((uint16_t)0xFFFF) /*!< Backup data */
+
+/******************* Bit definition for BKP_DR42 register *******************/
+#define BKP_DR42_D ((uint16_t)0xFFFF) /*!< Backup data */
+
+/****************** Bit definition for BKP_RTCCR register *******************/
+#define BKP_RTCCR_CAL ((uint16_t)0x007F) /*!< Calibration value */
+#define BKP_RTCCR_CCO ((uint16_t)0x0080) /*!< Calibration Clock Output */
+#define BKP_RTCCR_ASOE ((uint16_t)0x0100) /*!< Alarm or Second Output Enable */
+#define BKP_RTCCR_ASOS ((uint16_t)0x0200) /*!< Alarm or Second Output Selection */
+
+/******************** Bit definition for BKP_CR register ********************/
+#define BKP_CR_TPE ((uint8_t)0x01) /*!< TAMPER pin enable */
+#define BKP_CR_TPAL ((uint8_t)0x02) /*!< TAMPER pin active level */
+
+/******************* Bit definition for BKP_CSR register ********************/
+#define BKP_CSR_CTE ((uint16_t)0x0001) /*!< Clear Tamper event */
+#define BKP_CSR_CTI ((uint16_t)0x0002) /*!< Clear Tamper Interrupt */
+#define BKP_CSR_TPIE ((uint16_t)0x0004) /*!< TAMPER Pin interrupt enable */
+#define BKP_CSR_TEF ((uint16_t)0x0100) /*!< Tamper Event Flag */
+#define BKP_CSR_TIF ((uint16_t)0x0200) /*!< Tamper Interrupt Flag */
+
+/******************************************************************************/
+/* */
+/* Reset and Clock Control */
+/* */
+/******************************************************************************/
+
+/******************** Bit definition for RCC_CR register ********************/
+#define RCC_CR_HSION ((uint32_t)0x00000001) /*!< Internal High Speed clock enable */
+#define RCC_CR_HSIRDY ((uint32_t)0x00000002) /*!< Internal High Speed clock ready flag */
+#define RCC_CR_HSITRIM ((uint32_t)0x000000F8) /*!< Internal High Speed clock trimming */
+#define RCC_CR_HSICAL ((uint32_t)0x0000FF00) /*!< Internal High Speed clock Calibration */
+#define RCC_CR_HSEON ((uint32_t)0x00010000) /*!< External High Speed clock enable */
+#define RCC_CR_HSERDY ((uint32_t)0x00020000) /*!< External High Speed clock ready flag */
+#define RCC_CR_HSEBYP ((uint32_t)0x00040000) /*!< External High Speed clock Bypass */
+#define RCC_CR_CSSON ((uint32_t)0x00080000) /*!< Clock Security System enable */
+#define RCC_CR_PLLON ((uint32_t)0x01000000) /*!< PLL enable */
+#define RCC_CR_PLLRDY ((uint32_t)0x02000000) /*!< PLL clock ready flag */
+
+#ifdef STM32F10X_CL
+ #define RCC_CR_PLL2ON ((uint32_t)0x04000000) /*!< PLL2 enable */
+ #define RCC_CR_PLL2RDY ((uint32_t)0x08000000) /*!< PLL2 clock ready flag */
+ #define RCC_CR_PLL3ON ((uint32_t)0x10000000) /*!< PLL3 enable */
+ #define RCC_CR_PLL3RDY ((uint32_t)0x20000000) /*!< PLL3 clock ready flag */
+#endif /* STM32F10X_CL */
+
+/******************* Bit definition for RCC_CFGR register *******************/
+/*!< SW configuration */
+#define RCC_CFGR_SW ((uint32_t)0x00000003) /*!< SW[1:0] bits (System clock Switch) */
+#define RCC_CFGR_SW_0 ((uint32_t)0x00000001) /*!< Bit 0 */
+#define RCC_CFGR_SW_1 ((uint32_t)0x00000002) /*!< Bit 1 */
+
+#define RCC_CFGR_SW_HSI ((uint32_t)0x00000000) /*!< HSI selected as system clock */
+#define RCC_CFGR_SW_HSE ((uint32_t)0x00000001) /*!< HSE selected as system clock */
+#define RCC_CFGR_SW_PLL ((uint32_t)0x00000002) /*!< PLL selected as system clock */
+
+/*!< SWS configuration */
+#define RCC_CFGR_SWS ((uint32_t)0x0000000C) /*!< SWS[1:0] bits (System Clock Switch Status) */
+#define RCC_CFGR_SWS_0 ((uint32_t)0x00000004) /*!< Bit 0 */
+#define RCC_CFGR_SWS_1 ((uint32_t)0x00000008) /*!< Bit 1 */
+
+#define RCC_CFGR_SWS_HSI ((uint32_t)0x00000000) /*!< HSI oscillator used as system clock */
+#define RCC_CFGR_SWS_HSE ((uint32_t)0x00000004) /*!< HSE oscillator used as system clock */
+#define RCC_CFGR_SWS_PLL ((uint32_t)0x00000008) /*!< PLL used as system clock */
+
+/*!< HPRE configuration */
+#define RCC_CFGR_HPRE ((uint32_t)0x000000F0) /*!< HPRE[3:0] bits (AHB prescaler) */
+#define RCC_CFGR_HPRE_0 ((uint32_t)0x00000010) /*!< Bit 0 */
+#define RCC_CFGR_HPRE_1 ((uint32_t)0x00000020) /*!< Bit 1 */
+#define RCC_CFGR_HPRE_2 ((uint32_t)0x00000040) /*!< Bit 2 */
+#define RCC_CFGR_HPRE_3 ((uint32_t)0x00000080) /*!< Bit 3 */
+
+#define RCC_CFGR_HPRE_DIV1 ((uint32_t)0x00000000) /*!< SYSCLK not divided */
+#define RCC_CFGR_HPRE_DIV2 ((uint32_t)0x00000080) /*!< SYSCLK divided by 2 */
+#define RCC_CFGR_HPRE_DIV4 ((uint32_t)0x00000090) /*!< SYSCLK divided by 4 */
+#define RCC_CFGR_HPRE_DIV8 ((uint32_t)0x000000A0) /*!< SYSCLK divided by 8 */
+#define RCC_CFGR_HPRE_DIV16 ((uint32_t)0x000000B0) /*!< SYSCLK divided by 16 */
+#define RCC_CFGR_HPRE_DIV64 ((uint32_t)0x000000C0) /*!< SYSCLK divided by 64 */
+#define RCC_CFGR_HPRE_DIV128 ((uint32_t)0x000000D0) /*!< SYSCLK divided by 128 */
+#define RCC_CFGR_HPRE_DIV256 ((uint32_t)0x000000E0) /*!< SYSCLK divided by 256 */
+#define RCC_CFGR_HPRE_DIV512 ((uint32_t)0x000000F0) /*!< SYSCLK divided by 512 */
+
+/*!< PPRE1 configuration */
+#define RCC_CFGR_PPRE1 ((uint32_t)0x00000700) /*!< PRE1[2:0] bits (APB1 prescaler) */
+#define RCC_CFGR_PPRE1_0 ((uint32_t)0x00000100) /*!< Bit 0 */
+#define RCC_CFGR_PPRE1_1 ((uint32_t)0x00000200) /*!< Bit 1 */
+#define RCC_CFGR_PPRE1_2 ((uint32_t)0x00000400) /*!< Bit 2 */
+
+#define RCC_CFGR_PPRE1_DIV1 ((uint32_t)0x00000000) /*!< HCLK not divided */
+#define RCC_CFGR_PPRE1_DIV2 ((uint32_t)0x00000400) /*!< HCLK divided by 2 */
+#define RCC_CFGR_PPRE1_DIV4 ((uint32_t)0x00000500) /*!< HCLK divided by 4 */
+#define RCC_CFGR_PPRE1_DIV8 ((uint32_t)0x00000600) /*!< HCLK divided by 8 */
+#define RCC_CFGR_PPRE1_DIV16 ((uint32_t)0x00000700) /*!< HCLK divided by 16 */
+
+/*!< PPRE2 configuration */
+#define RCC_CFGR_PPRE2 ((uint32_t)0x00003800) /*!< PRE2[2:0] bits (APB2 prescaler) */
+#define RCC_CFGR_PPRE2_0 ((uint32_t)0x00000800) /*!< Bit 0 */
+#define RCC_CFGR_PPRE2_1 ((uint32_t)0x00001000) /*!< Bit 1 */
+#define RCC_CFGR_PPRE2_2 ((uint32_t)0x00002000) /*!< Bit 2 */
+
+#define RCC_CFGR_PPRE2_DIV1 ((uint32_t)0x00000000) /*!< HCLK not divided */
+#define RCC_CFGR_PPRE2_DIV2 ((uint32_t)0x00002000) /*!< HCLK divided by 2 */
+#define RCC_CFGR_PPRE2_DIV4 ((uint32_t)0x00002800) /*!< HCLK divided by 4 */
+#define RCC_CFGR_PPRE2_DIV8 ((uint32_t)0x00003000) /*!< HCLK divided by 8 */
+#define RCC_CFGR_PPRE2_DIV16 ((uint32_t)0x00003800) /*!< HCLK divided by 16 */
+
+/*!< ADCPPRE configuration */
+#define RCC_CFGR_ADCPRE ((uint32_t)0x0000C000) /*!< ADCPRE[1:0] bits (ADC prescaler) */
+#define RCC_CFGR_ADCPRE_0 ((uint32_t)0x00004000) /*!< Bit 0 */
+#define RCC_CFGR_ADCPRE_1 ((uint32_t)0x00008000) /*!< Bit 1 */
+
+#define RCC_CFGR_ADCPRE_DIV2 ((uint32_t)0x00000000) /*!< PCLK2 divided by 2 */
+#define RCC_CFGR_ADCPRE_DIV4 ((uint32_t)0x00004000) /*!< PCLK2 divided by 4 */
+#define RCC_CFGR_ADCPRE_DIV6 ((uint32_t)0x00008000) /*!< PCLK2 divided by 6 */
+#define RCC_CFGR_ADCPRE_DIV8 ((uint32_t)0x0000C000) /*!< PCLK2 divided by 8 */
+
+#define RCC_CFGR_PLLSRC ((uint32_t)0x00010000) /*!< PLL entry clock source */
+
+#define RCC_CFGR_PLLXTPRE ((uint32_t)0x00020000) /*!< HSE divider for PLL entry */
+
+/*!< PLLMUL configuration */
+#define RCC_CFGR_PLLMULL ((uint32_t)0x003C0000) /*!< PLLMUL[3:0] bits (PLL multiplication factor) */
+#define RCC_CFGR_PLLMULL_0 ((uint32_t)0x00040000) /*!< Bit 0 */
+#define RCC_CFGR_PLLMULL_1 ((uint32_t)0x00080000) /*!< Bit 1 */
+#define RCC_CFGR_PLLMULL_2 ((uint32_t)0x00100000) /*!< Bit 2 */
+#define RCC_CFGR_PLLMULL_3 ((uint32_t)0x00200000) /*!< Bit 3 */
+
+#ifdef STM32F10X_CL
+ #define RCC_CFGR_PLLSRC_HSI_Div2 ((uint32_t)0x00000000) /*!< HSI clock divided by 2 selected as PLL entry clock source */
+ #define RCC_CFGR_PLLSRC_PREDIV1 ((uint32_t)0x00010000) /*!< PREDIV1 clock selected as PLL entry clock source */
+
+ #define RCC_CFGR_PLLXTPRE_PREDIV1 ((uint32_t)0x00000000) /*!< PREDIV1 clock not divided for PLL entry */
+ #define RCC_CFGR_PLLXTPRE_PREDIV1_Div2 ((uint32_t)0x00020000) /*!< PREDIV1 clock divided by 2 for PLL entry */
+
+ #define RCC_CFGR_PLLMULL4 ((uint32_t)0x00080000) /*!< PLL input clock * 4 */
+ #define RCC_CFGR_PLLMULL5 ((uint32_t)0x000C0000) /*!< PLL input clock * 5 */
+ #define RCC_CFGR_PLLMULL6 ((uint32_t)0x00100000) /*!< PLL input clock * 6 */
+ #define RCC_CFGR_PLLMULL7 ((uint32_t)0x00140000) /*!< PLL input clock * 7 */
+ #define RCC_CFGR_PLLMULL8 ((uint32_t)0x00180000) /*!< PLL input clock * 8 */
+ #define RCC_CFGR_PLLMULL9 ((uint32_t)0x001C0000) /*!< PLL input clock * 9 */
+ #define RCC_CFGR_PLLMULL6_5 ((uint32_t)0x00340000) /*!< PLL input clock * 6.5 */
+
+ #define RCC_CFGR_OTGFSPRE ((uint32_t)0x00400000) /*!< USB OTG FS prescaler */
+
+/*!< MCO configuration */
+ #define RCC_CFGR_MCO ((uint32_t)0x0F000000) /*!< MCO[3:0] bits (Microcontroller Clock Output) */
+ #define RCC_CFGR_MCO_0 ((uint32_t)0x01000000) /*!< Bit 0 */
+ #define RCC_CFGR_MCO_1 ((uint32_t)0x02000000) /*!< Bit 1 */
+ #define RCC_CFGR_MCO_2 ((uint32_t)0x04000000) /*!< Bit 2 */
+ #define RCC_CFGR_MCO_3 ((uint32_t)0x08000000) /*!< Bit 3 */
+
+ #define RCC_CFGR_MCO_NOCLOCK ((uint32_t)0x00000000) /*!< No clock */
+ #define RCC_CFGR_MCO_SYSCLK ((uint32_t)0x04000000) /*!< System clock selected as MCO source */
+ #define RCC_CFGR_MCO_HSI ((uint32_t)0x05000000) /*!< HSI clock selected as MCO source */
+ #define RCC_CFGR_MCO_HSE ((uint32_t)0x06000000) /*!< HSE clock selected as MCO source */
+ #define RCC_CFGR_MCO_PLLCLK_Div2 ((uint32_t)0x07000000) /*!< PLL clock divided by 2 selected as MCO source */
+ #define RCC_CFGR_MCO_PLL2CLK ((uint32_t)0x08000000) /*!< PLL2 clock selected as MCO source*/
+ #define RCC_CFGR_MCO_PLL3CLK_Div2 ((uint32_t)0x09000000) /*!< PLL3 clock divided by 2 selected as MCO source*/
+ #define RCC_CFGR_MCO_Ext_HSE ((uint32_t)0x0A000000) /*!< XT1 external 3-25 MHz oscillator clock selected as MCO source */
+ #define RCC_CFGR_MCO_PLL3CLK ((uint32_t)0x0B000000) /*!< PLL3 clock selected as MCO source */
+#else
+ #define RCC_CFGR_PLLSRC_HSI_Div2 ((uint32_t)0x00000000) /*!< HSI clock divided by 2 selected as PLL entry clock source */
+ #define RCC_CFGR_PLLSRC_HSE ((uint32_t)0x00010000) /*!< HSE clock selected as PLL entry clock source */
+
+ #define RCC_CFGR_PLLXTPRE_HSE ((uint32_t)0x00000000) /*!< HSE clock not divided for PLL entry */
+ #define RCC_CFGR_PLLXTPRE_HSE_Div2 ((uint32_t)0x00020000) /*!< HSE clock divided by 2 for PLL entry */
+
+ #define RCC_CFGR_PLLMULL2 ((uint32_t)0x00000000) /*!< PLL input clock*2 */
+ #define RCC_CFGR_PLLMULL3 ((uint32_t)0x00040000) /*!< PLL input clock*3 */
+ #define RCC_CFGR_PLLMULL4 ((uint32_t)0x00080000) /*!< PLL input clock*4 */
+ #define RCC_CFGR_PLLMULL5 ((uint32_t)0x000C0000) /*!< PLL input clock*5 */
+ #define RCC_CFGR_PLLMULL6 ((uint32_t)0x00100000) /*!< PLL input clock*6 */
+ #define RCC_CFGR_PLLMULL7 ((uint32_t)0x00140000) /*!< PLL input clock*7 */
+ #define RCC_CFGR_PLLMULL8 ((uint32_t)0x00180000) /*!< PLL input clock*8 */
+ #define RCC_CFGR_PLLMULL9 ((uint32_t)0x001C0000) /*!< PLL input clock*9 */
+ #define RCC_CFGR_PLLMULL10 ((uint32_t)0x00200000) /*!< PLL input clock10 */
+ #define RCC_CFGR_PLLMULL11 ((uint32_t)0x00240000) /*!< PLL input clock*11 */
+ #define RCC_CFGR_PLLMULL12 ((uint32_t)0x00280000) /*!< PLL input clock*12 */
+ #define RCC_CFGR_PLLMULL13 ((uint32_t)0x002C0000) /*!< PLL input clock*13 */
+ #define RCC_CFGR_PLLMULL14 ((uint32_t)0x00300000) /*!< PLL input clock*14 */
+ #define RCC_CFGR_PLLMULL15 ((uint32_t)0x00340000) /*!< PLL input clock*15 */
+ #define RCC_CFGR_PLLMULL16 ((uint32_t)0x00380000) /*!< PLL input clock*16 */
+ #define RCC_CFGR_USBPRE ((uint32_t)0x00400000) /*!< USB Device prescaler */
+
+/*!< MCO configuration */
+ #define RCC_CFGR_MCO ((uint32_t)0x07000000) /*!< MCO[2:0] bits (Microcontroller Clock Output) */
+ #define RCC_CFGR_MCO_0 ((uint32_t)0x01000000) /*!< Bit 0 */
+ #define RCC_CFGR_MCO_1 ((uint32_t)0x02000000) /*!< Bit 1 */
+ #define RCC_CFGR_MCO_2 ((uint32_t)0x04000000) /*!< Bit 2 */
+
+ #define RCC_CFGR_MCO_NOCLOCK ((uint32_t)0x00000000) /*!< No clock */
+ #define RCC_CFGR_MCO_SYSCLK ((uint32_t)0x04000000) /*!< System clock selected as MCO source */
+ #define RCC_CFGR_MCO_HSI ((uint32_t)0x05000000) /*!< HSI clock selected as MCO source */
+ #define RCC_CFGR_MCO_HSE ((uint32_t)0x06000000) /*!< HSE clock selected as MCO source */
+ #define RCC_CFGR_MCO_PLL ((uint32_t)0x07000000) /*!< PLL clock divided by 2 selected as MCO source */
+#endif /* STM32F10X_CL */
+
+/*!<****************** Bit definition for RCC_CIR register ********************/
+#define RCC_CIR_LSIRDYF ((uint32_t)0x00000001) /*!< LSI Ready Interrupt flag */
+#define RCC_CIR_LSERDYF ((uint32_t)0x00000002) /*!< LSE Ready Interrupt flag */
+#define RCC_CIR_HSIRDYF ((uint32_t)0x00000004) /*!< HSI Ready Interrupt flag */
+#define RCC_CIR_HSERDYF ((uint32_t)0x00000008) /*!< HSE Ready Interrupt flag */
+#define RCC_CIR_PLLRDYF ((uint32_t)0x00000010) /*!< PLL Ready Interrupt flag */
+#define RCC_CIR_CSSF ((uint32_t)0x00000080) /*!< Clock Security System Interrupt flag */
+#define RCC_CIR_LSIRDYIE ((uint32_t)0x00000100) /*!< LSI Ready Interrupt Enable */
+#define RCC_CIR_LSERDYIE ((uint32_t)0x00000200) /*!< LSE Ready Interrupt Enable */
+#define RCC_CIR_HSIRDYIE ((uint32_t)0x00000400) /*!< HSI Ready Interrupt Enable */
+#define RCC_CIR_HSERDYIE ((uint32_t)0x00000800) /*!< HSE Ready Interrupt Enable */
+#define RCC_CIR_PLLRDYIE ((uint32_t)0x00001000) /*!< PLL Ready Interrupt Enable */
+#define RCC_CIR_LSIRDYC ((uint32_t)0x00010000) /*!< LSI Ready Interrupt Clear */
+#define RCC_CIR_LSERDYC ((uint32_t)0x00020000) /*!< LSE Ready Interrupt Clear */
+#define RCC_CIR_HSIRDYC ((uint32_t)0x00040000) /*!< HSI Ready Interrupt Clear */
+#define RCC_CIR_HSERDYC ((uint32_t)0x00080000) /*!< HSE Ready Interrupt Clear */
+#define RCC_CIR_PLLRDYC ((uint32_t)0x00100000) /*!< PLL Ready Interrupt Clear */
+#define RCC_CIR_CSSC ((uint32_t)0x00800000) /*!< Clock Security System Interrupt Clear */
+
+#ifdef STM32F10X_CL
+ #define RCC_CIR_PLL2RDYF ((uint32_t)0x00000020) /*!< PLL2 Ready Interrupt flag */
+ #define RCC_CIR_PLL3RDYF ((uint32_t)0x00000040) /*!< PLL3 Ready Interrupt flag */
+ #define RCC_CIR_PLL2RDYIE ((uint32_t)0x00002000) /*!< PLL2 Ready Interrupt Enable */
+ #define RCC_CIR_PLL3RDYIE ((uint32_t)0x00004000) /*!< PLL3 Ready Interrupt Enable */
+ #define RCC_CIR_PLL2RDYC ((uint32_t)0x00200000) /*!< PLL2 Ready Interrupt Clear */
+ #define RCC_CIR_PLL3RDYC ((uint32_t)0x00400000) /*!< PLL3 Ready Interrupt Clear */
+#endif /* STM32F10X_CL */
+
+/***************** Bit definition for RCC_APB2RSTR register *****************/
+#define RCC_APB2RSTR_AFIORST ((uint16_t)0x0001) /*!< Alternate Function I/O reset */
+#define RCC_APB2RSTR_IOPARST ((uint16_t)0x0004) /*!< I/O port A reset */
+#define RCC_APB2RSTR_IOPBRST ((uint16_t)0x0008) /*!< I/O port B reset */
+#define RCC_APB2RSTR_IOPCRST ((uint16_t)0x0010) /*!< I/O port C reset */
+#define RCC_APB2RSTR_IOPDRST ((uint16_t)0x0020) /*!< I/O port D reset */
+#define RCC_APB2RSTR_ADC1RST ((uint16_t)0x0200) /*!< ADC 1 interface reset */
+#define RCC_APB2RSTR_ADC2RST ((uint16_t)0x0400) /*!< ADC 2 interface reset */
+#define RCC_APB2RSTR_TIM1RST ((uint16_t)0x0800) /*!< TIM1 Timer reset */
+#define RCC_APB2RSTR_SPI1RST ((uint16_t)0x1000) /*!< SPI 1 reset */
+#define RCC_APB2RSTR_USART1RST ((uint16_t)0x4000) /*!< USART1 reset */
+
+#ifndef STM32F10X_LD
+ #define RCC_APB2RSTR_IOPERST ((uint16_t)0x0040) /*!< I/O port E reset */
+#endif /* STM32F10X_HD */
+
+#ifdef STM32F10X_HD
+ #define RCC_APB2RSTR_IOPFRST ((uint16_t)0x0080) /*!< I/O port F reset */
+ #define RCC_APB2RSTR_IOPGRST ((uint16_t)0x0100) /*!< I/O port G reset */
+ #define RCC_APB2RSTR_TIM8RST ((uint16_t)0x2000) /*!< TIM8 Timer reset */
+ #define RCC_APB2RSTR_ADC3RST ((uint16_t)0x8000) /*!< ADC3 interface reset */
+#endif /* STM32F10X_HD */
+
+/***************** Bit definition for RCC_APB1RSTR register *****************/
+#define RCC_APB1RSTR_TIM2RST ((uint32_t)0x00000001) /*!< Timer 2 reset */
+#define RCC_APB1RSTR_TIM3RST ((uint32_t)0x00000002) /*!< Timer 3 reset */
+#define RCC_APB1RSTR_WWDGRST ((uint32_t)0x00000800) /*!< Window Watchdog reset */
+#define RCC_APB1RSTR_USART2RST ((uint32_t)0x00020000) /*!< USART 2 reset */
+#define RCC_APB1RSTR_I2C1RST ((uint32_t)0x00200000) /*!< I2C 1 reset */
+#define RCC_APB1RSTR_CAN1RST ((uint32_t)0x02000000) /*!< CAN1 reset */
+#define RCC_APB1RSTR_BKPRST ((uint32_t)0x08000000) /*!< Backup interface reset */
+#define RCC_APB1RSTR_PWRRST ((uint32_t)0x10000000) /*!< Power interface reset */
+
+#ifndef STM32F10X_LD
+ #define RCC_APB1RSTR_TIM4RST ((uint32_t)0x00000004) /*!< Timer 4 reset */
+ #define RCC_APB1RSTR_SPI2RST ((uint32_t)0x00004000) /*!< SPI 2 reset */
+ #define RCC_APB1RSTR_USART3RST ((uint32_t)0x00040000) /*!< RUSART 3 reset */
+ #define RCC_APB1RSTR_I2C2RST ((uint32_t)0x00400000) /*!< I2C 2 reset */
+#endif /* STM32F10X_HD */
+
+#if defined (STM32F10X_HD) || defined (STM32F10X_MD) || defined (STM32F10X_LD)
+ #define RCC_APB1RSTR_USBRST ((uint32_t)0x00800000) /*!< USB Device reset */
+#endif
+
+#if defined (STM32F10X_HD) || defined (STM32F10X_CL)
+ #define RCC_APB1RSTR_TIM5RST ((uint32_t)0x00000008) /*!< Timer 5 reset */
+ #define RCC_APB1RSTR_TIM6RST ((uint32_t)0x00000010) /*!< Timer 6 reset */
+ #define RCC_APB1RSTR_TIM7RST ((uint32_t)0x00000020) /*!< Timer 7 reset */
+ #define RCC_APB1RSTR_SPI3RST ((uint32_t)0x00008000) /*!< SPI 3 reset */
+ #define RCC_APB1RSTR_UART4RST ((uint32_t)0x00080000) /*!< UART 4 reset */
+ #define RCC_APB1RSTR_UART5RST ((uint32_t)0x00100000) /*!< UART 5 reset */
+ #define RCC_APB1RSTR_DACRST ((uint32_t)0x20000000) /*!< DAC interface reset */
+#endif
+
+#ifdef STM32F10X_CL
+ #define RCC_APB1RSTR_CAN2RST ((uint32_t)0x08000000) /*!< CAN2 reset */
+#endif /* STM32F10X_CL */
+
+/****************** Bit definition for RCC_AHBENR register ******************/
+#define RCC_AHBENR_DMA1EN ((uint16_t)0x0001) /*!< DMA1 clock enable */
+#define RCC_AHBENR_SRAMEN ((uint16_t)0x0004) /*!< SRAM interface clock enable */
+#define RCC_AHBENR_FLITFEN ((uint16_t)0x0010) /*!< FLITF clock enable */
+#define RCC_AHBENR_CRCEN ((uint16_t)0x0040) /*!< CRC clock enable */
+
+#if defined (STM32F10X_HD) || defined (STM32F10X_CL)
+ #define RCC_AHBENR_DMA2EN ((uint16_t)0x0002) /*!< DMA2 clock enable */
+#endif
+
+#ifdef STM32F10X_HD
+ #define RCC_AHBENR_FSMCEN ((uint16_t)0x0100) /*!< FSMC clock enable */
+ #define RCC_AHBENR_SDIOEN ((uint16_t)0x0400) /*!< SDIO clock enable */
+#endif /* STM32F10X_HD */
+
+#ifdef STM32F10X_CL
+ #define RCC_AHBENR_OTGFSEN ((uint32_t)0x00001000) /*!< USB OTG FS clock enable */
+ #define RCC_AHBENR_ETHMACEN ((uint32_t)0x00004000) /*!< ETHERNET MAC clock enable */
+ #define RCC_AHBENR_ETHMACTXEN ((uint32_t)0x00008000) /*!< ETHERNET MAC Tx clock enable */
+ #define RCC_AHBENR_ETHMACRXEN ((uint32_t)0x00010000) /*!< ETHERNET MAC Rx clock enable */
+#endif /* STM32F10X_CL */
+
+/****************** Bit definition for RCC_APB2ENR register *****************/
+#define RCC_APB2ENR_AFIOEN ((uint16_t)0x0001) /*!< Alternate Function I/O clock enable */
+#define RCC_APB2ENR_IOPAEN ((uint16_t)0x0004) /*!< I/O port A clock enable */
+#define RCC_APB2ENR_IOPBEN ((uint16_t)0x0008) /*!< I/O port B clock enable */
+#define RCC_APB2ENR_IOPCEN ((uint16_t)0x0010) /*!< I/O port C clock enable */
+#define RCC_APB2ENR_IOPDEN ((uint16_t)0x0020) /*!< I/O port D clock enable */
+#define RCC_APB2ENR_ADC1EN ((uint16_t)0x0200) /*!< ADC 1 interface clock enable */
+#define RCC_APB2ENR_ADC2EN ((uint16_t)0x0400) /*!< ADC 2 interface clock enable */
+#define RCC_APB2ENR_TIM1EN ((uint16_t)0x0800) /*!< TIM1 Timer clock enable */
+#define RCC_APB2ENR_SPI1EN ((uint16_t)0x1000) /*!< SPI 1 clock enable */
+#define RCC_APB2ENR_USART1EN ((uint16_t)0x4000) /*!< USART1 clock enable */
+
+#ifndef STM32F10X_LD
+ #define RCC_APB2ENR_IOPEEN ((uint16_t)0x0040) /*!< I/O port E clock enable */
+#endif /* STM32F10X_HD */
+
+#ifdef STM32F10X_HD
+ #define RCC_APB2ENR_IOPFEN ((uint16_t)0x0080) /*!< I/O port F clock enable */
+ #define RCC_APB2ENR_IOPGEN ((uint16_t)0x0100) /*!< I/O port G clock enable */
+ #define RCC_APB2ENR_TIM8EN ((uint16_t)0x2000) /*!< TIM8 Timer clock enable */
+ #define RCC_APB2ENR_ADC3EN ((uint16_t)0x8000) /*!< DMA1 clock enable */
+#endif /* STM32F10X_HD */
+
+/***************** Bit definition for RCC_APB1ENR register ******************/
+#define RCC_APB1ENR_TIM2EN ((uint32_t)0x00000001) /*!< Timer 2 clock enabled*/
+#define RCC_APB1ENR_TIM3EN ((uint32_t)0x00000002) /*!< Timer 3 clock enable */
+#define RCC_APB1ENR_WWDGEN ((uint32_t)0x00000800) /*!< Window Watchdog clock enable */
+#define RCC_APB1ENR_USART2EN ((uint32_t)0x00020000) /*!< USART 2 clock enable */
+#define RCC_APB1ENR_I2C1EN ((uint32_t)0x00200000) /*!< I2C 1 clock enable */
+#define RCC_APB1ENR_CAN1EN ((uint32_t)0x02000000) /*!< CAN1 clock enable */
+#define RCC_APB1ENR_BKPEN ((uint32_t)0x08000000) /*!< Backup interface clock enable */
+#define RCC_APB1ENR_PWREN ((uint32_t)0x10000000) /*!< Power interface clock enable */
+
+#ifndef STM32F10X_LD
+ #define RCC_APB1ENR_TIM4EN ((uint32_t)0x00000004) /*!< Timer 4 clock enable */
+ #define RCC_APB1ENR_SPI2EN ((uint32_t)0x00004000) /*!< SPI 2 clock enable */
+ #define RCC_APB1ENR_USART3EN ((uint32_t)0x00040000) /*!< USART 3 clock enable */
+ #define RCC_APB1ENR_I2C2EN ((uint32_t)0x00400000) /*!< I2C 2 clock enable */
+#endif /* STM32F10X_HD */
+
+#if defined (STM32F10X_HD) || defined (STM32F10X_MD) || defined (STM32F10X_LD)
+ #define RCC_APB1ENR_USBEN ((uint32_t)0x00800000) /*!< USB Device clock enable */
+#endif
+
+#if defined (STM32F10X_HD) || defined (STM32F10X_CL)
+ #define RCC_APB1ENR_TIM5EN ((uint32_t)0x00000008) /*!< Timer 5 clock enable */
+ #define RCC_APB1ENR_TIM6EN ((uint32_t)0x00000010) /*!< Timer 6 clock enable */
+ #define RCC_APB1ENR_TIM7EN ((uint32_t)0x00000020) /*!< Timer 7 clock enable */
+ #define RCC_APB1ENR_SPI3EN ((uint32_t)0x00008000) /*!< SPI 3 clock enable */
+ #define RCC_APB1ENR_UART4EN ((uint32_t)0x00080000) /*!< UART 4 clock enable */
+ #define RCC_APB1ENR_UART5EN ((uint32_t)0x00100000) /*!< UART 5 clock enable */
+ #define RCC_APB1ENR_DACEN ((uint32_t)0x20000000) /*!< DAC interface clock enable */
+#endif
+
+#ifdef STM32F10X_CL
+ #define RCC_APB1ENR_CAN2EN ((uint32_t)0x08000000) /*!< CAN2 clock enable */
+#endif /* STM32F10X_CL */
+
+/******************* Bit definition for RCC_BDCR register *******************/
+#define RCC_BDCR_LSEON ((uint32_t)0x00000001) /*!< External Low Speed oscillator enable */
+#define RCC_BDCR_LSERDY ((uint32_t)0x00000002) /*!< External Low Speed oscillator Ready */
+#define RCC_BDCR_LSEBYP ((uint32_t)0x00000004) /*!< External Low Speed oscillator Bypass */
+
+#define RCC_BDCR_RTCSEL ((uint32_t)0x00000300) /*!< RTCSEL[1:0] bits (RTC clock source selection) */
+#define RCC_BDCR_RTCSEL_0 ((uint32_t)0x00000100) /*!< Bit 0 */
+#define RCC_BDCR_RTCSEL_1 ((uint32_t)0x00000200) /*!< Bit 1 */
+
+/*!< RTC congiguration */
+#define RCC_BDCR_RTCSEL_NOCLOCK ((uint32_t)0x00000000) /*!< No clock */
+#define RCC_BDCR_RTCSEL_LSE ((uint32_t)0x00000100) /*!< LSE oscillator clock used as RTC clock */
+#define RCC_BDCR_RTCSEL_LSI ((uint32_t)0x00000200) /*!< LSI oscillator clock used as RTC clock */
+#define RCC_BDCR_RTCSEL_HSE ((uint32_t)0x00000300) /*!< HSE oscillator clock divided by 128 used as RTC clock */
+
+#define RCC_BDCR_RTCEN ((uint32_t)0x00008000) /*!< RTC clock enable */
+#define RCC_BDCR_BDRST ((uint32_t)0x00010000) /*!< Backup domain software reset */
+
+/******************* Bit definition for RCC_CSR register ********************/
+#define RCC_CSR_LSION ((uint32_t)0x00000001) /*!< Internal Low Speed oscillator enable */
+#define RCC_CSR_LSIRDY ((uint32_t)0x00000002) /*!< Internal Low Speed oscillator Ready */
+#define RCC_CSR_RMVF ((uint32_t)0x01000000) /*!< Remove reset flag */
+#define RCC_CSR_PINRSTF ((uint32_t)0x04000000) /*!< PIN reset flag */
+#define RCC_CSR_PORRSTF ((uint32_t)0x08000000) /*!< POR/PDR reset flag */
+#define RCC_CSR_SFTRSTF ((uint32_t)0x10000000) /*!< Software Reset flag */
+#define RCC_CSR_IWDGRSTF ((uint32_t)0x20000000) /*!< Independent Watchdog reset flag */
+#define RCC_CSR_WWDGRSTF ((uint32_t)0x40000000) /*!< Window watchdog reset flag */
+#define RCC_CSR_LPWRRSTF ((uint32_t)0x80000000) /*!< Low-Power reset flag */
+
+#ifdef STM32F10X_CL
+/******************* Bit definition for RCC_AHBRSTR register ****************/
+ #define RCC_AHBRSTR_OTGFSRST ((uint32_t)0x00001000) /*!< USB OTG FS reset */
+ #define RCC_AHBRSTR_ETHMACRST ((uint32_t)0x00004000) /*!< ETHERNET MAC reset */
+
+/******************* Bit definition for RCC_CFGR2 register ******************/
+/*!< PREDIV1 configuration */
+ #define RCC_CFGR2_PREDIV1 ((uint32_t)0x0000000F) /*!< PREDIV1[3:0] bits */
+ #define RCC_CFGR2_PREDIV1_0 ((uint32_t)0x00000001) /*!< Bit 0 */
+ #define RCC_CFGR2_PREDIV1_1 ((uint32_t)0x00000002) /*!< Bit 1 */
+ #define RCC_CFGR2_PREDIV1_2 ((uint32_t)0x00000004) /*!< Bit 2 */
+ #define RCC_CFGR2_PREDIV1_3 ((uint32_t)0x00000008) /*!< Bit 3 */
+
+ #define RCC_CFGR2_PREDIV1_DIV1 ((uint32_t)0x00000000) /*!< PREDIV1 input clock not divided */
+ #define RCC_CFGR2_PREDIV1_DIV2 ((uint32_t)0x00000001) /*!< PREDIV1 input clock divided by 2 */
+ #define RCC_CFGR2_PREDIV1_DIV3 ((uint32_t)0x00000002) /*!< PREDIV1 input clock divided by 3 */
+ #define RCC_CFGR2_PREDIV1_DIV4 ((uint32_t)0x00000003) /*!< PREDIV1 input clock divided by 4 */
+ #define RCC_CFGR2_PREDIV1_DIV5 ((uint32_t)0x00000004) /*!< PREDIV1 input clock divided by 5 */
+ #define RCC_CFGR2_PREDIV1_DIV6 ((uint32_t)0x00000005) /*!< PREDIV1 input clock divided by 6 */
+ #define RCC_CFGR2_PREDIV1_DIV7 ((uint32_t)0x00000006) /*!< PREDIV1 input clock divided by 7 */
+ #define RCC_CFGR2_PREDIV1_DIV8 ((uint32_t)0x00000007) /*!< PREDIV1 input clock divided by 8 */
+ #define RCC_CFGR2_PREDIV1_DIV9 ((uint32_t)0x00000008) /*!< PREDIV1 input clock divided by 9 */
+ #define RCC_CFGR2_PREDIV1_DIV10 ((uint32_t)0x00000009) /*!< PREDIV1 input clock divided by 10 */
+ #define RCC_CFGR2_PREDIV1_DIV11 ((uint32_t)0x0000000A) /*!< PREDIV1 input clock divided by 11 */
+ #define RCC_CFGR2_PREDIV1_DIV12 ((uint32_t)0x0000000B) /*!< PREDIV1 input clock divided by 12 */
+ #define RCC_CFGR2_PREDIV1_DIV13 ((uint32_t)0x0000000C) /*!< PREDIV1 input clock divided by 13 */
+ #define RCC_CFGR2_PREDIV1_DIV14 ((uint32_t)0x0000000D) /*!< PREDIV1 input clock divided by 14 */
+ #define RCC_CFGR2_PREDIV1_DIV15 ((uint32_t)0x0000000E) /*!< PREDIV1 input clock divided by 15 */
+ #define RCC_CFGR2_PREDIV1_DIV16 ((uint32_t)0x0000000F) /*!< PREDIV1 input clock divided by 16 */
+
+/*!< PREDIV2 configuration */
+ #define RCC_CFGR2_PREDIV2 ((uint32_t)0x000000F0) /*!< PREDIV2[3:0] bits */
+ #define RCC_CFGR2_PREDIV2_0 ((uint32_t)0x00000010) /*!< Bit 0 */
+ #define RCC_CFGR2_PREDIV2_1 ((uint32_t)0x00000020) /*!< Bit 1 */
+ #define RCC_CFGR2_PREDIV2_2 ((uint32_t)0x00000040) /*!< Bit 2 */
+ #define RCC_CFGR2_PREDIV2_3 ((uint32_t)0x00000080) /*!< Bit 3 */
+
+ #define RCC_CFGR2_PREDIV2_DIV1 ((uint32_t)0x00000000) /*!< PREDIV2 input clock not divided */
+ #define RCC_CFGR2_PREDIV2_DIV2 ((uint32_t)0x00000010) /*!< PREDIV2 input clock divided by 2 */
+ #define RCC_CFGR2_PREDIV2_DIV3 ((uint32_t)0x00000020) /*!< PREDIV2 input clock divided by 3 */
+ #define RCC_CFGR2_PREDIV2_DIV4 ((uint32_t)0x00000030) /*!< PREDIV2 input clock divided by 4 */
+ #define RCC_CFGR2_PREDIV2_DIV5 ((uint32_t)0x00000040) /*!< PREDIV2 input clock divided by 5 */
+ #define RCC_CFGR2_PREDIV2_DIV6 ((uint32_t)0x00000050) /*!< PREDIV2 input clock divided by 6 */
+ #define RCC_CFGR2_PREDIV2_DIV7 ((uint32_t)0x00000060) /*!< PREDIV2 input clock divided by 7 */
+ #define RCC_CFGR2_PREDIV2_DIV8 ((uint32_t)0x00000070) /*!< PREDIV2 input clock divided by 8 */
+ #define RCC_CFGR2_PREDIV2_DIV9 ((uint32_t)0x00000080) /*!< PREDIV2 input clock divided by 9 */
+ #define RCC_CFGR2_PREDIV2_DIV10 ((uint32_t)0x00000090) /*!< PREDIV2 input clock divided by 10 */
+ #define RCC_CFGR2_PREDIV2_DIV11 ((uint32_t)0x000000A0) /*!< PREDIV2 input clock divided by 11 */
+ #define RCC_CFGR2_PREDIV2_DIV12 ((uint32_t)0x000000B0) /*!< PREDIV2 input clock divided by 12 */
+ #define RCC_CFGR2_PREDIV2_DIV13 ((uint32_t)0x000000C0) /*!< PREDIV2 input clock divided by 13 */
+ #define RCC_CFGR2_PREDIV2_DIV14 ((uint32_t)0x000000D0) /*!< PREDIV2 input clock divided by 14 */
+ #define RCC_CFGR2_PREDIV2_DIV15 ((uint32_t)0x000000E0) /*!< PREDIV2 input clock divided by 15 */
+ #define RCC_CFGR2_PREDIV2_DIV16 ((uint32_t)0x000000F0) /*!< PREDIV2 input clock divided by 16 */
+
+/*!< PLL2MUL configuration */
+ #define RCC_CFGR2_PLL2MUL ((uint32_t)0x00000F00) /*!< PLL2MUL[3:0] bits */
+ #define RCC_CFGR2_PLL2MUL_0 ((uint32_t)0x00000100) /*!< Bit 0 */
+ #define RCC_CFGR2_PLL2MUL_1 ((uint32_t)0x00000200) /*!< Bit 1 */
+ #define RCC_CFGR2_PLL2MUL_2 ((uint32_t)0x00000400) /*!< Bit 2 */
+ #define RCC_CFGR2_PLL2MUL_3 ((uint32_t)0x00000800) /*!< Bit 3 */
+
+ #define RCC_CFGR2_PLL2MUL8 ((uint32_t)0x00000600) /*!< PLL2 input clock * 8 */
+ #define RCC_CFGR2_PLL2MUL9 ((uint32_t)0x00000700) /*!< PLL2 input clock * 9 */
+ #define RCC_CFGR2_PLL2MUL10 ((uint32_t)0x00000800) /*!< PLL2 input clock * 10 */
+ #define RCC_CFGR2_PLL2MUL11 ((uint32_t)0x00000900) /*!< PLL2 input clock * 11 */
+ #define RCC_CFGR2_PLL2MUL12 ((uint32_t)0x00000A00) /*!< PLL2 input clock * 12 */
+ #define RCC_CFGR2_PLL2MUL13 ((uint32_t)0x00000B00) /*!< PLL2 input clock * 13 */
+ #define RCC_CFGR2_PLL2MUL14 ((uint32_t)0x00000C00) /*!< PLL2 input clock * 14 */
+ #define RCC_CFGR2_PLL2MUL16 ((uint32_t)0x00000E00) /*!< PLL2 input clock * 16 */
+ #define RCC_CFGR2_PLL2MUL20 ((uint32_t)0x00000F00) /*!< PLL2 input clock * 20 */
+
+/*!< PLL3MUL configuration */
+ #define RCC_CFGR2_PLL3MUL ((uint32_t)0x0000F000) /*!< PLL3MUL[3:0] bits */
+ #define RCC_CFGR2_PLL3MUL_0 ((uint32_t)0x00001000) /*!< Bit 0 */
+ #define RCC_CFGR2_PLL3MUL_1 ((uint32_t)0x00002000) /*!< Bit 1 */
+ #define RCC_CFGR2_PLL3MUL_2 ((uint32_t)0x00004000) /*!< Bit 2 */
+ #define RCC_CFGR2_PLL3MUL_3 ((uint32_t)0x00008000) /*!< Bit 3 */
+
+ #define RCC_CFGR2_PLL3MUL8 ((uint32_t)0x00006000) /*!< PLL3 input clock * 8 */
+ #define RCC_CFGR2_PLL3MUL9 ((uint32_t)0x00007000) /*!< PLL3 input clock * 9 */
+ #define RCC_CFGR2_PLL3MUL10 ((uint32_t)0x00008000) /*!< PLL3 input clock * 10 */
+ #define RCC_CFGR2_PLL3MUL11 ((uint32_t)0x00009000) /*!< PLL3 input clock * 11 */
+ #define RCC_CFGR2_PLL3MUL12 ((uint32_t)0x0000A000) /*!< PLL3 input clock * 12 */
+ #define RCC_CFGR2_PLL3MUL13 ((uint32_t)0x0000B000) /*!< PLL3 input clock * 13 */
+ #define RCC_CFGR2_PLL3MUL14 ((uint32_t)0x0000C000) /*!< PLL3 input clock * 14 */
+ #define RCC_CFGR2_PLL3MUL16 ((uint32_t)0x0000E000) /*!< PLL3 input clock * 16 */
+ #define RCC_CFGR2_PLL3MUL20 ((uint32_t)0x0000F000) /*!< PLL3 input clock * 20 */
+
+ #define RCC_CFGR2_PREDIV1SRC ((uint32_t)0x00010000) /*!< PREDIV1 entry clock source */
+ #define RCC_CFGR2_PREDIV1SRC_PLL2 ((uint32_t)0x00010000) /*!< PLL2 selected as PREDIV1 entry clock source */
+ #define RCC_CFGR2_PREDIV1SRC_HSE ((uint32_t)0x00000000) /*!< HSE selected as PREDIV1 entry clock source */
+ #define RCC_CFGR2_I2S2SRC ((uint32_t)0x00020000) /*!< I2S2 entry clock source */
+ #define RCC_CFGR2_I2S3SRC ((uint32_t)0x00040000) /*!< I2S3 clock source */
+#endif /* STM32F10X_CL */
+
+/******************************************************************************/
+/* */
+/* General Purpose and Alternate Function I/O */
+/* */
+/******************************************************************************/
+
+/******************* Bit definition for GPIO_CRL register *******************/
+#define GPIO_CRL_MODE ((uint32_t)0x33333333) /*!< Port x mode bits */
+
+#define GPIO_CRL_MODE0 ((uint32_t)0x00000003) /*!< MODE0[1:0] bits (Port x mode bits, pin 0) */
+#define GPIO_CRL_MODE0_0 ((uint32_t)0x00000001) /*!< Bit 0 */
+#define GPIO_CRL_MODE0_1 ((uint32_t)0x00000002) /*!< Bit 1 */
+
+#define GPIO_CRL_MODE1 ((uint32_t)0x00000030) /*!< MODE1[1:0] bits (Port x mode bits, pin 1) */
+#define GPIO_CRL_MODE1_0 ((uint32_t)0x00000010) /*!< Bit 0 */
+#define GPIO_CRL_MODE1_1 ((uint32_t)0x00000020) /*!< Bit 1 */
+
+#define GPIO_CRL_MODE2 ((uint32_t)0x00000300) /*!< MODE2[1:0] bits (Port x mode bits, pin 2) */
+#define GPIO_CRL_MODE2_0 ((uint32_t)0x00000100) /*!< Bit 0 */
+#define GPIO_CRL_MODE2_1 ((uint32_t)0x00000200) /*!< Bit 1 */
+
+#define GPIO_CRL_MODE3 ((uint32_t)0x00003000) /*!< MODE3[1:0] bits (Port x mode bits, pin 3) */
+#define GPIO_CRL_MODE3_0 ((uint32_t)0x00001000) /*!< Bit 0 */
+#define GPIO_CRL_MODE3_1 ((uint32_t)0x00002000) /*!< Bit 1 */
+
+#define GPIO_CRL_MODE4 ((uint32_t)0x00030000) /*!< MODE4[1:0] bits (Port x mode bits, pin 4) */
+#define GPIO_CRL_MODE4_0 ((uint32_t)0x00010000) /*!< Bit 0 */
+#define GPIO_CRL_MODE4_1 ((uint32_t)0x00020000) /*!< Bit 1 */
+
+#define GPIO_CRL_MODE5 ((uint32_t)0x00300000) /*!< MODE5[1:0] bits (Port x mode bits, pin 5) */
+#define GPIO_CRL_MODE5_0 ((uint32_t)0x00100000) /*!< Bit 0 */
+#define GPIO_CRL_MODE5_1 ((uint32_t)0x00200000) /*!< Bit 1 */
+
+#define GPIO_CRL_MODE6 ((uint32_t)0x03000000) /*!< MODE6[1:0] bits (Port x mode bits, pin 6) */
+#define GPIO_CRL_MODE6_0 ((uint32_t)0x01000000) /*!< Bit 0 */
+#define GPIO_CRL_MODE6_1 ((uint32_t)0x02000000) /*!< Bit 1 */
+
+#define GPIO_CRL_MODE7 ((uint32_t)0x30000000) /*!< MODE7[1:0] bits (Port x mode bits, pin 7) */
+#define GPIO_CRL_MODE7_0 ((uint32_t)0x10000000) /*!< Bit 0 */
+#define GPIO_CRL_MODE7_1 ((uint32_t)0x20000000) /*!< Bit 1 */
+
+#define GPIO_CRL_CNF ((uint32_t)0xCCCCCCCC) /*!< Port x configuration bits */
+
+#define GPIO_CRL_CNF0 ((uint32_t)0x0000000C) /*!< CNF0[1:0] bits (Port x configuration bits, pin 0) */
+#define GPIO_CRL_CNF0_0 ((uint32_t)0x00000004) /*!< Bit 0 */
+#define GPIO_CRL_CNF0_1 ((uint32_t)0x00000008) /*!< Bit 1 */
+
+#define GPIO_CRL_CNF1 ((uint32_t)0x000000C0) /*!< CNF1[1:0] bits (Port x configuration bits, pin 1) */
+#define GPIO_CRL_CNF1_0 ((uint32_t)0x00000040) /*!< Bit 0 */
+#define GPIO_CRL_CNF1_1 ((uint32_t)0x00000080) /*!< Bit 1 */
+
+#define GPIO_CRL_CNF2 ((uint32_t)0x00000C00) /*!< CNF2[1:0] bits (Port x configuration bits, pin 2) */
+#define GPIO_CRL_CNF2_0 ((uint32_t)0x00000400) /*!< Bit 0 */
+#define GPIO_CRL_CNF2_1 ((uint32_t)0x00000800) /*!< Bit 1 */
+
+#define GPIO_CRL_CNF3 ((uint32_t)0x0000C000) /*!< CNF3[1:0] bits (Port x configuration bits, pin 3) */
+#define GPIO_CRL_CNF3_0 ((uint32_t)0x00004000) /*!< Bit 0 */
+#define GPIO_CRL_CNF3_1 ((uint32_t)0x00008000) /*!< Bit 1 */
+
+#define GPIO_CRL_CNF4 ((uint32_t)0x000C0000) /*!< CNF4[1:0] bits (Port x configuration bits, pin 4) */
+#define GPIO_CRL_CNF4_0 ((uint32_t)0x00040000) /*!< Bit 0 */
+#define GPIO_CRL_CNF4_1 ((uint32_t)0x00080000) /*!< Bit 1 */
+
+#define GPIO_CRL_CNF5 ((uint32_t)0x00C00000) /*!< CNF5[1:0] bits (Port x configuration bits, pin 5) */
+#define GPIO_CRL_CNF5_0 ((uint32_t)0x00400000) /*!< Bit 0 */
+#define GPIO_CRL_CNF5_1 ((uint32_t)0x00800000) /*!< Bit 1 */
+
+#define GPIO_CRL_CNF6 ((uint32_t)0x0C000000) /*!< CNF6[1:0] bits (Port x configuration bits, pin 6) */
+#define GPIO_CRL_CNF6_0 ((uint32_t)0x04000000) /*!< Bit 0 */
+#define GPIO_CRL_CNF6_1 ((uint32_t)0x08000000) /*!< Bit 1 */
+
+#define GPIO_CRL_CNF7 ((uint32_t)0xC0000000) /*!< CNF7[1:0] bits (Port x configuration bits, pin 7) */
+#define GPIO_CRL_CNF7_0 ((uint32_t)0x40000000) /*!< Bit 0 */
+#define GPIO_CRL_CNF7_1 ((uint32_t)0x80000000) /*!< Bit 1 */
+
+/******************* Bit definition for GPIO_CRH register *******************/
+#define GPIO_CRH_MODE ((uint32_t)0x33333333) /*!< Port x mode bits */
+
+#define GPIO_CRH_MODE8 ((uint32_t)0x00000003) /*!< MODE8[1:0] bits (Port x mode bits, pin 8) */
+#define GPIO_CRH_MODE8_0 ((uint32_t)0x00000001) /*!< Bit 0 */
+#define GPIO_CRH_MODE8_1 ((uint32_t)0x00000002) /*!< Bit 1 */
+
+#define GPIO_CRH_MODE9 ((uint32_t)0x00000030) /*!< MODE9[1:0] bits (Port x mode bits, pin 9) */
+#define GPIO_CRH_MODE9_0 ((uint32_t)0x00000010) /*!< Bit 0 */
+#define GPIO_CRH_MODE9_1 ((uint32_t)0x00000020) /*!< Bit 1 */
+
+#define GPIO_CRH_MODE10 ((uint32_t)0x00000300) /*!< MODE10[1:0] bits (Port x mode bits, pin 10) */
+#define GPIO_CRH_MODE10_0 ((uint32_t)0x00000100) /*!< Bit 0 */
+#define GPIO_CRH_MODE10_1 ((uint32_t)0x00000200) /*!< Bit 1 */
+
+#define GPIO_CRH_MODE11 ((uint32_t)0x00003000) /*!< MODE11[1:0] bits (Port x mode bits, pin 11) */
+#define GPIO_CRH_MODE11_0 ((uint32_t)0x00001000) /*!< Bit 0 */
+#define GPIO_CRH_MODE11_1 ((uint32_t)0x00002000) /*!< Bit 1 */
+
+#define GPIO_CRH_MODE12 ((uint32_t)0x00030000) /*!< MODE12[1:0] bits (Port x mode bits, pin 12) */
+#define GPIO_CRH_MODE12_0 ((uint32_t)0x00010000) /*!< Bit 0 */
+#define GPIO_CRH_MODE12_1 ((uint32_t)0x00020000) /*!< Bit 1 */
+
+#define GPIO_CRH_MODE13 ((uint32_t)0x00300000) /*!< MODE13[1:0] bits (Port x mode bits, pin 13) */
+#define GPIO_CRH_MODE13_0 ((uint32_t)0x00100000) /*!< Bit 0 */
+#define GPIO_CRH_MODE13_1 ((uint32_t)0x00200000) /*!< Bit 1 */
+
+#define GPIO_CRH_MODE14 ((uint32_t)0x03000000) /*!< MODE14[1:0] bits (Port x mode bits, pin 14) */
+#define GPIO_CRH_MODE14_0 ((uint32_t)0x01000000) /*!< Bit 0 */
+#define GPIO_CRH_MODE14_1 ((uint32_t)0x02000000) /*!< Bit 1 */
+
+#define GPIO_CRH_MODE15 ((uint32_t)0x30000000) /*!< MODE15[1:0] bits (Port x mode bits, pin 15) */
+#define GPIO_CRH_MODE15_0 ((uint32_t)0x10000000) /*!< Bit 0 */
+#define GPIO_CRH_MODE15_1 ((uint32_t)0x20000000) /*!< Bit 1 */
+
+#define GPIO_CRH_CNF ((uint32_t)0xCCCCCCCC) /*!< Port x configuration bits */
+
+#define GPIO_CRH_CNF8 ((uint32_t)0x0000000C) /*!< CNF8[1:0] bits (Port x configuration bits, pin 8) */
+#define GPIO_CRH_CNF8_0 ((uint32_t)0x00000004) /*!< Bit 0 */
+#define GPIO_CRH_CNF8_1 ((uint32_t)0x00000008) /*!< Bit 1 */
+
+#define GPIO_CRH_CNF9 ((uint32_t)0x000000C0) /*!< CNF9[1:0] bits (Port x configuration bits, pin 9) */
+#define GPIO_CRH_CNF9_0 ((uint32_t)0x00000040) /*!< Bit 0 */
+#define GPIO_CRH_CNF9_1 ((uint32_t)0x00000080) /*!< Bit 1 */
+
+#define GPIO_CRH_CNF10 ((uint32_t)0x00000C00) /*!< CNF10[1:0] bits (Port x configuration bits, pin 10) */
+#define GPIO_CRH_CNF10_0 ((uint32_t)0x00000400) /*!< Bit 0 */
+#define GPIO_CRH_CNF10_1 ((uint32_t)0x00000800) /*!< Bit 1 */
+
+#define GPIO_CRH_CNF11 ((uint32_t)0x0000C000) /*!< CNF11[1:0] bits (Port x configuration bits, pin 11) */
+#define GPIO_CRH_CNF11_0 ((uint32_t)0x00004000) /*!< Bit 0 */
+#define GPIO_CRH_CNF11_1 ((uint32_t)0x00008000) /*!< Bit 1 */
+
+#define GPIO_CRH_CNF12 ((uint32_t)0x000C0000) /*!< CNF12[1:0] bits (Port x configuration bits, pin 12) */
+#define GPIO_CRH_CNF12_0 ((uint32_t)0x00040000) /*!< Bit 0 */
+#define GPIO_CRH_CNF12_1 ((uint32_t)0x00080000) /*!< Bit 1 */
+
+#define GPIO_CRH_CNF13 ((uint32_t)0x00C00000) /*!< CNF13[1:0] bits (Port x configuration bits, pin 13) */
+#define GPIO_CRH_CNF13_0 ((uint32_t)0x00400000) /*!< Bit 0 */
+#define GPIO_CRH_CNF13_1 ((uint32_t)0x00800000) /*!< Bit 1 */
+
+#define GPIO_CRH_CNF14 ((uint32_t)0x0C000000) /*!< CNF14[1:0] bits (Port x configuration bits, pin 14) */
+#define GPIO_CRH_CNF14_0 ((uint32_t)0x04000000) /*!< Bit 0 */
+#define GPIO_CRH_CNF14_1 ((uint32_t)0x08000000) /*!< Bit 1 */
+
+#define GPIO_CRH_CNF15 ((uint32_t)0xC0000000) /*!< CNF15[1:0] bits (Port x configuration bits, pin 15) */
+#define GPIO_CRH_CNF15_0 ((uint32_t)0x40000000) /*!< Bit 0 */
+#define GPIO_CRH_CNF15_1 ((uint32_t)0x80000000) /*!< Bit 1 */
+
+/*!<****************** Bit definition for GPIO_IDR register *******************/
+#define GPIO_IDR_IDR0 ((uint16_t)0x0001) /*!< Port input data, bit 0 */
+#define GPIO_IDR_IDR1 ((uint16_t)0x0002) /*!< Port input data, bit 1 */
+#define GPIO_IDR_IDR2 ((uint16_t)0x0004) /*!< Port input data, bit 2 */
+#define GPIO_IDR_IDR3 ((uint16_t)0x0008) /*!< Port input data, bit 3 */
+#define GPIO_IDR_IDR4 ((uint16_t)0x0010) /*!< Port input data, bit 4 */
+#define GPIO_IDR_IDR5 ((uint16_t)0x0020) /*!< Port input data, bit 5 */
+#define GPIO_IDR_IDR6 ((uint16_t)0x0040) /*!< Port input data, bit 6 */
+#define GPIO_IDR_IDR7 ((uint16_t)0x0080) /*!< Port input data, bit 7 */
+#define GPIO_IDR_IDR8 ((uint16_t)0x0100) /*!< Port input data, bit 8 */
+#define GPIO_IDR_IDR9 ((uint16_t)0x0200) /*!< Port input data, bit 9 */
+#define GPIO_IDR_IDR10 ((uint16_t)0x0400) /*!< Port input data, bit 10 */
+#define GPIO_IDR_IDR11 ((uint16_t)0x0800) /*!< Port input data, bit 11 */
+#define GPIO_IDR_IDR12 ((uint16_t)0x1000) /*!< Port input data, bit 12 */
+#define GPIO_IDR_IDR13 ((uint16_t)0x2000) /*!< Port input data, bit 13 */
+#define GPIO_IDR_IDR14 ((uint16_t)0x4000) /*!< Port input data, bit 14 */
+#define GPIO_IDR_IDR15 ((uint16_t)0x8000) /*!< Port input data, bit 15 */
+
+/******************* Bit definition for GPIO_ODR register *******************/
+#define GPIO_ODR_ODR0 ((uint16_t)0x0001) /*!< Port output data, bit 0 */
+#define GPIO_ODR_ODR1 ((uint16_t)0x0002) /*!< Port output data, bit 1 */
+#define GPIO_ODR_ODR2 ((uint16_t)0x0004) /*!< Port output data, bit 2 */
+#define GPIO_ODR_ODR3 ((uint16_t)0x0008) /*!< Port output data, bit 3 */
+#define GPIO_ODR_ODR4 ((uint16_t)0x0010) /*!< Port output data, bit 4 */
+#define GPIO_ODR_ODR5 ((uint16_t)0x0020) /*!< Port output data, bit 5 */
+#define GPIO_ODR_ODR6 ((uint16_t)0x0040) /*!< Port output data, bit 6 */
+#define GPIO_ODR_ODR7 ((uint16_t)0x0080) /*!< Port output data, bit 7 */
+#define GPIO_ODR_ODR8 ((uint16_t)0x0100) /*!< Port output data, bit 8 */
+#define GPIO_ODR_ODR9 ((uint16_t)0x0200) /*!< Port output data, bit 9 */
+#define GPIO_ODR_ODR10 ((uint16_t)0x0400) /*!< Port output data, bit 10 */
+#define GPIO_ODR_ODR11 ((uint16_t)0x0800) /*!< Port output data, bit 11 */
+#define GPIO_ODR_ODR12 ((uint16_t)0x1000) /*!< Port output data, bit 12 */
+#define GPIO_ODR_ODR13 ((uint16_t)0x2000) /*!< Port output data, bit 13 */
+#define GPIO_ODR_ODR14 ((uint16_t)0x4000) /*!< Port output data, bit 14 */
+#define GPIO_ODR_ODR15 ((uint16_t)0x8000) /*!< Port output data, bit 15 */
+
+/****************** Bit definition for GPIO_BSRR register *******************/
+#define GPIO_BSRR_BS0 ((uint32_t)0x00000001) /*!< Port x Set bit 0 */
+#define GPIO_BSRR_BS1 ((uint32_t)0x00000002) /*!< Port x Set bit 1 */
+#define GPIO_BSRR_BS2 ((uint32_t)0x00000004) /*!< Port x Set bit 2 */
+#define GPIO_BSRR_BS3 ((uint32_t)0x00000008) /*!< Port x Set bit 3 */
+#define GPIO_BSRR_BS4 ((uint32_t)0x00000010) /*!< Port x Set bit 4 */
+#define GPIO_BSRR_BS5 ((uint32_t)0x00000020) /*!< Port x Set bit 5 */
+#define GPIO_BSRR_BS6 ((uint32_t)0x00000040) /*!< Port x Set bit 6 */
+#define GPIO_BSRR_BS7 ((uint32_t)0x00000080) /*!< Port x Set bit 7 */
+#define GPIO_BSRR_BS8 ((uint32_t)0x00000100) /*!< Port x Set bit 8 */
+#define GPIO_BSRR_BS9 ((uint32_t)0x00000200) /*!< Port x Set bit 9 */
+#define GPIO_BSRR_BS10 ((uint32_t)0x00000400) /*!< Port x Set bit 10 */
+#define GPIO_BSRR_BS11 ((uint32_t)0x00000800) /*!< Port x Set bit 11 */
+#define GPIO_BSRR_BS12 ((uint32_t)0x00001000) /*!< Port x Set bit 12 */
+#define GPIO_BSRR_BS13 ((uint32_t)0x00002000) /*!< Port x Set bit 13 */
+#define GPIO_BSRR_BS14 ((uint32_t)0x00004000) /*!< Port x Set bit 14 */
+#define GPIO_BSRR_BS15 ((uint32_t)0x00008000) /*!< Port x Set bit 15 */
+
+#define GPIO_BSRR_BR0 ((uint32_t)0x00010000) /*!< Port x Reset bit 0 */
+#define GPIO_BSRR_BR1 ((uint32_t)0x00020000) /*!< Port x Reset bit 1 */
+#define GPIO_BSRR_BR2 ((uint32_t)0x00040000) /*!< Port x Reset bit 2 */
+#define GPIO_BSRR_BR3 ((uint32_t)0x00080000) /*!< Port x Reset bit 3 */
+#define GPIO_BSRR_BR4 ((uint32_t)0x00100000) /*!< Port x Reset bit 4 */
+#define GPIO_BSRR_BR5 ((uint32_t)0x00200000) /*!< Port x Reset bit 5 */
+#define GPIO_BSRR_BR6 ((uint32_t)0x00400000) /*!< Port x Reset bit 6 */
+#define GPIO_BSRR_BR7 ((uint32_t)0x00800000) /*!< Port x Reset bit 7 */
+#define GPIO_BSRR_BR8 ((uint32_t)0x01000000) /*!< Port x Reset bit 8 */
+#define GPIO_BSRR_BR9 ((uint32_t)0x02000000) /*!< Port x Reset bit 9 */
+#define GPIO_BSRR_BR10 ((uint32_t)0x04000000) /*!< Port x Reset bit 10 */
+#define GPIO_BSRR_BR11 ((uint32_t)0x08000000) /*!< Port x Reset bit 11 */
+#define GPIO_BSRR_BR12 ((uint32_t)0x10000000) /*!< Port x Reset bit 12 */
+#define GPIO_BSRR_BR13 ((uint32_t)0x20000000) /*!< Port x Reset bit 13 */
+#define GPIO_BSRR_BR14 ((uint32_t)0x40000000) /*!< Port x Reset bit 14 */
+#define GPIO_BSRR_BR15 ((uint32_t)0x80000000) /*!< Port x Reset bit 15 */
+
+/******************* Bit definition for GPIO_BRR register *******************/
+#define GPIO_BRR_BR0 ((uint16_t)0x0001) /*!< Port x Reset bit 0 */
+#define GPIO_BRR_BR1 ((uint16_t)0x0002) /*!< Port x Reset bit 1 */
+#define GPIO_BRR_BR2 ((uint16_t)0x0004) /*!< Port x Reset bit 2 */
+#define GPIO_BRR_BR3 ((uint16_t)0x0008) /*!< Port x Reset bit 3 */
+#define GPIO_BRR_BR4 ((uint16_t)0x0010) /*!< Port x Reset bit 4 */
+#define GPIO_BRR_BR5 ((uint16_t)0x0020) /*!< Port x Reset bit 5 */
+#define GPIO_BRR_BR6 ((uint16_t)0x0040) /*!< Port x Reset bit 6 */
+#define GPIO_BRR_BR7 ((uint16_t)0x0080) /*!< Port x Reset bit 7 */
+#define GPIO_BRR_BR8 ((uint16_t)0x0100) /*!< Port x Reset bit 8 */
+#define GPIO_BRR_BR9 ((uint16_t)0x0200) /*!< Port x Reset bit 9 */
+#define GPIO_BRR_BR10 ((uint16_t)0x0400) /*!< Port x Reset bit 10 */
+#define GPIO_BRR_BR11 ((uint16_t)0x0800) /*!< Port x Reset bit 11 */
+#define GPIO_BRR_BR12 ((uint16_t)0x1000) /*!< Port x Reset bit 12 */
+#define GPIO_BRR_BR13 ((uint16_t)0x2000) /*!< Port x Reset bit 13 */
+#define GPIO_BRR_BR14 ((uint16_t)0x4000) /*!< Port x Reset bit 14 */
+#define GPIO_BRR_BR15 ((uint16_t)0x8000) /*!< Port x Reset bit 15 */
+
+/****************** Bit definition for GPIO_LCKR register *******************/
+#define GPIO_LCKR_LCK0 ((uint32_t)0x00000001) /*!< Port x Lock bit 0 */
+#define GPIO_LCKR_LCK1 ((uint32_t)0x00000002) /*!< Port x Lock bit 1 */
+#define GPIO_LCKR_LCK2 ((uint32_t)0x00000004) /*!< Port x Lock bit 2 */
+#define GPIO_LCKR_LCK3 ((uint32_t)0x00000008) /*!< Port x Lock bit 3 */
+#define GPIO_LCKR_LCK4 ((uint32_t)0x00000010) /*!< Port x Lock bit 4 */
+#define GPIO_LCKR_LCK5 ((uint32_t)0x00000020) /*!< Port x Lock bit 5 */
+#define GPIO_LCKR_LCK6 ((uint32_t)0x00000040) /*!< Port x Lock bit 6 */
+#define GPIO_LCKR_LCK7 ((uint32_t)0x00000080) /*!< Port x Lock bit 7 */
+#define GPIO_LCKR_LCK8 ((uint32_t)0x00000100) /*!< Port x Lock bit 8 */
+#define GPIO_LCKR_LCK9 ((uint32_t)0x00000200) /*!< Port x Lock bit 9 */
+#define GPIO_LCKR_LCK10 ((uint32_t)0x00000400) /*!< Port x Lock bit 10 */
+#define GPIO_LCKR_LCK11 ((uint32_t)0x00000800) /*!< Port x Lock bit 11 */
+#define GPIO_LCKR_LCK12 ((uint32_t)0x00001000) /*!< Port x Lock bit 12 */
+#define GPIO_LCKR_LCK13 ((uint32_t)0x00002000) /*!< Port x Lock bit 13 */
+#define GPIO_LCKR_LCK14 ((uint32_t)0x00004000) /*!< Port x Lock bit 14 */
+#define GPIO_LCKR_LCK15 ((uint32_t)0x00008000) /*!< Port x Lock bit 15 */
+#define GPIO_LCKR_LCKK ((uint32_t)0x00010000) /*!< Lock key */
+
+/*----------------------------------------------------------------------------*/
+
+/****************** Bit definition for AFIO_EVCR register *******************/
+#define AFIO_EVCR_PIN ((uint8_t)0x0F) /*!< PIN[3:0] bits (Pin selection) */
+#define AFIO_EVCR_PIN_0 ((uint8_t)0x01) /*!< Bit 0 */
+#define AFIO_EVCR_PIN_1 ((uint8_t)0x02) /*!< Bit 1 */
+#define AFIO_EVCR_PIN_2 ((uint8_t)0x04) /*!< Bit 2 */
+#define AFIO_EVCR_PIN_3 ((uint8_t)0x08) /*!< Bit 3 */
+
+/*!< PIN configuration */
+#define AFIO_EVCR_PIN_PX0 ((uint8_t)0x00) /*!< Pin 0 selected */
+#define AFIO_EVCR_PIN_PX1 ((uint8_t)0x01) /*!< Pin 1 selected */
+#define AFIO_EVCR_PIN_PX2 ((uint8_t)0x02) /*!< Pin 2 selected */
+#define AFIO_EVCR_PIN_PX3 ((uint8_t)0x03) /*!< Pin 3 selected */
+#define AFIO_EVCR_PIN_PX4 ((uint8_t)0x04) /*!< Pin 4 selected */
+#define AFIO_EVCR_PIN_PX5 ((uint8_t)0x05) /*!< Pin 5 selected */
+#define AFIO_EVCR_PIN_PX6 ((uint8_t)0x06) /*!< Pin 6 selected */
+#define AFIO_EVCR_PIN_PX7 ((uint8_t)0x07) /*!< Pin 7 selected */
+#define AFIO_EVCR_PIN_PX8 ((uint8_t)0x08) /*!< Pin 8 selected */
+#define AFIO_EVCR_PIN_PX9 ((uint8_t)0x09) /*!< Pin 9 selected */
+#define AFIO_EVCR_PIN_PX10 ((uint8_t)0x0A) /*!< Pin 10 selected */
+#define AFIO_EVCR_PIN_PX11 ((uint8_t)0x0B) /*!< Pin 11 selected */
+#define AFIO_EVCR_PIN_PX12 ((uint8_t)0x0C) /*!< Pin 12 selected */
+#define AFIO_EVCR_PIN_PX13 ((uint8_t)0x0D) /*!< Pin 13 selected */
+#define AFIO_EVCR_PIN_PX14 ((uint8_t)0x0E) /*!< Pin 14 selected */
+#define AFIO_EVCR_PIN_PX15 ((uint8_t)0x0F) /*!< Pin 15 selected */
+
+#define AFIO_EVCR_PORT ((uint8_t)0x70) /*!< PORT[2:0] bits (Port selection) */
+#define AFIO_EVCR_PORT_0 ((uint8_t)0x10) /*!< Bit 0 */
+#define AFIO_EVCR_PORT_1 ((uint8_t)0x20) /*!< Bit 1 */
+#define AFIO_EVCR_PORT_2 ((uint8_t)0x40) /*!< Bit 2 */
+
+/*!< PORT configuration */
+#define AFIO_EVCR_PORT_PA ((uint8_t)0x00) /*!< Port A selected */
+#define AFIO_EVCR_PORT_PB ((uint8_t)0x10) /*!< Port B selected */
+#define AFIO_EVCR_PORT_PC ((uint8_t)0x20) /*!< Port C selected */
+#define AFIO_EVCR_PORT_PD ((uint8_t)0x30) /*!< Port D selected */
+#define AFIO_EVCR_PORT_PE ((uint8_t)0x40) /*!< Port E selected */
+
+#define AFIO_EVCR_EVOE ((uint8_t)0x80) /*!< Event Output Enable */
+
+/****************** Bit definition for AFIO_MAPR register *******************/
+#define AFIO_MAPR_SPI1_REMAP ((uint32_t)0x00000001) /*!< SPI1 remapping */
+#define AFIO_MAPR_I2C1_REMAP ((uint32_t)0x00000002) /*!< I2C1 remapping */
+#define AFIO_MAPR_USART1_REMAP ((uint32_t)0x00000004) /*!< USART1 remapping */
+#define AFIO_MAPR_USART2_REMAP ((uint32_t)0x00000008) /*!< USART2 remapping */
+
+#define AFIO_MAPR_USART3_REMAP ((uint32_t)0x00000030) /*!< USART3_REMAP[1:0] bits (USART3 remapping) */
+#define AFIO_MAPR_USART3_REMAP_0 ((uint32_t)0x00000010) /*!< Bit 0 */
+#define AFIO_MAPR_USART3_REMAP_1 ((uint32_t)0x00000020) /*!< Bit 1 */
+
+/* USART3_REMAP configuration */
+#define AFIO_MAPR_USART3_REMAP_NOREMAP ((uint32_t)0x00000000) /*!< No remap (TX/PB10, RX/PB11, CK/PB12, CTS/PB13, RTS/PB14) */
+#define AFIO_MAPR_USART3_REMAP_PARTIALREMAP ((uint32_t)0x00000010) /*!< Partial remap (TX/PC10, RX/PC11, CK/PC12, CTS/PB13, RTS/PB14) */
+#define AFIO_MAPR_USART3_REMAP_FULLREMAP ((uint32_t)0x00000030) /*!< Full remap (TX/PD8, RX/PD9, CK/PD10, CTS/PD11, RTS/PD12) */
+
+#define AFIO_MAPR_TIM1_REMAP ((uint32_t)0x000000C0) /*!< TIM1_REMAP[1:0] bits (TIM1 remapping) */
+#define AFIO_MAPR_TIM1_REMAP_0 ((uint32_t)0x00000040) /*!< Bit 0 */
+#define AFIO_MAPR_TIM1_REMAP_1 ((uint32_t)0x00000080) /*!< Bit 1 */
+
+/*!< TIM1_REMAP configuration */
+#define AFIO_MAPR_TIM1_REMAP_NOREMAP ((uint32_t)0x00000000) /*!< No remap (ETR/PA12, CH1/PA8, CH2/PA9, CH3/PA10, CH4/PA11, BKIN/PB12, CH1N/PB13, CH2N/PB14, CH3N/PB15) */
+#define AFIO_MAPR_TIM1_REMAP_PARTIALREMAP ((uint32_t)0x00000040) /*!< Partial remap (ETR/PA12, CH1/PA8, CH2/PA9, CH3/PA10, CH4/PA11, BKIN/PA6, CH1N/PA7, CH2N/PB0, CH3N/PB1) */
+#define AFIO_MAPR_TIM1_REMAP_FULLREMAP ((uint32_t)0x000000C0) /*!< Full remap (ETR/PE7, CH1/PE9, CH2/PE11, CH3/PE13, CH4/PE14, BKIN/PE15, CH1N/PE8, CH2N/PE10, CH3N/PE12) */
+
+#define AFIO_MAPR_TIM2_REMAP ((uint32_t)0x00000300) /*!< TIM2_REMAP[1:0] bits (TIM2 remapping) */
+#define AFIO_MAPR_TIM2_REMAP_0 ((uint32_t)0x00000100) /*!< Bit 0 */
+#define AFIO_MAPR_TIM2_REMAP_1 ((uint32_t)0x00000200) /*!< Bit 1 */
+
+/*!< TIM2_REMAP configuration */
+#define AFIO_MAPR_TIM2_REMAP_NOREMAP ((uint32_t)0x00000000) /*!< No remap (CH1/ETR/PA0, CH2/PA1, CH3/PA2, CH4/PA3) */
+#define AFIO_MAPR_TIM2_REMAP_PARTIALREMAP1 ((uint32_t)0x00000100) /*!< Partial remap (CH1/ETR/PA15, CH2/PB3, CH3/PA2, CH4/PA3) */
+#define AFIO_MAPR_TIM2_REMAP_PARTIALREMAP2 ((uint32_t)0x00000200) /*!< Partial remap (CH1/ETR/PA0, CH2/PA1, CH3/PB10, CH4/PB11) */
+#define AFIO_MAPR_TIM2_REMAP_FULLREMAP ((uint32_t)0x00000300) /*!< Full remap (CH1/ETR/PA15, CH2/PB3, CH3/PB10, CH4/PB11) */
+
+#define AFIO_MAPR_TIM3_REMAP ((uint32_t)0x00000C00) /*!< TIM3_REMAP[1:0] bits (TIM3 remapping) */
+#define AFIO_MAPR_TIM3_REMAP_0 ((uint32_t)0x00000400) /*!< Bit 0 */
+#define AFIO_MAPR_TIM3_REMAP_1 ((uint32_t)0x00000800) /*!< Bit 1 */
+
+/*!< TIM3_REMAP configuration */
+#define AFIO_MAPR_TIM3_REMAP_NOREMAP ((uint32_t)0x00000000) /*!< No remap (CH1/PA6, CH2/PA7, CH3/PB0, CH4/PB1) */
+#define AFIO_MAPR_TIM3_REMAP_PARTIALREMAP ((uint32_t)0x00000800) /*!< Partial remap (CH1/PB4, CH2/PB5, CH3/PB0, CH4/PB1) */
+#define AFIO_MAPR_TIM3_REMAP_FULLREMAP ((uint32_t)0x00000C00) /*!< Full remap (CH1/PC6, CH2/PC7, CH3/PC8, CH4/PC9) */
+
+#define AFIO_MAPR_TIM4_REMAP ((uint32_t)0x00001000) /*!< TIM4_REMAP bit (TIM4 remapping) */
+
+#define AFIO_MAPR_CAN_REMAP ((uint32_t)0x00006000) /*!< CAN_REMAP[1:0] bits (CAN Alternate function remapping) */
+#define AFIO_MAPR_CAN_REMAP_0 ((uint32_t)0x00002000) /*!< Bit 0 */
+#define AFIO_MAPR_CAN_REMAP_1 ((uint32_t)0x00004000) /*!< Bit 1 */
+
+/*!< CAN_REMAP configuration */
+#define AFIO_MAPR_CAN_REMAP_REMAP1 ((uint32_t)0x00000000) /*!< CANRX mapped to PA11, CANTX mapped to PA12 */
+#define AFIO_MAPR_CAN_REMAP_REMAP2 ((uint32_t)0x00004000) /*!< CANRX mapped to PB8, CANTX mapped to PB9 */
+#define AFIO_MAPR_CAN_REMAP_REMAP3 ((uint32_t)0x00006000) /*!< CANRX mapped to PD0, CANTX mapped to PD1 */
+
+#define AFIO_MAPR_PD01_REMAP ((uint32_t)0x00008000) /*!< Port D0/Port D1 mapping on OSC_IN/OSC_OUT */
+#define AFIO_MAPR_TIM5CH4_IREMAP ((uint32_t)0x00010000) /*!< TIM5 Channel4 Internal Remap */
+#define AFIO_MAPR_ADC1_ETRGINJ_REMAP ((uint32_t)0x00020000) /*!< ADC 1 External Trigger Injected Conversion remapping */
+#define AFIO_MAPR_ADC1_ETRGREG_REMAP ((uint32_t)0x00040000) /*!< ADC 1 External Trigger Regular Conversion remapping */
+#define AFIO_MAPR_ADC2_ETRGINJ_REMAP ((uint32_t)0x00080000) /*!< ADC 2 External Trigger Injected Conversion remapping */
+#define AFIO_MAPR_ADC2_ETRGREG_REMAP ((uint32_t)0x00100000) /*!< ADC 2 External Trigger Regular Conversion remapping */
+
+/*!< SWJ_CFG configuration */
+#define AFIO_MAPR_SWJ_CFG ((uint32_t)0x07000000) /*!< SWJ_CFG[2:0] bits (Serial Wire JTAG configuration) */
+#define AFIO_MAPR_SWJ_CFG_0 ((uint32_t)0x01000000) /*!< Bit 0 */
+#define AFIO_MAPR_SWJ_CFG_1 ((uint32_t)0x02000000) /*!< Bit 1 */
+#define AFIO_MAPR_SWJ_CFG_2 ((uint32_t)0x04000000) /*!< Bit 2 */
+
+#define AFIO_MAPR_SWJ_CFG_RESET ((uint32_t)0x00000000) /*!< Full SWJ (JTAG-DP + SW-DP) : Reset State */
+#define AFIO_MAPR_SWJ_CFG_NOJNTRST ((uint32_t)0x01000000) /*!< Full SWJ (JTAG-DP + SW-DP) but without JNTRST */
+#define AFIO_MAPR_SWJ_CFG_JTAGDISABLE ((uint32_t)0x02000000) /*!< JTAG-DP Disabled and SW-DP Enabled */
+#define AFIO_MAPR_SWJ_CFG_DISABLE ((uint32_t)0x04000000) /*!< JTAG-DP Disabled and SW-DP Disabled */
+
+#ifdef STM32F10X_CL
+/*!< ETH_REMAP configuration */
+ #define AFIO_MAPR_ETH_REMAP ((uint32_t)0x00200000) /*!< SPI3_REMAP bit (Ethernet MAC I/O remapping) */
+
+/*!< CAN2_REMAP configuration */
+ #define AFIO_MAPR_CAN2_REMAP ((uint32_t)0x00400000) /*!< CAN2_REMAP bit (CAN2 I/O remapping) */
+
+/*!< MII_RMII_SEL configuration */
+ #define AFIO_MAPR_MII_RMII_SEL ((uint32_t)0x00800000) /*!< MII_RMII_SEL bit (Ethernet MII or RMII selection) */
+
+/*!< SPI3_REMAP configuration */
+ #define AFIO_MAPR_SPI3_REMAP ((uint32_t)0x10000000) /*!< SPI3_REMAP bit (SPI3 remapping) */
+
+/*!< TIM2ITR1_IREMAP configuration */
+ #define AFIO_MAPR_TIM2ITR1_IREMAP ((uint32_t)0x20000000) /*!< TIM2ITR1_IREMAP bit (TIM2 internal trigger 1 remapping) */
+
+/*!< PTP_PPS_REMAP configuration */
+ #define AFIO_MAPR_PTP_PPS_REMAP ((uint32_t)0x20000000) /*!< PTP_PPS_REMAP bit (Ethernet PTP PPS remapping) */
+#endif
+
+/***************** Bit definition for AFIO_EXTICR1 register *****************/
+#define AFIO_EXTICR1_EXTI0 ((uint16_t)0x000F) /*!< EXTI 0 configuration */
+#define AFIO_EXTICR1_EXTI1 ((uint16_t)0x00F0) /*!< EXTI 1 configuration */
+#define AFIO_EXTICR1_EXTI2 ((uint16_t)0x0F00) /*!< EXTI 2 configuration */
+#define AFIO_EXTICR1_EXTI3 ((uint16_t)0xF000) /*!< EXTI 3 configuration */
+
+/*!< EXTI0 configuration */
+#define AFIO_EXTICR1_EXTI0_PA ((uint16_t)0x0000) /*!< PA[0] pin */
+#define AFIO_EXTICR1_EXTI0_PB ((uint16_t)0x0001) /*!< PB[0] pin */
+#define AFIO_EXTICR1_EXTI0_PC ((uint16_t)0x0002) /*!< PC[0] pin */
+#define AFIO_EXTICR1_EXTI0_PD ((uint16_t)0x0003) /*!< PD[0] pin */
+#define AFIO_EXTICR1_EXTI0_PE ((uint16_t)0x0004) /*!< PE[0] pin */
+#define AFIO_EXTICR1_EXTI0_PF ((uint16_t)0x0005) /*!< PF[0] pin */
+#define AFIO_EXTICR1_EXTI0_PG ((uint16_t)0x0006) /*!< PG[0] pin */
+
+/*!< EXTI1 configuration */
+#define AFIO_EXTICR1_EXTI1_PA ((uint16_t)0x0000) /*!< PA[1] pin */
+#define AFIO_EXTICR1_EXTI1_PB ((uint16_t)0x0010) /*!< PB[1] pin */
+#define AFIO_EXTICR1_EXTI1_PC ((uint16_t)0x0020) /*!< PC[1] pin */
+#define AFIO_EXTICR1_EXTI1_PD ((uint16_t)0x0030) /*!< PD[1] pin */
+#define AFIO_EXTICR1_EXTI1_PE ((uint16_t)0x0040) /*!< PE[1] pin */
+#define AFIO_EXTICR1_EXTI1_PF ((uint16_t)0x0050) /*!< PF[1] pin */
+#define AFIO_EXTICR1_EXTI1_PG ((uint16_t)0x0060) /*!< PG[1] pin */
+
+/*!< EXTI2 configuration */
+#define AFIO_EXTICR1_EXTI2_PA ((uint16_t)0x0000) /*!< PA[2] pin */
+#define AFIO_EXTICR1_EXTI2_PB ((uint16_t)0x0100) /*!< PB[2] pin */
+#define AFIO_EXTICR1_EXTI2_PC ((uint16_t)0x0200) /*!< PC[2] pin */
+#define AFIO_EXTICR1_EXTI2_PD ((uint16_t)0x0300) /*!< PD[2] pin */
+#define AFIO_EXTICR1_EXTI2_PE ((uint16_t)0x0400) /*!< PE[2] pin */
+#define AFIO_EXTICR1_EXTI2_PF ((uint16_t)0x0500) /*!< PF[2] pin */
+#define AFIO_EXTICR1_EXTI2_PG ((uint16_t)0x0600) /*!< PG[2] pin */
+
+/*!< EXTI3 configuration */
+#define AFIO_EXTICR1_EXTI3_PA ((uint16_t)0x0000) /*!< PA[3] pin */
+#define AFIO_EXTICR1_EXTI3_PB ((uint16_t)0x1000) /*!< PB[3] pin */
+#define AFIO_EXTICR1_EXTI3_PC ((uint16_t)0x2000) /*!< PC[3] pin */
+#define AFIO_EXTICR1_EXTI3_PD ((uint16_t)0x3000) /*!< PD[3] pin */
+#define AFIO_EXTICR1_EXTI3_PE ((uint16_t)0x4000) /*!< PE[3] pin */
+#define AFIO_EXTICR1_EXTI3_PF ((uint16_t)0x5000) /*!< PF[3] pin */
+#define AFIO_EXTICR1_EXTI3_PG ((uint16_t)0x6000) /*!< PG[3] pin */
+
+/***************** Bit definition for AFIO_EXTICR2 register *****************/
+#define AFIO_EXTICR2_EXTI4 ((uint16_t)0x000F) /*!< EXTI 4 configuration */
+#define AFIO_EXTICR2_EXTI5 ((uint16_t)0x00F0) /*!< EXTI 5 configuration */
+#define AFIO_EXTICR2_EXTI6 ((uint16_t)0x0F00) /*!< EXTI 6 configuration */
+#define AFIO_EXTICR2_EXTI7 ((uint16_t)0xF000) /*!< EXTI 7 configuration */
+
+/*!< EXTI4 configuration */
+#define AFIO_EXTICR2_EXTI4_PA ((uint16_t)0x0000) /*!< PA[4] pin */
+#define AFIO_EXTICR2_EXTI4_PB ((uint16_t)0x0001) /*!< PB[4] pin */
+#define AFIO_EXTICR2_EXTI4_PC ((uint16_t)0x0002) /*!< PC[4] pin */
+#define AFIO_EXTICR2_EXTI4_PD ((uint16_t)0x0003) /*!< PD[4] pin */
+#define AFIO_EXTICR2_EXTI4_PE ((uint16_t)0x0004) /*!< PE[4] pin */
+#define AFIO_EXTICR2_EXTI4_PF ((uint16_t)0x0005) /*!< PF[4] pin */
+#define AFIO_EXTICR2_EXTI4_PG ((uint16_t)0x0006) /*!< PG[4] pin */
+
+/* EXTI5 configuration */
+#define AFIO_EXTICR2_EXTI5_PA ((uint16_t)0x0000) /*!< PA[5] pin */
+#define AFIO_EXTICR2_EXTI5_PB ((uint16_t)0x0010) /*!< PB[5] pin */
+#define AFIO_EXTICR2_EXTI5_PC ((uint16_t)0x0020) /*!< PC[5] pin */
+#define AFIO_EXTICR2_EXTI5_PD ((uint16_t)0x0030) /*!< PD[5] pin */
+#define AFIO_EXTICR2_EXTI5_PE ((uint16_t)0x0040) /*!< PE[5] pin */
+#define AFIO_EXTICR2_EXTI5_PF ((uint16_t)0x0050) /*!< PF[5] pin */
+#define AFIO_EXTICR2_EXTI5_PG ((uint16_t)0x0060) /*!< PG[5] pin */
+
+/*!< EXTI6 configuration */
+#define AFIO_EXTICR2_EXTI6_PA ((uint16_t)0x0000) /*!< PA[6] pin */
+#define AFIO_EXTICR2_EXTI6_PB ((uint16_t)0x0100) /*!< PB[6] pin */
+#define AFIO_EXTICR2_EXTI6_PC ((uint16_t)0x0200) /*!< PC[6] pin */
+#define AFIO_EXTICR2_EXTI6_PD ((uint16_t)0x0300) /*!< PD[6] pin */
+#define AFIO_EXTICR2_EXTI6_PE ((uint16_t)0x0400) /*!< PE[6] pin */
+#define AFIO_EXTICR2_EXTI6_PF ((uint16_t)0x0500) /*!< PF[6] pin */
+#define AFIO_EXTICR2_EXTI6_PG ((uint16_t)0x0600) /*!< PG[6] pin */
+
+/*!< EXTI7 configuration */
+#define AFIO_EXTICR2_EXTI7_PA ((uint16_t)0x0000) /*!< PA[7] pin */
+#define AFIO_EXTICR2_EXTI7_PB ((uint16_t)0x1000) /*!< PB[7] pin */
+#define AFIO_EXTICR2_EXTI7_PC ((uint16_t)0x2000) /*!< PC[7] pin */
+#define AFIO_EXTICR2_EXTI7_PD ((uint16_t)0x3000) /*!< PD[7] pin */
+#define AFIO_EXTICR2_EXTI7_PE ((uint16_t)0x4000) /*!< PE[7] pin */
+#define AFIO_EXTICR2_EXTI7_PF ((uint16_t)0x5000) /*!< PF[7] pin */
+#define AFIO_EXTICR2_EXTI7_PG ((uint16_t)0x6000) /*!< PG[7] pin */
+
+/***************** Bit definition for AFIO_EXTICR3 register *****************/
+#define AFIO_EXTICR3_EXTI8 ((uint16_t)0x000F) /*!< EXTI 8 configuration */
+#define AFIO_EXTICR3_EXTI9 ((uint16_t)0x00F0) /*!< EXTI 9 configuration */
+#define AFIO_EXTICR3_EXTI10 ((uint16_t)0x0F00) /*!< EXTI 10 configuration */
+#define AFIO_EXTICR3_EXTI11 ((uint16_t)0xF000) /*!< EXTI 11 configuration */
+
+/*!< EXTI8 configuration */
+#define AFIO_EXTICR3_EXTI8_PA ((uint16_t)0x0000) /*!< PA[8] pin */
+#define AFIO_EXTICR3_EXTI8_PB ((uint16_t)0x0001) /*!< PB[8] pin */
+#define AFIO_EXTICR3_EXTI8_PC ((uint16_t)0x0002) /*!< PC[8] pin */
+#define AFIO_EXTICR3_EXTI8_PD ((uint16_t)0x0003) /*!< PD[8] pin */
+#define AFIO_EXTICR3_EXTI8_PE ((uint16_t)0x0004) /*!< PE[8] pin */
+#define AFIO_EXTICR3_EXTI8_PF ((uint16_t)0x0005) /*!< PF[8] pin */
+#define AFIO_EXTICR3_EXTI8_PG ((uint16_t)0x0006) /*!< PG[8] pin */
+
+/*!< EXTI9 configuration */
+#define AFIO_EXTICR3_EXTI9_PA ((uint16_t)0x0000) /*!< PA[9] pin */
+#define AFIO_EXTICR3_EXTI9_PB ((uint16_t)0x0010) /*!< PB[9] pin */
+#define AFIO_EXTICR3_EXTI9_PC ((uint16_t)0x0020) /*!< PC[9] pin */
+#define AFIO_EXTICR3_EXTI9_PD ((uint16_t)0x0030) /*!< PD[9] pin */
+#define AFIO_EXTICR3_EXTI9_PE ((uint16_t)0x0040) /*!< PE[9] pin */
+#define AFIO_EXTICR3_EXTI9_PF ((uint16_t)0x0050) /*!< PF[9] pin */
+#define AFIO_EXTICR3_EXTI9_PG ((uint16_t)0x0060) /*!< PG[9] pin */
+
+/*!< EXTI10 configuration */
+#define AFIO_EXTICR3_EXTI10_PA ((uint16_t)0x0000) /*!< PA[10] pin */
+#define AFIO_EXTICR3_EXTI10_PB ((uint16_t)0x0100) /*!< PB[10] pin */
+#define AFIO_EXTICR3_EXTI10_PC ((uint16_t)0x0200) /*!< PC[10] pin */
+#define AFIO_EXTICR3_EXTI10_PD ((uint16_t)0x0300) /*!< PD[10] pin */
+#define AFIO_EXTICR3_EXTI10_PE ((uint16_t)0x0400) /*!< PE[10] pin */
+#define AFIO_EXTICR3_EXTI10_PF ((uint16_t)0x0500) /*!< PF[10] pin */
+#define AFIO_EXTICR3_EXTI10_PG ((uint16_t)0x0600) /*!< PG[10] pin */
+
+/*!< EXTI11 configuration */
+#define AFIO_EXTICR3_EXTI11_PA ((uint16_t)0x0000) /*!< PA[11] pin */
+#define AFIO_EXTICR3_EXTI11_PB ((uint16_t)0x1000) /*!< PB[11] pin */
+#define AFIO_EXTICR3_EXTI11_PC ((uint16_t)0x2000) /*!< PC[11] pin */
+#define AFIO_EXTICR3_EXTI11_PD ((uint16_t)0x3000) /*!< PD[11] pin */
+#define AFIO_EXTICR3_EXTI11_PE ((uint16_t)0x4000) /*!< PE[11] pin */
+#define AFIO_EXTICR3_EXTI11_PF ((uint16_t)0x5000) /*!< PF[11] pin */
+#define AFIO_EXTICR3_EXTI11_PG ((uint16_t)0x6000) /*!< PG[11] pin */
+
+/***************** Bit definition for AFIO_EXTICR4 register *****************/
+#define AFIO_EXTICR4_EXTI12 ((uint16_t)0x000F) /*!< EXTI 12 configuration */
+#define AFIO_EXTICR4_EXTI13 ((uint16_t)0x00F0) /*!< EXTI 13 configuration */
+#define AFIO_EXTICR4_EXTI14 ((uint16_t)0x0F00) /*!< EXTI 14 configuration */
+#define AFIO_EXTICR4_EXTI15 ((uint16_t)0xF000) /*!< EXTI 15 configuration */
+
+/* EXTI12 configuration */
+#define AFIO_EXTICR4_EXTI12_PA ((uint16_t)0x0000) /*!< PA[12] pin */
+#define AFIO_EXTICR4_EXTI12_PB ((uint16_t)0x0001) /*!< PB[12] pin */
+#define AFIO_EXTICR4_EXTI12_PC ((uint16_t)0x0002) /*!< PC[12] pin */
+#define AFIO_EXTICR4_EXTI12_PD ((uint16_t)0x0003) /*!< PD[12] pin */
+#define AFIO_EXTICR4_EXTI12_PE ((uint16_t)0x0004) /*!< PE[12] pin */
+#define AFIO_EXTICR4_EXTI12_PF ((uint16_t)0x0005) /*!< PF[12] pin */
+#define AFIO_EXTICR4_EXTI12_PG ((uint16_t)0x0006) /*!< PG[12] pin */
+
+/* EXTI13 configuration */
+#define AFIO_EXTICR4_EXTI13_PA ((uint16_t)0x0000) /*!< PA[13] pin */
+#define AFIO_EXTICR4_EXTI13_PB ((uint16_t)0x0010) /*!< PB[13] pin */
+#define AFIO_EXTICR4_EXTI13_PC ((uint16_t)0x0020) /*!< PC[13] pin */
+#define AFIO_EXTICR4_EXTI13_PD ((uint16_t)0x0030) /*!< PD[13] pin */
+#define AFIO_EXTICR4_EXTI13_PE ((uint16_t)0x0040) /*!< PE[13] pin */
+#define AFIO_EXTICR4_EXTI13_PF ((uint16_t)0x0050) /*!< PF[13] pin */
+#define AFIO_EXTICR4_EXTI13_PG ((uint16_t)0x0060) /*!< PG[13] pin */
+
+/*!< EXTI14 configuration */
+#define AFIO_EXTICR4_EXTI14_PA ((uint16_t)0x0000) /*!< PA[14] pin */
+#define AFIO_EXTICR4_EXTI14_PB ((uint16_t)0x0100) /*!< PB[14] pin */
+#define AFIO_EXTICR4_EXTI14_PC ((uint16_t)0x0200) /*!< PC[14] pin */
+#define AFIO_EXTICR4_EXTI14_PD ((uint16_t)0x0300) /*!< PD[14] pin */
+#define AFIO_EXTICR4_EXTI14_PE ((uint16_t)0x0400) /*!< PE[14] pin */
+#define AFIO_EXTICR4_EXTI14_PF ((uint16_t)0x0500) /*!< PF[14] pin */
+#define AFIO_EXTICR4_EXTI14_PG ((uint16_t)0x0600) /*!< PG[14] pin */
+
+/*!< EXTI15 configuration */
+#define AFIO_EXTICR4_EXTI15_PA ((uint16_t)0x0000) /*!< PA[15] pin */
+#define AFIO_EXTICR4_EXTI15_PB ((uint16_t)0x1000) /*!< PB[15] pin */
+#define AFIO_EXTICR4_EXTI15_PC ((uint16_t)0x2000) /*!< PC[15] pin */
+#define AFIO_EXTICR4_EXTI15_PD ((uint16_t)0x3000) /*!< PD[15] pin */
+#define AFIO_EXTICR4_EXTI15_PE ((uint16_t)0x4000) /*!< PE[15] pin */
+#define AFIO_EXTICR4_EXTI15_PF ((uint16_t)0x5000) /*!< PF[15] pin */
+#define AFIO_EXTICR4_EXTI15_PG ((uint16_t)0x6000) /*!< PG[15] pin */
+
+/******************************************************************************/
+/* */
+/* SystemTick */
+/* */
+/******************************************************************************/
+
+/***************** Bit definition for SysTick_CTRL register *****************/
+#define SysTick_CTRL_ENABLE ((uint32_t)0x00000001) /*!< Counter enable */
+#define SysTick_CTRL_TICKINT ((uint32_t)0x00000002) /*!< Counting down to 0 pends the SysTick handler */
+#define SysTick_CTRL_CLKSOURCE ((uint32_t)0x00000004) /*!< Clock source */
+#define SysTick_CTRL_COUNTFLAG ((uint32_t)0x00010000) /*!< Count Flag */
+
+/***************** Bit definition for SysTick_LOAD register *****************/
+#define SysTick_LOAD_RELOAD ((uint32_t)0x00FFFFFF) /*!< Value to load into the SysTick Current Value Register when the counter reaches 0 */
+
+/***************** Bit definition for SysTick_VAL register ******************/
+#define SysTick_VAL_CURRENT ((uint32_t)0x00FFFFFF) /*!< Current value at the time the register is accessed */
+
+/***************** Bit definition for SysTick_CALIB register ****************/
+#define SysTick_CALIB_TENMS ((uint32_t)0x00FFFFFF) /*!< Reload value to use for 10ms timing */
+#define SysTick_CALIB_SKEW ((uint32_t)0x40000000) /*!< Calibration value is not exactly 10 ms */
+#define SysTick_CALIB_NOREF ((uint32_t)0x80000000) /*!< The reference clock is not provided */
+
+/******************************************************************************/
+/* */
+/* Nested Vectored Interrupt Controller */
+/* */
+/******************************************************************************/
+
+/****************** Bit definition for NVIC_ISER register *******************/
+#define NVIC_ISER_SETENA ((uint32_t)0xFFFFFFFF) /*!< Interrupt set enable bits */
+#define NVIC_ISER_SETENA_0 ((uint32_t)0x00000001) /*!< bit 0 */
+#define NVIC_ISER_SETENA_1 ((uint32_t)0x00000002) /*!< bit 1 */
+#define NVIC_ISER_SETENA_2 ((uint32_t)0x00000004) /*!< bit 2 */
+#define NVIC_ISER_SETENA_3 ((uint32_t)0x00000008) /*!< bit 3 */
+#define NVIC_ISER_SETENA_4 ((uint32_t)0x00000010) /*!< bit 4 */
+#define NVIC_ISER_SETENA_5 ((uint32_t)0x00000020) /*!< bit 5 */
+#define NVIC_ISER_SETENA_6 ((uint32_t)0x00000040) /*!< bit 6 */
+#define NVIC_ISER_SETENA_7 ((uint32_t)0x00000080) /*!< bit 7 */
+#define NVIC_ISER_SETENA_8 ((uint32_t)0x00000100) /*!< bit 8 */
+#define NVIC_ISER_SETENA_9 ((uint32_t)0x00000200) /*!< bit 9 */
+#define NVIC_ISER_SETENA_10 ((uint32_t)0x00000400) /*!< bit 10 */
+#define NVIC_ISER_SETENA_11 ((uint32_t)0x00000800) /*!< bit 11 */
+#define NVIC_ISER_SETENA_12 ((uint32_t)0x00001000) /*!< bit 12 */
+#define NVIC_ISER_SETENA_13 ((uint32_t)0x00002000) /*!< bit 13 */
+#define NVIC_ISER_SETENA_14 ((uint32_t)0x00004000) /*!< bit 14 */
+#define NVIC_ISER_SETENA_15 ((uint32_t)0x00008000) /*!< bit 15 */
+#define NVIC_ISER_SETENA_16 ((uint32_t)0x00010000) /*!< bit 16 */
+#define NVIC_ISER_SETENA_17 ((uint32_t)0x00020000) /*!< bit 17 */
+#define NVIC_ISER_SETENA_18 ((uint32_t)0x00040000) /*!< bit 18 */
+#define NVIC_ISER_SETENA_19 ((uint32_t)0x00080000) /*!< bit 19 */
+#define NVIC_ISER_SETENA_20 ((uint32_t)0x00100000) /*!< bit 20 */
+#define NVIC_ISER_SETENA_21 ((uint32_t)0x00200000) /*!< bit 21 */
+#define NVIC_ISER_SETENA_22 ((uint32_t)0x00400000) /*!< bit 22 */
+#define NVIC_ISER_SETENA_23 ((uint32_t)0x00800000) /*!< bit 23 */
+#define NVIC_ISER_SETENA_24 ((uint32_t)0x01000000) /*!< bit 24 */
+#define NVIC_ISER_SETENA_25 ((uint32_t)0x02000000) /*!< bit 25 */
+#define NVIC_ISER_SETENA_26 ((uint32_t)0x04000000) /*!< bit 26 */
+#define NVIC_ISER_SETENA_27 ((uint32_t)0x08000000) /*!< bit 27 */
+#define NVIC_ISER_SETENA_28 ((uint32_t)0x10000000) /*!< bit 28 */
+#define NVIC_ISER_SETENA_29 ((uint32_t)0x20000000) /*!< bit 29 */
+#define NVIC_ISER_SETENA_30 ((uint32_t)0x40000000) /*!< bit 30 */
+#define NVIC_ISER_SETENA_31 ((uint32_t)0x80000000) /*!< bit 31 */
+
+/****************** Bit definition for NVIC_ICER register *******************/
+#define NVIC_ICER_CLRENA ((uint32_t)0xFFFFFFFF) /*!< Interrupt clear-enable bits */
+#define NVIC_ICER_CLRENA_0 ((uint32_t)0x00000001) /*!< bit 0 */
+#define NVIC_ICER_CLRENA_1 ((uint32_t)0x00000002) /*!< bit 1 */
+#define NVIC_ICER_CLRENA_2 ((uint32_t)0x00000004) /*!< bit 2 */
+#define NVIC_ICER_CLRENA_3 ((uint32_t)0x00000008) /*!< bit 3 */
+#define NVIC_ICER_CLRENA_4 ((uint32_t)0x00000010) /*!< bit 4 */
+#define NVIC_ICER_CLRENA_5 ((uint32_t)0x00000020) /*!< bit 5 */
+#define NVIC_ICER_CLRENA_6 ((uint32_t)0x00000040) /*!< bit 6 */
+#define NVIC_ICER_CLRENA_7 ((uint32_t)0x00000080) /*!< bit 7 */
+#define NVIC_ICER_CLRENA_8 ((uint32_t)0x00000100) /*!< bit 8 */
+#define NVIC_ICER_CLRENA_9 ((uint32_t)0x00000200) /*!< bit 9 */
+#define NVIC_ICER_CLRENA_10 ((uint32_t)0x00000400) /*!< bit 10 */
+#define NVIC_ICER_CLRENA_11 ((uint32_t)0x00000800) /*!< bit 11 */
+#define NVIC_ICER_CLRENA_12 ((uint32_t)0x00001000) /*!< bit 12 */
+#define NVIC_ICER_CLRENA_13 ((uint32_t)0x00002000) /*!< bit 13 */
+#define NVIC_ICER_CLRENA_14 ((uint32_t)0x00004000) /*!< bit 14 */
+#define NVIC_ICER_CLRENA_15 ((uint32_t)0x00008000) /*!< bit 15 */
+#define NVIC_ICER_CLRENA_16 ((uint32_t)0x00010000) /*!< bit 16 */
+#define NVIC_ICER_CLRENA_17 ((uint32_t)0x00020000) /*!< bit 17 */
+#define NVIC_ICER_CLRENA_18 ((uint32_t)0x00040000) /*!< bit 18 */
+#define NVIC_ICER_CLRENA_19 ((uint32_t)0x00080000) /*!< bit 19 */
+#define NVIC_ICER_CLRENA_20 ((uint32_t)0x00100000) /*!< bit 20 */
+#define NVIC_ICER_CLRENA_21 ((uint32_t)0x00200000) /*!< bit 21 */
+#define NVIC_ICER_CLRENA_22 ((uint32_t)0x00400000) /*!< bit 22 */
+#define NVIC_ICER_CLRENA_23 ((uint32_t)0x00800000) /*!< bit 23 */
+#define NVIC_ICER_CLRENA_24 ((uint32_t)0x01000000) /*!< bit 24 */
+#define NVIC_ICER_CLRENA_25 ((uint32_t)0x02000000) /*!< bit 25 */
+#define NVIC_ICER_CLRENA_26 ((uint32_t)0x04000000) /*!< bit 26 */
+#define NVIC_ICER_CLRENA_27 ((uint32_t)0x08000000) /*!< bit 27 */
+#define NVIC_ICER_CLRENA_28 ((uint32_t)0x10000000) /*!< bit 28 */
+#define NVIC_ICER_CLRENA_29 ((uint32_t)0x20000000) /*!< bit 29 */
+#define NVIC_ICER_CLRENA_30 ((uint32_t)0x40000000) /*!< bit 30 */
+#define NVIC_ICER_CLRENA_31 ((uint32_t)0x80000000) /*!< bit 31 */
+
+/****************** Bit definition for NVIC_ISPR register *******************/
+#define NVIC_ISPR_SETPEND ((uint32_t)0xFFFFFFFF) /*!< Interrupt set-pending bits */
+#define NVIC_ISPR_SETPEND_0 ((uint32_t)0x00000001) /*!< bit 0 */
+#define NVIC_ISPR_SETPEND_1 ((uint32_t)0x00000002) /*!< bit 1 */
+#define NVIC_ISPR_SETPEND_2 ((uint32_t)0x00000004) /*!< bit 2 */
+#define NVIC_ISPR_SETPEND_3 ((uint32_t)0x00000008) /*!< bit 3 */
+#define NVIC_ISPR_SETPEND_4 ((uint32_t)0x00000010) /*!< bit 4 */
+#define NVIC_ISPR_SETPEND_5 ((uint32_t)0x00000020) /*!< bit 5 */
+#define NVIC_ISPR_SETPEND_6 ((uint32_t)0x00000040) /*!< bit 6 */
+#define NVIC_ISPR_SETPEND_7 ((uint32_t)0x00000080) /*!< bit 7 */
+#define NVIC_ISPR_SETPEND_8 ((uint32_t)0x00000100) /*!< bit 8 */
+#define NVIC_ISPR_SETPEND_9 ((uint32_t)0x00000200) /*!< bit 9 */
+#define NVIC_ISPR_SETPEND_10 ((uint32_t)0x00000400) /*!< bit 10 */
+#define NVIC_ISPR_SETPEND_11 ((uint32_t)0x00000800) /*!< bit 11 */
+#define NVIC_ISPR_SETPEND_12 ((uint32_t)0x00001000) /*!< bit 12 */
+#define NVIC_ISPR_SETPEND_13 ((uint32_t)0x00002000) /*!< bit 13 */
+#define NVIC_ISPR_SETPEND_14 ((uint32_t)0x00004000) /*!< bit 14 */
+#define NVIC_ISPR_SETPEND_15 ((uint32_t)0x00008000) /*!< bit 15 */
+#define NVIC_ISPR_SETPEND_16 ((uint32_t)0x00010000) /*!< bit 16 */
+#define NVIC_ISPR_SETPEND_17 ((uint32_t)0x00020000) /*!< bit 17 */
+#define NVIC_ISPR_SETPEND_18 ((uint32_t)0x00040000) /*!< bit 18 */
+#define NVIC_ISPR_SETPEND_19 ((uint32_t)0x00080000) /*!< bit 19 */
+#define NVIC_ISPR_SETPEND_20 ((uint32_t)0x00100000) /*!< bit 20 */
+#define NVIC_ISPR_SETPEND_21 ((uint32_t)0x00200000) /*!< bit 21 */
+#define NVIC_ISPR_SETPEND_22 ((uint32_t)0x00400000) /*!< bit 22 */
+#define NVIC_ISPR_SETPEND_23 ((uint32_t)0x00800000) /*!< bit 23 */
+#define NVIC_ISPR_SETPEND_24 ((uint32_t)0x01000000) /*!< bit 24 */
+#define NVIC_ISPR_SETPEND_25 ((uint32_t)0x02000000) /*!< bit 25 */
+#define NVIC_ISPR_SETPEND_26 ((uint32_t)0x04000000) /*!< bit 26 */
+#define NVIC_ISPR_SETPEND_27 ((uint32_t)0x08000000) /*!< bit 27 */
+#define NVIC_ISPR_SETPEND_28 ((uint32_t)0x10000000) /*!< bit 28 */
+#define NVIC_ISPR_SETPEND_29 ((uint32_t)0x20000000) /*!< bit 29 */
+#define NVIC_ISPR_SETPEND_30 ((uint32_t)0x40000000) /*!< bit 30 */
+#define NVIC_ISPR_SETPEND_31 ((uint32_t)0x80000000) /*!< bit 31 */
+
+/****************** Bit definition for NVIC_ICPR register *******************/
+#define NVIC_ICPR_CLRPEND ((uint32_t)0xFFFFFFFF) /*!< Interrupt clear-pending bits */
+#define NVIC_ICPR_CLRPEND_0 ((uint32_t)0x00000001) /*!< bit 0 */
+#define NVIC_ICPR_CLRPEND_1 ((uint32_t)0x00000002) /*!< bit 1 */
+#define NVIC_ICPR_CLRPEND_2 ((uint32_t)0x00000004) /*!< bit 2 */
+#define NVIC_ICPR_CLRPEND_3 ((uint32_t)0x00000008) /*!< bit 3 */
+#define NVIC_ICPR_CLRPEND_4 ((uint32_t)0x00000010) /*!< bit 4 */
+#define NVIC_ICPR_CLRPEND_5 ((uint32_t)0x00000020) /*!< bit 5 */
+#define NVIC_ICPR_CLRPEND_6 ((uint32_t)0x00000040) /*!< bit 6 */
+#define NVIC_ICPR_CLRPEND_7 ((uint32_t)0x00000080) /*!< bit 7 */
+#define NVIC_ICPR_CLRPEND_8 ((uint32_t)0x00000100) /*!< bit 8 */
+#define NVIC_ICPR_CLRPEND_9 ((uint32_t)0x00000200) /*!< bit 9 */
+#define NVIC_ICPR_CLRPEND_10 ((uint32_t)0x00000400) /*!< bit 10 */
+#define NVIC_ICPR_CLRPEND_11 ((uint32_t)0x00000800) /*!< bit 11 */
+#define NVIC_ICPR_CLRPEND_12 ((uint32_t)0x00001000) /*!< bit 12 */
+#define NVIC_ICPR_CLRPEND_13 ((uint32_t)0x00002000) /*!< bit 13 */
+#define NVIC_ICPR_CLRPEND_14 ((uint32_t)0x00004000) /*!< bit 14 */
+#define NVIC_ICPR_CLRPEND_15 ((uint32_t)0x00008000) /*!< bit 15 */
+#define NVIC_ICPR_CLRPEND_16 ((uint32_t)0x00010000) /*!< bit 16 */
+#define NVIC_ICPR_CLRPEND_17 ((uint32_t)0x00020000) /*!< bit 17 */
+#define NVIC_ICPR_CLRPEND_18 ((uint32_t)0x00040000) /*!< bit 18 */
+#define NVIC_ICPR_CLRPEND_19 ((uint32_t)0x00080000) /*!< bit 19 */
+#define NVIC_ICPR_CLRPEND_20 ((uint32_t)0x00100000) /*!< bit 20 */
+#define NVIC_ICPR_CLRPEND_21 ((uint32_t)0x00200000) /*!< bit 21 */
+#define NVIC_ICPR_CLRPEND_22 ((uint32_t)0x00400000) /*!< bit 22 */
+#define NVIC_ICPR_CLRPEND_23 ((uint32_t)0x00800000) /*!< bit 23 */
+#define NVIC_ICPR_CLRPEND_24 ((uint32_t)0x01000000) /*!< bit 24 */
+#define NVIC_ICPR_CLRPEND_25 ((uint32_t)0x02000000) /*!< bit 25 */
+#define NVIC_ICPR_CLRPEND_26 ((uint32_t)0x04000000) /*!< bit 26 */
+#define NVIC_ICPR_CLRPEND_27 ((uint32_t)0x08000000) /*!< bit 27 */
+#define NVIC_ICPR_CLRPEND_28 ((uint32_t)0x10000000) /*!< bit 28 */
+#define NVIC_ICPR_CLRPEND_29 ((uint32_t)0x20000000) /*!< bit 29 */
+#define NVIC_ICPR_CLRPEND_30 ((uint32_t)0x40000000) /*!< bit 30 */
+#define NVIC_ICPR_CLRPEND_31 ((uint32_t)0x80000000) /*!< bit 31 */
+
+/****************** Bit definition for NVIC_IABR register *******************/
+#define NVIC_IABR_ACTIVE ((uint32_t)0xFFFFFFFF) /*!< Interrupt active flags */
+#define NVIC_IABR_ACTIVE_0 ((uint32_t)0x00000001) /*!< bit 0 */
+#define NVIC_IABR_ACTIVE_1 ((uint32_t)0x00000002) /*!< bit 1 */
+#define NVIC_IABR_ACTIVE_2 ((uint32_t)0x00000004) /*!< bit 2 */
+#define NVIC_IABR_ACTIVE_3 ((uint32_t)0x00000008) /*!< bit 3 */
+#define NVIC_IABR_ACTIVE_4 ((uint32_t)0x00000010) /*!< bit 4 */
+#define NVIC_IABR_ACTIVE_5 ((uint32_t)0x00000020) /*!< bit 5 */
+#define NVIC_IABR_ACTIVE_6 ((uint32_t)0x00000040) /*!< bit 6 */
+#define NVIC_IABR_ACTIVE_7 ((uint32_t)0x00000080) /*!< bit 7 */
+#define NVIC_IABR_ACTIVE_8 ((uint32_t)0x00000100) /*!< bit 8 */
+#define NVIC_IABR_ACTIVE_9 ((uint32_t)0x00000200) /*!< bit 9 */
+#define NVIC_IABR_ACTIVE_10 ((uint32_t)0x00000400) /*!< bit 10 */
+#define NVIC_IABR_ACTIVE_11 ((uint32_t)0x00000800) /*!< bit 11 */
+#define NVIC_IABR_ACTIVE_12 ((uint32_t)0x00001000) /*!< bit 12 */
+#define NVIC_IABR_ACTIVE_13 ((uint32_t)0x00002000) /*!< bit 13 */
+#define NVIC_IABR_ACTIVE_14 ((uint32_t)0x00004000) /*!< bit 14 */
+#define NVIC_IABR_ACTIVE_15 ((uint32_t)0x00008000) /*!< bit 15 */
+#define NVIC_IABR_ACTIVE_16 ((uint32_t)0x00010000) /*!< bit 16 */
+#define NVIC_IABR_ACTIVE_17 ((uint32_t)0x00020000) /*!< bit 17 */
+#define NVIC_IABR_ACTIVE_18 ((uint32_t)0x00040000) /*!< bit 18 */
+#define NVIC_IABR_ACTIVE_19 ((uint32_t)0x00080000) /*!< bit 19 */
+#define NVIC_IABR_ACTIVE_20 ((uint32_t)0x00100000) /*!< bit 20 */
+#define NVIC_IABR_ACTIVE_21 ((uint32_t)0x00200000) /*!< bit 21 */
+#define NVIC_IABR_ACTIVE_22 ((uint32_t)0x00400000) /*!< bit 22 */
+#define NVIC_IABR_ACTIVE_23 ((uint32_t)0x00800000) /*!< bit 23 */
+#define NVIC_IABR_ACTIVE_24 ((uint32_t)0x01000000) /*!< bit 24 */
+#define NVIC_IABR_ACTIVE_25 ((uint32_t)0x02000000) /*!< bit 25 */
+#define NVIC_IABR_ACTIVE_26 ((uint32_t)0x04000000) /*!< bit 26 */
+#define NVIC_IABR_ACTIVE_27 ((uint32_t)0x08000000) /*!< bit 27 */
+#define NVIC_IABR_ACTIVE_28 ((uint32_t)0x10000000) /*!< bit 28 */
+#define NVIC_IABR_ACTIVE_29 ((uint32_t)0x20000000) /*!< bit 29 */
+#define NVIC_IABR_ACTIVE_30 ((uint32_t)0x40000000) /*!< bit 30 */
+#define NVIC_IABR_ACTIVE_31 ((uint32_t)0x80000000) /*!< bit 31 */
+
+/****************** Bit definition for NVIC_PRI0 register *******************/
+#define NVIC_IPR0_PRI_0 ((uint32_t)0x000000FF) /*!< Priority of interrupt 0 */
+#define NVIC_IPR0_PRI_1 ((uint32_t)0x0000FF00) /*!< Priority of interrupt 1 */
+#define NVIC_IPR0_PRI_2 ((uint32_t)0x00FF0000) /*!< Priority of interrupt 2 */
+#define NVIC_IPR0_PRI_3 ((uint32_t)0xFF000000) /*!< Priority of interrupt 3 */
+
+/****************** Bit definition for NVIC_PRI1 register *******************/
+#define NVIC_IPR1_PRI_4 ((uint32_t)0x000000FF) /*!< Priority of interrupt 4 */
+#define NVIC_IPR1_PRI_5 ((uint32_t)0x0000FF00) /*!< Priority of interrupt 5 */
+#define NVIC_IPR1_PRI_6 ((uint32_t)0x00FF0000) /*!< Priority of interrupt 6 */
+#define NVIC_IPR1_PRI_7 ((uint32_t)0xFF000000) /*!< Priority of interrupt 7 */
+
+/****************** Bit definition for NVIC_PRI2 register *******************/
+#define NVIC_IPR2_PRI_8 ((uint32_t)0x000000FF) /*!< Priority of interrupt 8 */
+#define NVIC_IPR2_PRI_9 ((uint32_t)0x0000FF00) /*!< Priority of interrupt 9 */
+#define NVIC_IPR2_PRI_10 ((uint32_t)0x00FF0000) /*!< Priority of interrupt 10 */
+#define NVIC_IPR2_PRI_11 ((uint32_t)0xFF000000) /*!< Priority of interrupt 11 */
+
+/****************** Bit definition for NVIC_PRI3 register *******************/
+#define NVIC_IPR3_PRI_12 ((uint32_t)0x000000FF) /*!< Priority of interrupt 12 */
+#define NVIC_IPR3_PRI_13 ((uint32_t)0x0000FF00) /*!< Priority of interrupt 13 */
+#define NVIC_IPR3_PRI_14 ((uint32_t)0x00FF0000) /*!< Priority of interrupt 14 */
+#define NVIC_IPR3_PRI_15 ((uint32_t)0xFF000000) /*!< Priority of interrupt 15 */
+
+/****************** Bit definition for NVIC_PRI4 register *******************/
+#define NVIC_IPR4_PRI_16 ((uint32_t)0x000000FF) /*!< Priority of interrupt 16 */
+#define NVIC_IPR4_PRI_17 ((uint32_t)0x0000FF00) /*!< Priority of interrupt 17 */
+#define NVIC_IPR4_PRI_18 ((uint32_t)0x00FF0000) /*!< Priority of interrupt 18 */
+#define NVIC_IPR4_PRI_19 ((uint32_t)0xFF000000) /*!< Priority of interrupt 19 */
+
+/****************** Bit definition for NVIC_PRI5 register *******************/
+#define NVIC_IPR5_PRI_20 ((uint32_t)0x000000FF) /*!< Priority of interrupt 20 */
+#define NVIC_IPR5_PRI_21 ((uint32_t)0x0000FF00) /*!< Priority of interrupt 21 */
+#define NVIC_IPR5_PRI_22 ((uint32_t)0x00FF0000) /*!< Priority of interrupt 22 */
+#define NVIC_IPR5_PRI_23 ((uint32_t)0xFF000000) /*!< Priority of interrupt 23 */
+
+/****************** Bit definition for NVIC_PRI6 register *******************/
+#define NVIC_IPR6_PRI_24 ((uint32_t)0x000000FF) /*!< Priority of interrupt 24 */
+#define NVIC_IPR6_PRI_25 ((uint32_t)0x0000FF00) /*!< Priority of interrupt 25 */
+#define NVIC_IPR6_PRI_26 ((uint32_t)0x00FF0000) /*!< Priority of interrupt 26 */
+#define NVIC_IPR6_PRI_27 ((uint32_t)0xFF000000) /*!< Priority of interrupt 27 */
+
+/****************** Bit definition for NVIC_PRI7 register *******************/
+#define NVIC_IPR7_PRI_28 ((uint32_t)0x000000FF) /*!< Priority of interrupt 28 */
+#define NVIC_IPR7_PRI_29 ((uint32_t)0x0000FF00) /*!< Priority of interrupt 29 */
+#define NVIC_IPR7_PRI_30 ((uint32_t)0x00FF0000) /*!< Priority of interrupt 30 */
+#define NVIC_IPR7_PRI_31 ((uint32_t)0xFF000000) /*!< Priority of interrupt 31 */
+
+/****************** Bit definition for SCB_CPUID register *******************/
+#define SCB_CPUID_REVISION ((uint32_t)0x0000000F) /*!< Implementation defined revision number */
+#define SCB_CPUID_PARTNO ((uint32_t)0x0000FFF0) /*!< Number of processor within family */
+#define SCB_CPUID_Constant ((uint32_t)0x000F0000) /*!< Reads as 0x0F */
+#define SCB_CPUID_VARIANT ((uint32_t)0x00F00000) /*!< Implementation defined variant number */
+#define SCB_CPUID_IMPLEMENTER ((uint32_t)0xFF000000) /*!< Implementer code. ARM is 0x41 */
+
+/******************* Bit definition for SCB_ICSR register *******************/
+#define SCB_ICSR_VECTACTIVE ((uint32_t)0x000001FF) /*!< Active ISR number field */
+#define SCB_ICSR_RETTOBASE ((uint32_t)0x00000800) /*!< All active exceptions minus the IPSR_current_exception yields the empty set */
+#define SCB_ICSR_VECTPENDING ((uint32_t)0x003FF000) /*!< Pending ISR number field */
+#define SCB_ICSR_ISRPENDING ((uint32_t)0x00400000) /*!< Interrupt pending flag */
+#define SCB_ICSR_ISRPREEMPT ((uint32_t)0x00800000) /*!< It indicates that a pending interrupt becomes active in the next running cycle */
+#define SCB_ICSR_PENDSTCLR ((uint32_t)0x02000000) /*!< Clear pending SysTick bit */
+#define SCB_ICSR_PENDSTSET ((uint32_t)0x04000000) /*!< Set pending SysTick bit */
+#define SCB_ICSR_PENDSVCLR ((uint32_t)0x08000000) /*!< Clear pending pendSV bit */
+#define SCB_ICSR_PENDSVSET ((uint32_t)0x10000000) /*!< Set pending pendSV bit */
+#define SCB_ICSR_NMIPENDSET ((uint32_t)0x80000000) /*!< Set pending NMI bit */
+
+/******************* Bit definition for SCB_VTOR register *******************/
+#define SCB_VTOR_TBLOFF ((uint32_t)0x1FFFFF80) /*!< Vector table base offset field */
+#define SCB_VTOR_TBLBASE ((uint32_t)0x20000000) /*!< Table base in code(0) or RAM(1) */
+
+/*!<***************** Bit definition for SCB_AIRCR register *******************/
+#define SCB_AIRCR_VECTRESET ((uint32_t)0x00000001) /*!< System Reset bit */
+#define SCB_AIRCR_VECTCLRACTIVE ((uint32_t)0x00000002) /*!< Clear active vector bit */
+#define SCB_AIRCR_SYSRESETREQ ((uint32_t)0x00000004) /*!< Requests chip control logic to generate a reset */
+
+#define SCB_AIRCR_PRIGROUP ((uint32_t)0x00000700) /*!< PRIGROUP[2:0] bits (Priority group) */
+#define SCB_AIRCR_PRIGROUP_0 ((uint32_t)0x00000100) /*!< Bit 0 */
+#define SCB_AIRCR_PRIGROUP_1 ((uint32_t)0x00000200) /*!< Bit 1 */
+#define SCB_AIRCR_PRIGROUP_2 ((uint32_t)0x00000400) /*!< Bit 2 */
+
+/* prority group configuration */
+#define SCB_AIRCR_PRIGROUP0 ((uint32_t)0x00000000) /*!< Priority group=0 (7 bits of pre-emption priority, 1 bit of subpriority) */
+#define SCB_AIRCR_PRIGROUP1 ((uint32_t)0x00000100) /*!< Priority group=1 (6 bits of pre-emption priority, 2 bits of subpriority) */
+#define SCB_AIRCR_PRIGROUP2 ((uint32_t)0x00000200) /*!< Priority group=2 (5 bits of pre-emption priority, 3 bits of subpriority) */
+#define SCB_AIRCR_PRIGROUP3 ((uint32_t)0x00000300) /*!< Priority group=3 (4 bits of pre-emption priority, 4 bits of subpriority) */
+#define SCB_AIRCR_PRIGROUP4 ((uint32_t)0x00000400) /*!< Priority group=4 (3 bits of pre-emption priority, 5 bits of subpriority) */
+#define SCB_AIRCR_PRIGROUP5 ((uint32_t)0x00000500) /*!< Priority group=5 (2 bits of pre-emption priority, 6 bits of subpriority) */
+#define SCB_AIRCR_PRIGROUP6 ((uint32_t)0x00000600) /*!< Priority group=6 (1 bit of pre-emption priority, 7 bits of subpriority) */
+#define SCB_AIRCR_PRIGROUP7 ((uint32_t)0x00000700) /*!< Priority group=7 (no pre-emption priority, 8 bits of subpriority) */
+
+#define SCB_AIRCR_ENDIANESS ((uint32_t)0x00008000) /*!< Data endianness bit */
+#define SCB_AIRCR_VECTKEY ((uint32_t)0xFFFF0000) /*!< Register key (VECTKEY) - Reads as 0xFA05 (VECTKEYSTAT) */
+
+/******************* Bit definition for SCB_SCR register ********************/
+#define SCB_SCR_SLEEPONEXIT ((uint8_t)0x02) /*!< Sleep on exit bit */
+#define SCB_SCR_SLEEPDEEP ((uint8_t)0x04) /*!< Sleep deep bit */
+#define SCB_SCR_SEVONPEND ((uint8_t)0x10) /*!< Wake up from WFE */
+
+/******************** Bit definition for SCB_CCR register *******************/
+#define SCB_CCR_NONBASETHRDENA ((uint16_t)0x0001) /*!< Thread mode can be entered from any level in Handler mode by controlled return value */
+#define SCB_CCR_USERSETMPEND ((uint16_t)0x0002) /*!< Enables user code to write the Software Trigger Interrupt register to trigger (pend) a Main exception */
+#define SCB_CCR_UNALIGN_TRP ((uint16_t)0x0008) /*!< Trap for unaligned access */
+#define SCB_CCR_DIV_0_TRP ((uint16_t)0x0010) /*!< Trap on Divide by 0 */
+#define SCB_CCR_BFHFNMIGN ((uint16_t)0x0100) /*!< Handlers running at priority -1 and -2 */
+#define SCB_CCR_STKALIGN ((uint16_t)0x0200) /*!< On exception entry, the SP used prior to the exception is adjusted to be 8-byte aligned */
+
+/******************* Bit definition for SCB_SHPR register ********************/
+#define SCB_SHPR_PRI_N ((uint32_t)0x000000FF) /*!< Priority of system handler 4,8, and 12. Mem Manage, reserved and Debug Monitor */
+#define SCB_SHPR_PRI_N1 ((uint32_t)0x0000FF00) /*!< Priority of system handler 5,9, and 13. Bus Fault, reserved and reserved */
+#define SCB_SHPR_PRI_N2 ((uint32_t)0x00FF0000) /*!< Priority of system handler 6,10, and 14. Usage Fault, reserved and PendSV */
+#define SCB_SHPR_PRI_N3 ((uint32_t)0xFF000000) /*!< Priority of system handler 7,11, and 15. Reserved, SVCall and SysTick */
+
+/****************** Bit definition for SCB_SHCSR register *******************/
+#define SCB_SHCSR_MEMFAULTACT ((uint32_t)0x00000001) /*!< MemManage is active */
+#define SCB_SHCSR_BUSFAULTACT ((uint32_t)0x00000002) /*!< BusFault is active */
+#define SCB_SHCSR_USGFAULTACT ((uint32_t)0x00000008) /*!< UsageFault is active */
+#define SCB_SHCSR_SVCALLACT ((uint32_t)0x00000080) /*!< SVCall is active */
+#define SCB_SHCSR_MONITORACT ((uint32_t)0x00000100) /*!< Monitor is active */
+#define SCB_SHCSR_PENDSVACT ((uint32_t)0x00000400) /*!< PendSV is active */
+#define SCB_SHCSR_SYSTICKACT ((uint32_t)0x00000800) /*!< SysTick is active */
+#define SCB_SHCSR_USGFAULTPENDED ((uint32_t)0x00001000) /*!< Usage Fault is pended */
+#define SCB_SHCSR_MEMFAULTPENDED ((uint32_t)0x00002000) /*!< MemManage is pended */
+#define SCB_SHCSR_BUSFAULTPENDED ((uint32_t)0x00004000) /*!< Bus Fault is pended */
+#define SCB_SHCSR_SVCALLPENDED ((uint32_t)0x00008000) /*!< SVCall is pended */
+#define SCB_SHCSR_MEMFAULTENA ((uint32_t)0x00010000) /*!< MemManage enable */
+#define SCB_SHCSR_BUSFAULTENA ((uint32_t)0x00020000) /*!< Bus Fault enable */
+#define SCB_SHCSR_USGFAULTENA ((uint32_t)0x00040000) /*!< UsageFault enable */
+
+/******************* Bit definition for SCB_CFSR register *******************/
+/*!< MFSR */
+#define SCB_CFSR_IACCVIOL ((uint32_t)0x00000001) /*!< Instruction access violation */
+#define SCB_CFSR_DACCVIOL ((uint32_t)0x00000002) /*!< Data access violation */
+#define SCB_CFSR_MUNSTKERR ((uint32_t)0x00000008) /*!< Unstacking error */
+#define SCB_CFSR_MSTKERR ((uint32_t)0x00000010) /*!< Stacking error */
+#define SCB_CFSR_MMARVALID ((uint32_t)0x00000080) /*!< Memory Manage Address Register address valid flag */
+/*!< BFSR */
+#define SCB_CFSR_IBUSERR ((uint32_t)0x00000100) /*!< Instruction bus error flag */
+#define SCB_CFSR_PRECISERR ((uint32_t)0x00000200) /*!< Precise data bus error */
+#define SCB_CFSR_IMPRECISERR ((uint32_t)0x00000400) /*!< Imprecise data bus error */
+#define SCB_CFSR_UNSTKERR ((uint32_t)0x00000800) /*!< Unstacking error */
+#define SCB_CFSR_STKERR ((uint32_t)0x00001000) /*!< Stacking error */
+#define SCB_CFSR_BFARVALID ((uint32_t)0x00008000) /*!< Bus Fault Address Register address valid flag */
+/*!< UFSR */
+#define SCB_CFSR_UNDEFINSTR ((uint32_t)0x00010000) /*!< The processor attempt to excecute an undefined instruction */
+#define SCB_CFSR_INVSTATE ((uint32_t)0x00020000) /*!< Invalid combination of EPSR and instruction */
+#define SCB_CFSR_INVPC ((uint32_t)0x00040000) /*!< Attempt to load EXC_RETURN into pc illegally */
+#define SCB_CFSR_NOCP ((uint32_t)0x00080000) /*!< Attempt to use a coprocessor instruction */
+#define SCB_CFSR_UNALIGNED ((uint32_t)0x01000000) /*!< Fault occurs when there is an attempt to make an unaligned memory access */
+#define SCB_CFSR_DIVBYZERO ((uint32_t)0x02000000) /*!< Fault occurs when SDIV or DIV instruction is used with a divisor of 0 */
+
+/******************* Bit definition for SCB_HFSR register *******************/
+#define SCB_HFSR_VECTTBL ((uint32_t)0x00000002) /*!< Fault occures because of vector table read on exception processing */
+#define SCB_HFSR_FORCED ((uint32_t)0x40000000) /*!< Hard Fault activated when a configurable Fault was received and cannot activate */
+#define SCB_HFSR_DEBUGEVT ((uint32_t)0x80000000) /*!< Fault related to debug */
+
+/******************* Bit definition for SCB_DFSR register *******************/
+#define SCB_DFSR_HALTED ((uint8_t)0x01) /*!< Halt request flag */
+#define SCB_DFSR_BKPT ((uint8_t)0x02) /*!< BKPT flag */
+#define SCB_DFSR_DWTTRAP ((uint8_t)0x04) /*!< Data Watchpoint and Trace (DWT) flag */
+#define SCB_DFSR_VCATCH ((uint8_t)0x08) /*!< Vector catch flag */
+#define SCB_DFSR_EXTERNAL ((uint8_t)0x10) /*!< External debug request flag */
+
+/******************* Bit definition for SCB_MMFAR register ******************/
+#define SCB_MMFAR_ADDRESS ((uint32_t)0xFFFFFFFF) /*!< Mem Manage fault address field */
+
+/******************* Bit definition for SCB_BFAR register *******************/
+#define SCB_BFAR_ADDRESS ((uint32_t)0xFFFFFFFF) /*!< Bus fault address field */
+
+/******************* Bit definition for SCB_afsr register *******************/
+#define SCB_AFSR_IMPDEF ((uint32_t)0xFFFFFFFF) /*!< Implementation defined */
+
+/******************************************************************************/
+/* */
+/* External Interrupt/Event Controller */
+/* */
+/******************************************************************************/
+
+/******************* Bit definition for EXTI_IMR register *******************/
+#define EXTI_IMR_MR0 ((uint32_t)0x00000001) /*!< Interrupt Mask on line 0 */
+#define EXTI_IMR_MR1 ((uint32_t)0x00000002) /*!< Interrupt Mask on line 1 */
+#define EXTI_IMR_MR2 ((uint32_t)0x00000004) /*!< Interrupt Mask on line 2 */
+#define EXTI_IMR_MR3 ((uint32_t)0x00000008) /*!< Interrupt Mask on line 3 */
+#define EXTI_IMR_MR4 ((uint32_t)0x00000010) /*!< Interrupt Mask on line 4 */
+#define EXTI_IMR_MR5 ((uint32_t)0x00000020) /*!< Interrupt Mask on line 5 */
+#define EXTI_IMR_MR6 ((uint32_t)0x00000040) /*!< Interrupt Mask on line 6 */
+#define EXTI_IMR_MR7 ((uint32_t)0x00000080) /*!< Interrupt Mask on line 7 */
+#define EXTI_IMR_MR8 ((uint32_t)0x00000100) /*!< Interrupt Mask on line 8 */
+#define EXTI_IMR_MR9 ((uint32_t)0x00000200) /*!< Interrupt Mask on line 9 */
+#define EXTI_IMR_MR10 ((uint32_t)0x00000400) /*!< Interrupt Mask on line 10 */
+#define EXTI_IMR_MR11 ((uint32_t)0x00000800) /*!< Interrupt Mask on line 11 */
+#define EXTI_IMR_MR12 ((uint32_t)0x00001000) /*!< Interrupt Mask on line 12 */
+#define EXTI_IMR_MR13 ((uint32_t)0x00002000) /*!< Interrupt Mask on line 13 */
+#define EXTI_IMR_MR14 ((uint32_t)0x00004000) /*!< Interrupt Mask on line 14 */
+#define EXTI_IMR_MR15 ((uint32_t)0x00008000) /*!< Interrupt Mask on line 15 */
+#define EXTI_IMR_MR16 ((uint32_t)0x00010000) /*!< Interrupt Mask on line 16 */
+#define EXTI_IMR_MR17 ((uint32_t)0x00020000) /*!< Interrupt Mask on line 17 */
+#define EXTI_IMR_MR18 ((uint32_t)0x00040000) /*!< Interrupt Mask on line 18 */
+#define EXTI_IMR_MR19 ((uint32_t)0x00080000) /*!< Interrupt Mask on line 19 */
+
+/******************* Bit definition for EXTI_EMR register *******************/
+#define EXTI_EMR_MR0 ((uint32_t)0x00000001) /*!< Event Mask on line 0 */
+#define EXTI_EMR_MR1 ((uint32_t)0x00000002) /*!< Event Mask on line 1 */
+#define EXTI_EMR_MR2 ((uint32_t)0x00000004) /*!< Event Mask on line 2 */
+#define EXTI_EMR_MR3 ((uint32_t)0x00000008) /*!< Event Mask on line 3 */
+#define EXTI_EMR_MR4 ((uint32_t)0x00000010) /*!< Event Mask on line 4 */
+#define EXTI_EMR_MR5 ((uint32_t)0x00000020) /*!< Event Mask on line 5 */
+#define EXTI_EMR_MR6 ((uint32_t)0x00000040) /*!< Event Mask on line 6 */
+#define EXTI_EMR_MR7 ((uint32_t)0x00000080) /*!< Event Mask on line 7 */
+#define EXTI_EMR_MR8 ((uint32_t)0x00000100) /*!< Event Mask on line 8 */
+#define EXTI_EMR_MR9 ((uint32_t)0x00000200) /*!< Event Mask on line 9 */
+#define EXTI_EMR_MR10 ((uint32_t)0x00000400) /*!< Event Mask on line 10 */
+#define EXTI_EMR_MR11 ((uint32_t)0x00000800) /*!< Event Mask on line 11 */
+#define EXTI_EMR_MR12 ((uint32_t)0x00001000) /*!< Event Mask on line 12 */
+#define EXTI_EMR_MR13 ((uint32_t)0x00002000) /*!< Event Mask on line 13 */
+#define EXTI_EMR_MR14 ((uint32_t)0x00004000) /*!< Event Mask on line 14 */
+#define EXTI_EMR_MR15 ((uint32_t)0x00008000) /*!< Event Mask on line 15 */
+#define EXTI_EMR_MR16 ((uint32_t)0x00010000) /*!< Event Mask on line 16 */
+#define EXTI_EMR_MR17 ((uint32_t)0x00020000) /*!< Event Mask on line 17 */
+#define EXTI_EMR_MR18 ((uint32_t)0x00040000) /*!< Event Mask on line 18 */
+#define EXTI_EMR_MR19 ((uint32_t)0x00080000) /*!< Event Mask on line 19 */
+
+/****************** Bit definition for EXTI_RTSR register *******************/
+#define EXTI_RTSR_TR0 ((uint32_t)0x00000001) /*!< Rising trigger event configuration bit of line 0 */
+#define EXTI_RTSR_TR1 ((uint32_t)0x00000002) /*!< Rising trigger event configuration bit of line 1 */
+#define EXTI_RTSR_TR2 ((uint32_t)0x00000004) /*!< Rising trigger event configuration bit of line 2 */
+#define EXTI_RTSR_TR3 ((uint32_t)0x00000008) /*!< Rising trigger event configuration bit of line 3 */
+#define EXTI_RTSR_TR4 ((uint32_t)0x00000010) /*!< Rising trigger event configuration bit of line 4 */
+#define EXTI_RTSR_TR5 ((uint32_t)0x00000020) /*!< Rising trigger event configuration bit of line 5 */
+#define EXTI_RTSR_TR6 ((uint32_t)0x00000040) /*!< Rising trigger event configuration bit of line 6 */
+#define EXTI_RTSR_TR7 ((uint32_t)0x00000080) /*!< Rising trigger event configuration bit of line 7 */
+#define EXTI_RTSR_TR8 ((uint32_t)0x00000100) /*!< Rising trigger event configuration bit of line 8 */
+#define EXTI_RTSR_TR9 ((uint32_t)0x00000200) /*!< Rising trigger event configuration bit of line 9 */
+#define EXTI_RTSR_TR10 ((uint32_t)0x00000400) /*!< Rising trigger event configuration bit of line 10 */
+#define EXTI_RTSR_TR11 ((uint32_t)0x00000800) /*!< Rising trigger event configuration bit of line 11 */
+#define EXTI_RTSR_TR12 ((uint32_t)0x00001000) /*!< Rising trigger event configuration bit of line 12 */
+#define EXTI_RTSR_TR13 ((uint32_t)0x00002000) /*!< Rising trigger event configuration bit of line 13 */
+#define EXTI_RTSR_TR14 ((uint32_t)0x00004000) /*!< Rising trigger event configuration bit of line 14 */
+#define EXTI_RTSR_TR15 ((uint32_t)0x00008000) /*!< Rising trigger event configuration bit of line 15 */
+#define EXTI_RTSR_TR16 ((uint32_t)0x00010000) /*!< Rising trigger event configuration bit of line 16 */
+#define EXTI_RTSR_TR17 ((uint32_t)0x00020000) /*!< Rising trigger event configuration bit of line 17 */
+#define EXTI_RTSR_TR18 ((uint32_t)0x00040000) /*!< Rising trigger event configuration bit of line 18 */
+#define EXTI_RTSR_TR19 ((uint32_t)0x00080000) /*!< Rising trigger event configuration bit of line 19 */
+
+/****************** Bit definition for EXTI_FTSR register *******************/
+#define EXTI_FTSR_TR0 ((uint32_t)0x00000001) /*!< Falling trigger event configuration bit of line 0 */
+#define EXTI_FTSR_TR1 ((uint32_t)0x00000002) /*!< Falling trigger event configuration bit of line 1 */
+#define EXTI_FTSR_TR2 ((uint32_t)0x00000004) /*!< Falling trigger event configuration bit of line 2 */
+#define EXTI_FTSR_TR3 ((uint32_t)0x00000008) /*!< Falling trigger event configuration bit of line 3 */
+#define EXTI_FTSR_TR4 ((uint32_t)0x00000010) /*!< Falling trigger event configuration bit of line 4 */
+#define EXTI_FTSR_TR5 ((uint32_t)0x00000020) /*!< Falling trigger event configuration bit of line 5 */
+#define EXTI_FTSR_TR6 ((uint32_t)0x00000040) /*!< Falling trigger event configuration bit of line 6 */
+#define EXTI_FTSR_TR7 ((uint32_t)0x00000080) /*!< Falling trigger event configuration bit of line 7 */
+#define EXTI_FTSR_TR8 ((uint32_t)0x00000100) /*!< Falling trigger event configuration bit of line 8 */
+#define EXTI_FTSR_TR9 ((uint32_t)0x00000200) /*!< Falling trigger event configuration bit of line 9 */
+#define EXTI_FTSR_TR10 ((uint32_t)0x00000400) /*!< Falling trigger event configuration bit of line 10 */
+#define EXTI_FTSR_TR11 ((uint32_t)0x00000800) /*!< Falling trigger event configuration bit of line 11 */
+#define EXTI_FTSR_TR12 ((uint32_t)0x00001000) /*!< Falling trigger event configuration bit of line 12 */
+#define EXTI_FTSR_TR13 ((uint32_t)0x00002000) /*!< Falling trigger event configuration bit of line 13 */
+#define EXTI_FTSR_TR14 ((uint32_t)0x00004000) /*!< Falling trigger event configuration bit of line 14 */
+#define EXTI_FTSR_TR15 ((uint32_t)0x00008000) /*!< Falling trigger event configuration bit of line 15 */
+#define EXTI_FTSR_TR16 ((uint32_t)0x00010000) /*!< Falling trigger event configuration bit of line 16 */
+#define EXTI_FTSR_TR17 ((uint32_t)0x00020000) /*!< Falling trigger event configuration bit of line 17 */
+#define EXTI_FTSR_TR18 ((uint32_t)0x00040000) /*!< Falling trigger event configuration bit of line 18 */
+#define EXTI_FTSR_TR19 ((uint32_t)0x00080000) /*!< Falling trigger event configuration bit of line 19 */
+
+/****************** Bit definition for EXTI_SWIER register ******************/
+#define EXTI_SWIER_SWIER0 ((uint32_t)0x00000001) /*!< Software Interrupt on line 0 */
+#define EXTI_SWIER_SWIER1 ((uint32_t)0x00000002) /*!< Software Interrupt on line 1 */
+#define EXTI_SWIER_SWIER2 ((uint32_t)0x00000004) /*!< Software Interrupt on line 2 */
+#define EXTI_SWIER_SWIER3 ((uint32_t)0x00000008) /*!< Software Interrupt on line 3 */
+#define EXTI_SWIER_SWIER4 ((uint32_t)0x00000010) /*!< Software Interrupt on line 4 */
+#define EXTI_SWIER_SWIER5 ((uint32_t)0x00000020) /*!< Software Interrupt on line 5 */
+#define EXTI_SWIER_SWIER6 ((uint32_t)0x00000040) /*!< Software Interrupt on line 6 */
+#define EXTI_SWIER_SWIER7 ((uint32_t)0x00000080) /*!< Software Interrupt on line 7 */
+#define EXTI_SWIER_SWIER8 ((uint32_t)0x00000100) /*!< Software Interrupt on line 8 */
+#define EXTI_SWIER_SWIER9 ((uint32_t)0x00000200) /*!< Software Interrupt on line 9 */
+#define EXTI_SWIER_SWIER10 ((uint32_t)0x00000400) /*!< Software Interrupt on line 10 */
+#define EXTI_SWIER_SWIER11 ((uint32_t)0x00000800) /*!< Software Interrupt on line 11 */
+#define EXTI_SWIER_SWIER12 ((uint32_t)0x00001000) /*!< Software Interrupt on line 12 */
+#define EXTI_SWIER_SWIER13 ((uint32_t)0x00002000) /*!< Software Interrupt on line 13 */
+#define EXTI_SWIER_SWIER14 ((uint32_t)0x00004000) /*!< Software Interrupt on line 14 */
+#define EXTI_SWIER_SWIER15 ((uint32_t)0x00008000) /*!< Software Interrupt on line 15 */
+#define EXTI_SWIER_SWIER16 ((uint32_t)0x00010000) /*!< Software Interrupt on line 16 */
+#define EXTI_SWIER_SWIER17 ((uint32_t)0x00020000) /*!< Software Interrupt on line 17 */
+#define EXTI_SWIER_SWIER18 ((uint32_t)0x00040000) /*!< Software Interrupt on line 18 */
+#define EXTI_SWIER_SWIER19 ((uint32_t)0x00080000) /*!< Software Interrupt on line 19 */
+
+/******************* Bit definition for EXTI_PR register ********************/
+#define EXTI_PR_PR0 ((uint32_t)0x00000001) /*!< Pending bit for line 0 */
+#define EXTI_PR_PR1 ((uint32_t)0x00000002) /*!< Pending bit for line 1 */
+#define EXTI_PR_PR2 ((uint32_t)0x00000004) /*!< Pending bit for line 2 */
+#define EXTI_PR_PR3 ((uint32_t)0x00000008) /*!< Pending bit for line 3 */
+#define EXTI_PR_PR4 ((uint32_t)0x00000010) /*!< Pending bit for line 4 */
+#define EXTI_PR_PR5 ((uint32_t)0x00000020) /*!< Pending bit for line 5 */
+#define EXTI_PR_PR6 ((uint32_t)0x00000040) /*!< Pending bit for line 6 */
+#define EXTI_PR_PR7 ((uint32_t)0x00000080) /*!< Pending bit for line 7 */
+#define EXTI_PR_PR8 ((uint32_t)0x00000100) /*!< Pending bit for line 8 */
+#define EXTI_PR_PR9 ((uint32_t)0x00000200) /*!< Pending bit for line 9 */
+#define EXTI_PR_PR10 ((uint32_t)0x00000400) /*!< Pending bit for line 10 */
+#define EXTI_PR_PR11 ((uint32_t)0x00000800) /*!< Pending bit for line 11 */
+#define EXTI_PR_PR12 ((uint32_t)0x00001000) /*!< Pending bit for line 12 */
+#define EXTI_PR_PR13 ((uint32_t)0x00002000) /*!< Pending bit for line 13 */
+#define EXTI_PR_PR14 ((uint32_t)0x00004000) /*!< Pending bit for line 14 */
+#define EXTI_PR_PR15 ((uint32_t)0x00008000) /*!< Pending bit for line 15 */
+#define EXTI_PR_PR16 ((uint32_t)0x00010000) /*!< Pending bit for line 16 */
+#define EXTI_PR_PR17 ((uint32_t)0x00020000) /*!< Pending bit for line 17 */
+#define EXTI_PR_PR18 ((uint32_t)0x00040000) /*!< Pending bit for line 18 */
+#define EXTI_PR_PR19 ((uint32_t)0x00080000) /*!< Pending bit for line 19 */
+
+/******************************************************************************/
+/* */
+/* DMA Controller */
+/* */
+/******************************************************************************/
+
+/******************* Bit definition for DMA_ISR register ********************/
+#define DMA_ISR_GIF1 ((uint32_t)0x00000001) /*!< Channel 1 Global interrupt flag */
+#define DMA_ISR_TCIF1 ((uint32_t)0x00000002) /*!< Channel 1 Transfer Complete flag */
+#define DMA_ISR_HTIF1 ((uint32_t)0x00000004) /*!< Channel 1 Half Transfer flag */
+#define DMA_ISR_TEIF1 ((uint32_t)0x00000008) /*!< Channel 1 Transfer Error flag */
+#define DMA_ISR_GIF2 ((uint32_t)0x00000010) /*!< Channel 2 Global interrupt flag */
+#define DMA_ISR_TCIF2 ((uint32_t)0x00000020) /*!< Channel 2 Transfer Complete flag */
+#define DMA_ISR_HTIF2 ((uint32_t)0x00000040) /*!< Channel 2 Half Transfer flag */
+#define DMA_ISR_TEIF2 ((uint32_t)0x00000080) /*!< Channel 2 Transfer Error flag */
+#define DMA_ISR_GIF3 ((uint32_t)0x00000100) /*!< Channel 3 Global interrupt flag */
+#define DMA_ISR_TCIF3 ((uint32_t)0x00000200) /*!< Channel 3 Transfer Complete flag */
+#define DMA_ISR_HTIF3 ((uint32_t)0x00000400) /*!< Channel 3 Half Transfer flag */
+#define DMA_ISR_TEIF3 ((uint32_t)0x00000800) /*!< Channel 3 Transfer Error flag */
+#define DMA_ISR_GIF4 ((uint32_t)0x00001000) /*!< Channel 4 Global interrupt flag */
+#define DMA_ISR_TCIF4 ((uint32_t)0x00002000) /*!< Channel 4 Transfer Complete flag */
+#define DMA_ISR_HTIF4 ((uint32_t)0x00004000) /*!< Channel 4 Half Transfer flag */
+#define DMA_ISR_TEIF4 ((uint32_t)0x00008000) /*!< Channel 4 Transfer Error flag */
+#define DMA_ISR_GIF5 ((uint32_t)0x00010000) /*!< Channel 5 Global interrupt flag */
+#define DMA_ISR_TCIF5 ((uint32_t)0x00020000) /*!< Channel 5 Transfer Complete flag */
+#define DMA_ISR_HTIF5 ((uint32_t)0x00040000) /*!< Channel 5 Half Transfer flag */
+#define DMA_ISR_TEIF5 ((uint32_t)0x00080000) /*!< Channel 5 Transfer Error flag */
+#define DMA_ISR_GIF6 ((uint32_t)0x00100000) /*!< Channel 6 Global interrupt flag */
+#define DMA_ISR_TCIF6 ((uint32_t)0x00200000) /*!< Channel 6 Transfer Complete flag */
+#define DMA_ISR_HTIF6 ((uint32_t)0x00400000) /*!< Channel 6 Half Transfer flag */
+#define DMA_ISR_TEIF6 ((uint32_t)0x00800000) /*!< Channel 6 Transfer Error flag */
+#define DMA_ISR_GIF7 ((uint32_t)0x01000000) /*!< Channel 7 Global interrupt flag */
+#define DMA_ISR_TCIF7 ((uint32_t)0x02000000) /*!< Channel 7 Transfer Complete flag */
+#define DMA_ISR_HTIF7 ((uint32_t)0x04000000) /*!< Channel 7 Half Transfer flag */
+#define DMA_ISR_TEIF7 ((uint32_t)0x08000000) /*!< Channel 7 Transfer Error flag */
+
+/******************* Bit definition for DMA_IFCR register *******************/
+#define DMA_IFCR_CGIF1 ((uint32_t)0x00000001) /*!< Channel 1 Global interrupt clearr */
+#define DMA_IFCR_CTCIF1 ((uint32_t)0x00000002) /*!< Channel 1 Transfer Complete clear */
+#define DMA_IFCR_CHTIF1 ((uint32_t)0x00000004) /*!< Channel 1 Half Transfer clear */
+#define DMA_IFCR_CTEIF1 ((uint32_t)0x00000008) /*!< Channel 1 Transfer Error clear */
+#define DMA_IFCR_CGIF2 ((uint32_t)0x00000010) /*!< Channel 2 Global interrupt clear */
+#define DMA_IFCR_CTCIF2 ((uint32_t)0x00000020) /*!< Channel 2 Transfer Complete clear */
+#define DMA_IFCR_CHTIF2 ((uint32_t)0x00000040) /*!< Channel 2 Half Transfer clear */
+#define DMA_IFCR_CTEIF2 ((uint32_t)0x00000080) /*!< Channel 2 Transfer Error clear */
+#define DMA_IFCR_CGIF3 ((uint32_t)0x00000100) /*!< Channel 3 Global interrupt clear */
+#define DMA_IFCR_CTCIF3 ((uint32_t)0x00000200) /*!< Channel 3 Transfer Complete clear */
+#define DMA_IFCR_CHTIF3 ((uint32_t)0x00000400) /*!< Channel 3 Half Transfer clear */
+#define DMA_IFCR_CTEIF3 ((uint32_t)0x00000800) /*!< Channel 3 Transfer Error clear */
+#define DMA_IFCR_CGIF4 ((uint32_t)0x00001000) /*!< Channel 4 Global interrupt clear */
+#define DMA_IFCR_CTCIF4 ((uint32_t)0x00002000) /*!< Channel 4 Transfer Complete clear */
+#define DMA_IFCR_CHTIF4 ((uint32_t)0x00004000) /*!< Channel 4 Half Transfer clear */
+#define DMA_IFCR_CTEIF4 ((uint32_t)0x00008000) /*!< Channel 4 Transfer Error clear */
+#define DMA_IFCR_CGIF5 ((uint32_t)0x00010000) /*!< Channel 5 Global interrupt clear */
+#define DMA_IFCR_CTCIF5 ((uint32_t)0x00020000) /*!< Channel 5 Transfer Complete clear */
+#define DMA_IFCR_CHTIF5 ((uint32_t)0x00040000) /*!< Channel 5 Half Transfer clear */
+#define DMA_IFCR_CTEIF5 ((uint32_t)0x00080000) /*!< Channel 5 Transfer Error clear */
+#define DMA_IFCR_CGIF6 ((uint32_t)0x00100000) /*!< Channel 6 Global interrupt clear */
+#define DMA_IFCR_CTCIF6 ((uint32_t)0x00200000) /*!< Channel 6 Transfer Complete clear */
+#define DMA_IFCR_CHTIF6 ((uint32_t)0x00400000) /*!< Channel 6 Half Transfer clear */
+#define DMA_IFCR_CTEIF6 ((uint32_t)0x00800000) /*!< Channel 6 Transfer Error clear */
+#define DMA_IFCR_CGIF7 ((uint32_t)0x01000000) /*!< Channel 7 Global interrupt clear */
+#define DMA_IFCR_CTCIF7 ((uint32_t)0x02000000) /*!< Channel 7 Transfer Complete clear */
+#define DMA_IFCR_CHTIF7 ((uint32_t)0x04000000) /*!< Channel 7 Half Transfer clear */
+#define DMA_IFCR_CTEIF7 ((uint32_t)0x08000000) /*!< Channel 7 Transfer Error clear */
+
+/******************* Bit definition for DMA_CCR1 register *******************/
+#define DMA_CCR1_EN ((uint16_t)0x0001) /*!< Channel enable*/
+#define DMA_CCR1_TCIE ((uint16_t)0x0002) /*!< Transfer complete interrupt enable */
+#define DMA_CCR1_HTIE ((uint16_t)0x0004) /*!< Half Transfer interrupt enable */
+#define DMA_CCR1_TEIE ((uint16_t)0x0008) /*!< Transfer error interrupt enable */
+#define DMA_CCR1_DIR ((uint16_t)0x0010) /*!< Data transfer direction */
+#define DMA_CCR1_CIRC ((uint16_t)0x0020) /*!< Circular mode */
+#define DMA_CCR1_PINC ((uint16_t)0x0040) /*!< Peripheral increment mode */
+#define DMA_CCR1_MINC ((uint16_t)0x0080) /*!< Memory increment mode */
+
+#define DMA_CCR1_PSIZE ((uint16_t)0x0300) /*!< PSIZE[1:0] bits (Peripheral size) */
+#define DMA_CCR1_PSIZE_0 ((uint16_t)0x0100) /*!< Bit 0 */
+#define DMA_CCR1_PSIZE_1 ((uint16_t)0x0200) /*!< Bit 1 */
+
+#define DMA_CCR1_MSIZE ((uint16_t)0x0C00) /*!< MSIZE[1:0] bits (Memory size) */
+#define DMA_CCR1_MSIZE_0 ((uint16_t)0x0400) /*!< Bit 0 */
+#define DMA_CCR1_MSIZE_1 ((uint16_t)0x0800) /*!< Bit 1 */
+
+#define DMA_CCR1_PL ((uint16_t)0x3000) /*!< PL[1:0] bits(Channel Priority level) */
+#define DMA_CCR1_PL_0 ((uint16_t)0x1000) /*!< Bit 0 */
+#define DMA_CCR1_PL_1 ((uint16_t)0x2000) /*!< Bit 1 */
+
+#define DMA_CCR1_MEM2MEM ((uint16_t)0x4000) /*!< Memory to memory mode */
+
+/******************* Bit definition for DMA_CCR2 register *******************/
+#define DMA_CCR2_EN ((uint16_t)0x0001) /*!< Channel enable */
+#define DMA_CCR2_TCIE ((uint16_t)0x0002) /*!< ransfer complete interrupt enable */
+#define DMA_CCR2_HTIE ((uint16_t)0x0004) /*!< Half Transfer interrupt enable */
+#define DMA_CCR2_TEIE ((uint16_t)0x0008) /*!< Transfer error interrupt enable */
+#define DMA_CCR2_DIR ((uint16_t)0x0010) /*!< Data transfer direction */
+#define DMA_CCR2_CIRC ((uint16_t)0x0020) /*!< Circular mode */
+#define DMA_CCR2_PINC ((uint16_t)0x0040) /*!< Peripheral increment mode */
+#define DMA_CCR2_MINC ((uint16_t)0x0080) /*!< Memory increment mode */
+
+#define DMA_CCR2_PSIZE ((uint16_t)0x0300) /*!< PSIZE[1:0] bits (Peripheral size) */
+#define DMA_CCR2_PSIZE_0 ((uint16_t)0x0100) /*!< Bit 0 */
+#define DMA_CCR2_PSIZE_1 ((uint16_t)0x0200) /*!< Bit 1 */
+
+#define DMA_CCR2_MSIZE ((uint16_t)0x0C00) /*!< MSIZE[1:0] bits (Memory size) */
+#define DMA_CCR2_MSIZE_0 ((uint16_t)0x0400) /*!< Bit 0 */
+#define DMA_CCR2_MSIZE_1 ((uint16_t)0x0800) /*!< Bit 1 */
+
+#define DMA_CCR2_PL ((uint16_t)0x3000) /*!< PL[1:0] bits (Channel Priority level) */
+#define DMA_CCR2_PL_0 ((uint16_t)0x1000) /*!< Bit 0 */
+#define DMA_CCR2_PL_1 ((uint16_t)0x2000) /*!< Bit 1 */
+
+#define DMA_CCR2_MEM2MEM ((uint16_t)0x4000) /*!< Memory to memory mode */
+
+/******************* Bit definition for DMA_CCR3 register *******************/
+#define DMA_CCR3_EN ((uint16_t)0x0001) /*!< Channel enable */
+#define DMA_CCR3_TCIE ((uint16_t)0x0002) /*!< Transfer complete interrupt enable */
+#define DMA_CCR3_HTIE ((uint16_t)0x0004) /*!< Half Transfer interrupt enable */
+#define DMA_CCR3_TEIE ((uint16_t)0x0008) /*!< Transfer error interrupt enable */
+#define DMA_CCR3_DIR ((uint16_t)0x0010) /*!< Data transfer direction */
+#define DMA_CCR3_CIRC ((uint16_t)0x0020) /*!< Circular mode */
+#define DMA_CCR3_PINC ((uint16_t)0x0040) /*!< Peripheral increment mode */
+#define DMA_CCR3_MINC ((uint16_t)0x0080) /*!< Memory increment mode */
+
+#define DMA_CCR3_PSIZE ((uint16_t)0x0300) /*!< PSIZE[1:0] bits (Peripheral size) */
+#define DMA_CCR3_PSIZE_0 ((uint16_t)0x0100) /*!< Bit 0 */
+#define DMA_CCR3_PSIZE_1 ((uint16_t)0x0200) /*!< Bit 1 */
+
+#define DMA_CCR3_MSIZE ((uint16_t)0x0C00) /*!< MSIZE[1:0] bits (Memory size) */
+#define DMA_CCR3_MSIZE_0 ((uint16_t)0x0400) /*!< Bit 0 */
+#define DMA_CCR3_MSIZE_1 ((uint16_t)0x0800) /*!< Bit 1 */
+
+#define DMA_CCR3_PL ((uint16_t)0x3000) /*!< PL[1:0] bits (Channel Priority level) */
+#define DMA_CCR3_PL_0 ((uint16_t)0x1000) /*!< Bit 0 */
+#define DMA_CCR3_PL_1 ((uint16_t)0x2000) /*!< Bit 1 */
+
+#define DMA_CCR3_MEM2MEM ((uint16_t)0x4000) /*!< Memory to memory mode */
+
+/*!<****************** Bit definition for DMA_CCR4 register *******************/
+#define DMA_CCR4_EN ((uint16_t)0x0001) /*!<Channel enable */
+#define DMA_CCR4_TCIE ((uint16_t)0x0002) /*!<Transfer complete interrupt enable */
+#define DMA_CCR4_HTIE ((uint16_t)0x0004) /*!<Half Transfer interrupt enable */
+#define DMA_CCR4_TEIE ((uint16_t)0x0008) /*!<Transfer error interrupt enable */
+#define DMA_CCR4_DIR ((uint16_t)0x0010) /*!<Data transfer direction */
+#define DMA_CCR4_CIRC ((uint16_t)0x0020) /*!<Circular mode */
+#define DMA_CCR4_PINC ((uint16_t)0x0040) /*!<Peripheral increment mode */
+#define DMA_CCR4_MINC ((uint16_t)0x0080) /*!<Memory increment mode */
+
+#define DMA_CCR4_PSIZE ((uint16_t)0x0300) /*!<PSIZE[1:0] bits (Peripheral size) */
+#define DMA_CCR4_PSIZE_0 ((uint16_t)0x0100) /*!<Bit 0 */
+#define DMA_CCR4_PSIZE_1 ((uint16_t)0x0200) /*!<Bit 1 */
+
+#define DMA_CCR4_MSIZE ((uint16_t)0x0C00) /*!<MSIZE[1:0] bits (Memory size) */
+#define DMA_CCR4_MSIZE_0 ((uint16_t)0x0400) /*!<Bit 0 */
+#define DMA_CCR4_MSIZE_1 ((uint16_t)0x0800) /*!<Bit 1 */
+
+#define DMA_CCR4_PL ((uint16_t)0x3000) /*!<PL[1:0] bits (Channel Priority level) */
+#define DMA_CCR4_PL_0 ((uint16_t)0x1000) /*!<Bit 0 */
+#define DMA_CCR4_PL_1 ((uint16_t)0x2000) /*!<Bit 1 */
+
+#define DMA_CCR4_MEM2MEM ((uint16_t)0x4000) /*!<Memory to memory mode */
+
+/****************** Bit definition for DMA_CCR5 register *******************/
+#define DMA_CCR5_EN ((uint16_t)0x0001) /*!<Channel enable */
+#define DMA_CCR5_TCIE ((uint16_t)0x0002) /*!<Transfer complete interrupt enable */
+#define DMA_CCR5_HTIE ((uint16_t)0x0004) /*!<Half Transfer interrupt enable */
+#define DMA_CCR5_TEIE ((uint16_t)0x0008) /*!<Transfer error interrupt enable */
+#define DMA_CCR5_DIR ((uint16_t)0x0010) /*!<Data transfer direction */
+#define DMA_CCR5_CIRC ((uint16_t)0x0020) /*!<Circular mode */
+#define DMA_CCR5_PINC ((uint16_t)0x0040) /*!<Peripheral increment mode */
+#define DMA_CCR5_MINC ((uint16_t)0x0080) /*!<Memory increment mode */
+
+#define DMA_CCR5_PSIZE ((uint16_t)0x0300) /*!<PSIZE[1:0] bits (Peripheral size) */
+#define DMA_CCR5_PSIZE_0 ((uint16_t)0x0100) /*!<Bit 0 */
+#define DMA_CCR5_PSIZE_1 ((uint16_t)0x0200) /*!<Bit 1 */
+
+#define DMA_CCR5_MSIZE ((uint16_t)0x0C00) /*!<MSIZE[1:0] bits (Memory size) */
+#define DMA_CCR5_MSIZE_0 ((uint16_t)0x0400) /*!<Bit 0 */
+#define DMA_CCR5_MSIZE_1 ((uint16_t)0x0800) /*!<Bit 1 */
+
+#define DMA_CCR5_PL ((uint16_t)0x3000) /*!<PL[1:0] bits (Channel Priority level) */
+#define DMA_CCR5_PL_0 ((uint16_t)0x1000) /*!<Bit 0 */
+#define DMA_CCR5_PL_1 ((uint16_t)0x2000) /*!<Bit 1 */
+
+#define DMA_CCR5_MEM2MEM ((uint16_t)0x4000) /*!<Memory to memory mode enable */
+
+/******************* Bit definition for DMA_CCR6 register *******************/
+#define DMA_CCR6_EN ((uint16_t)0x0001) /*!<Channel enable */
+#define DMA_CCR6_TCIE ((uint16_t)0x0002) /*!<Transfer complete interrupt enable */
+#define DMA_CCR6_HTIE ((uint16_t)0x0004) /*!<Half Transfer interrupt enable */
+#define DMA_CCR6_TEIE ((uint16_t)0x0008) /*!<Transfer error interrupt enable */
+#define DMA_CCR6_DIR ((uint16_t)0x0010) /*!<Data transfer direction */
+#define DMA_CCR6_CIRC ((uint16_t)0x0020) /*!<Circular mode */
+#define DMA_CCR6_PINC ((uint16_t)0x0040) /*!<Peripheral increment mode */
+#define DMA_CCR6_MINC ((uint16_t)0x0080) /*!<Memory increment mode */
+
+#define DMA_CCR6_PSIZE ((uint16_t)0x0300) /*!<PSIZE[1:0] bits (Peripheral size) */
+#define DMA_CCR6_PSIZE_0 ((uint16_t)0x0100) /*!<Bit 0 */
+#define DMA_CCR6_PSIZE_1 ((uint16_t)0x0200) /*!<Bit 1 */
+
+#define DMA_CCR6_MSIZE ((uint16_t)0x0C00) /*!<MSIZE[1:0] bits (Memory size) */
+#define DMA_CCR6_MSIZE_0 ((uint16_t)0x0400) /*!<Bit 0 */
+#define DMA_CCR6_MSIZE_1 ((uint16_t)0x0800) /*!<Bit 1 */
+
+#define DMA_CCR6_PL ((uint16_t)0x3000) /*!<PL[1:0] bits (Channel Priority level) */
+#define DMA_CCR6_PL_0 ((uint16_t)0x1000) /*!<Bit 0 */
+#define DMA_CCR6_PL_1 ((uint16_t)0x2000) /*!<Bit 1 */
+
+#define DMA_CCR6_MEM2MEM ((uint16_t)0x4000) /*!<Memory to memory mode */
+
+/******************* Bit definition for DMA_CCR7 register *******************/
+#define DMA_CCR7_EN ((uint16_t)0x0001) /*!<Channel enable */
+#define DMA_CCR7_TCIE ((uint16_t)0x0002) /*!<Transfer complete interrupt enable */
+#define DMA_CCR7_HTIE ((uint16_t)0x0004) /*!<Half Transfer interrupt enable */
+#define DMA_CCR7_TEIE ((uint16_t)0x0008) /*!<Transfer error interrupt enable */
+#define DMA_CCR7_DIR ((uint16_t)0x0010) /*!<Data transfer direction */
+#define DMA_CCR7_CIRC ((uint16_t)0x0020) /*!<Circular mode */
+#define DMA_CCR7_PINC ((uint16_t)0x0040) /*!<Peripheral increment mode */
+#define DMA_CCR7_MINC ((uint16_t)0x0080) /*!<Memory increment mode */
+
+#define DMA_CCR7_PSIZE , ((uint16_t)0x0300) /*!<PSIZE[1:0] bits (Peripheral size) */
+#define DMA_CCR7_PSIZE_0 ((uint16_t)0x0100) /*!<Bit 0 */
+#define DMA_CCR7_PSIZE_1 ((uint16_t)0x0200) /*!<Bit 1 */
+
+#define DMA_CCR7_MSIZE ((uint16_t)0x0C00) /*!<MSIZE[1:0] bits (Memory size) */
+#define DMA_CCR7_MSIZE_0 ((uint16_t)0x0400) /*!<Bit 0 */
+#define DMA_CCR7_MSIZE_1 ((uint16_t)0x0800) /*!<Bit 1 */
+
+#define DMA_CCR7_PL ((uint16_t)0x3000) /*!<PL[1:0] bits (Channel Priority level) */
+#define DMA_CCR7_PL_0 ((uint16_t)0x1000) /*!<Bit 0 */
+#define DMA_CCR7_PL_1 ((uint16_t)0x2000) /*!<Bit 1 */
+
+#define DMA_CCR7_MEM2MEM ((uint16_t)0x4000) /*!<Memory to memory mode enable */
+
+/****************** Bit definition for DMA_CNDTR1 register ******************/
+#define DMA_CNDTR1_NDT ((uint16_t)0xFFFF) /*!<Number of data to Transfer */
+
+/****************** Bit definition for DMA_CNDTR2 register ******************/
+#define DMA_CNDTR2_NDT ((uint16_t)0xFFFF) /*!<Number of data to Transfer */
+
+/****************** Bit definition for DMA_CNDTR3 register ******************/
+#define DMA_CNDTR3_NDT ((uint16_t)0xFFFF) /*!<Number of data to Transfer */
+
+/****************** Bit definition for DMA_CNDTR4 register ******************/
+#define DMA_CNDTR4_NDT ((uint16_t)0xFFFF) /*!<Number of data to Transfer */
+
+/****************** Bit definition for DMA_CNDTR5 register ******************/
+#define DMA_CNDTR5_NDT ((uint16_t)0xFFFF) /*!<Number of data to Transfer */
+
+/****************** Bit definition for DMA_CNDTR6 register ******************/
+#define DMA_CNDTR6_NDT ((uint16_t)0xFFFF) /*!<Number of data to Transfer */
+
+/****************** Bit definition for DMA_CNDTR7 register ******************/
+#define DMA_CNDTR7_NDT ((uint16_t)0xFFFF) /*!<Number of data to Transfer */
+
+/****************** Bit definition for DMA_CPAR1 register *******************/
+#define DMA_CPAR1_PA ((uint32_t)0xFFFFFFFF) /*!<Peripheral Address */
+
+/****************** Bit definition for DMA_CPAR2 register *******************/
+#define DMA_CPAR2_PA ((uint32_t)0xFFFFFFFF) /*!<Peripheral Address */
+
+/****************** Bit definition for DMA_CPAR3 register *******************/
+#define DMA_CPAR3_PA ((uint32_t)0xFFFFFFFF) /*!<Peripheral Address */
+
+
+/****************** Bit definition for DMA_CPAR4 register *******************/
+#define DMA_CPAR4_PA ((uint32_t)0xFFFFFFFF) /*!<Peripheral Address */
+
+/****************** Bit definition for DMA_CPAR5 register *******************/
+#define DMA_CPAR5_PA ((uint32_t)0xFFFFFFFF) /*!<Peripheral Address */
+
+/****************** Bit definition for DMA_CPAR6 register *******************/
+#define DMA_CPAR6_PA ((uint32_t)0xFFFFFFFF) /*!<Peripheral Address */
+
+
+/****************** Bit definition for DMA_CPAR7 register *******************/
+#define DMA_CPAR7_PA ((uint32_t)0xFFFFFFFF) /*!<Peripheral Address */
+
+/****************** Bit definition for DMA_CMAR1 register *******************/
+#define DMA_CMAR1_MA ((uint32_t)0xFFFFFFFF) /*!<Memory Address */
+
+/****************** Bit definition for DMA_CMAR2 register *******************/
+#define DMA_CMAR2_MA ((uint32_t)0xFFFFFFFF) /*!<Memory Address */
+
+/****************** Bit definition for DMA_CMAR3 register *******************/
+#define DMA_CMAR3_MA ((uint32_t)0xFFFFFFFF) /*!<Memory Address */
+
+
+/****************** Bit definition for DMA_CMAR4 register *******************/
+#define DMA_CMAR4_MA ((uint32_t)0xFFFFFFFF) /*!<Memory Address */
+
+/****************** Bit definition for DMA_CMAR5 register *******************/
+#define DMA_CMAR5_MA ((uint32_t)0xFFFFFFFF) /*!<Memory Address */
+
+/****************** Bit definition for DMA_CMAR6 register *******************/
+#define DMA_CMAR6_MA ((uint32_t)0xFFFFFFFF) /*!<Memory Address */
+
+/****************** Bit definition for DMA_CMAR7 register *******************/
+#define DMA_CMAR7_MA ((uint32_t)0xFFFFFFFF) /*!<Memory Address */
+
+/******************************************************************************/
+/* */
+/* Analog to Digital Converter */
+/* */
+/******************************************************************************/
+
+/******************** Bit definition for ADC_SR register ********************/
+#define ADC_SR_AWD ((uint8_t)0x01) /*!<Analog watchdog flag */
+#define ADC_SR_EOC ((uint8_t)0x02) /*!<End of conversion */
+#define ADC_SR_JEOC ((uint8_t)0x04) /*!<Injected channel end of conversion */
+#define ADC_SR_JSTRT ((uint8_t)0x08) /*!<Injected channel Start flag */
+#define ADC_SR_STRT ((uint8_t)0x10) /*!<Regular channel Start flag */
+
+/******************* Bit definition for ADC_CR1 register ********************/
+#define ADC_CR1_AWDCH ((uint32_t)0x0000001F) /*!<AWDCH[4:0] bits (Analog watchdog channel select bits) */
+#define ADC_CR1_AWDCH_0 ((uint32_t)0x00000001) /*!<Bit 0 */
+#define ADC_CR1_AWDCH_1 ((uint32_t)0x00000002) /*!<Bit 1 */
+#define ADC_CR1_AWDCH_2 ((uint32_t)0x00000004) /*!<Bit 2 */
+#define ADC_CR1_AWDCH_3 ((uint32_t)0x00000008) /*!<Bit 3 */
+#define ADC_CR1_AWDCH_4 ((uint32_t)0x00000010) /*!<Bit 4 */
+
+#define ADC_CR1_EOCIE ((uint32_t)0x00000020) /*!<Interrupt enable for EOC */
+#define ADC_CR1_AWDIE ((uint32_t)0x00000040) /*!<AAnalog Watchdog interrupt enable */
+#define ADC_CR1_JEOCIE ((uint32_t)0x00000080) /*!<Interrupt enable for injected channels */
+#define ADC_CR1_SCAN ((uint32_t)0x00000100) /*!<Scan mode */
+#define ADC_CR1_AWDSGL ((uint32_t)0x00000200) /*!<Enable the watchdog on a single channel in scan mode */
+#define ADC_CR1_JAUTO ((uint32_t)0x00000400) /*!<Automatic injected group conversion */
+#define ADC_CR1_DISCEN ((uint32_t)0x00000800) /*!<Discontinuous mode on regular channels */
+#define ADC_CR1_JDISCEN ((uint32_t)0x00001000) /*!<Discontinuous mode on injected channels */
+
+#define ADC_CR1_DISCNUM ((uint32_t)0x0000E000) /*!<DISCNUM[2:0] bits (Discontinuous mode channel count) */
+#define ADC_CR1_DISCNUM_0 ((uint32_t)0x00002000) /*!<Bit 0 */
+#define ADC_CR1_DISCNUM_1 ((uint32_t)0x00004000) /*!<Bit 1 */
+#define ADC_CR1_DISCNUM_2 ((uint32_t)0x00008000) /*!<Bit 2 */
+
+#define ADC_CR1_DUALMOD ((uint32_t)0x000F0000) /*!<DUALMOD[3:0] bits (Dual mode selection) */
+#define ADC_CR1_DUALMOD_0 ((uint32_t)0x00010000) /*!<Bit 0 */
+#define ADC_CR1_DUALMOD_1 ((uint32_t)0x00020000) /*!<Bit 1 */
+#define ADC_CR1_DUALMOD_2 ((uint32_t)0x00040000) /*!<Bit 2 */
+#define ADC_CR1_DUALMOD_3 ((uint32_t)0x00080000) /*!<Bit 3 */
+
+#define ADC_CR1_JAWDEN ((uint32_t)0x00400000) /*!<Analog watchdog enable on injected channels */
+#define ADC_CR1_AWDEN ((uint32_t)0x00800000) /*!<Analog watchdog enable on regular channels */
+
+
+/******************* Bit definition for ADC_CR2 register ********************/
+#define ADC_CR2_ADON ((uint32_t)0x00000001) /*!<A/D Converter ON / OFF */
+#define ADC_CR2_CONT ((uint32_t)0x00000002) /*!<Continuous Conversion */
+#define ADC_CR2_CAL ((uint32_t)0x00000004) /*!<A/D Calibration */
+#define ADC_CR2_RSTCAL ((uint32_t)0x00000008) /*!<Reset Calibration */
+#define ADC_CR2_DMA ((uint32_t)0x00000100) /*!<Direct Memory access mode */
+#define ADC_CR2_ALIGN ((uint32_t)0x00000800) /*!<Data Alignment */
+
+#define ADC_CR2_JEXTSEL ((uint32_t)0x00007000) /*!<JEXTSEL[2:0] bits (External event select for injected group) */
+#define ADC_CR2_JEXTSEL_0 ((uint32_t)0x00001000) /*!<Bit 0 */
+#define ADC_CR2_JEXTSEL_1 ((uint32_t)0x00002000) /*!<Bit 1 */
+#define ADC_CR2_JEXTSEL_2 ((uint32_t)0x00004000) /*!<Bit 2 */
+
+#define ADC_CR2_JEXTTRIG ((uint32_t)0x00008000) /*!<External Trigger Conversion mode for injected channels */
+
+#define ADC_CR2_EXTSEL ((uint32_t)0x000E0000) /*!<EXTSEL[2:0] bits (External Event Select for regular group) */
+#define ADC_CR2_EXTSEL_0 ((uint32_t)0x00020000) /*!<Bit 0 */
+#define ADC_CR2_EXTSEL_1 ((uint32_t)0x00040000) /*!<Bit 1 */
+#define ADC_CR2_EXTSEL_2 ((uint32_t)0x00080000) /*!<Bit 2 */
+
+#define ADC_CR2_EXTTRIG ((uint32_t)0x00100000) /*!<External Trigger Conversion mode for regular channels */
+#define ADC_CR2_JSWSTART ((uint32_t)0x00200000) /*!<Start Conversion of injected channels */
+#define ADC_CR2_SWSTART ((uint32_t)0x00400000) /*!<Start Conversion of regular channels */
+#define ADC_CR2_TSVREFE ((uint32_t)0x00800000) /*!<Temperature Sensor and VREFINT Enable */
+
+/****************** Bit definition for ADC_SMPR1 register *******************/
+#define ADC_SMPR1_SMP10 ((uint32_t)0x00000007) /*!<SMP10[2:0] bits (Channel 10 Sample time selection) */
+#define ADC_SMPR1_SMP10_0 ((uint32_t)0x00000001) /*!<Bit 0 */
+#define ADC_SMPR1_SMP10_1 ((uint32_t)0x00000002) /*!<Bit 1 */
+#define ADC_SMPR1_SMP10_2 ((uint32_t)0x00000004) /*!<Bit 2 */
+
+#define ADC_SMPR1_SMP11 ((uint32_t)0x00000038) /*!<SMP11[2:0] bits (Channel 11 Sample time selection) */
+#define ADC_SMPR1_SMP11_0 ((uint32_t)0x00000008) /*!<Bit 0 */
+#define ADC_SMPR1_SMP11_1 ((uint32_t)0x00000010) /*!<Bit 1 */
+#define ADC_SMPR1_SMP11_2 ((uint32_t)0x00000020) /*!<Bit 2 */
+
+#define ADC_SMPR1_SMP12 ((uint32_t)0x000001C0) /*!<SMP12[2:0] bits (Channel 12 Sample time selection) */
+#define ADC_SMPR1_SMP12_0 ((uint32_t)0x00000040) /*!<Bit 0 */
+#define ADC_SMPR1_SMP12_1 ((uint32_t)0x00000080) /*!<Bit 1 */
+#define ADC_SMPR1_SMP12_2 ((uint32_t)0x00000100) /*!<Bit 2 */
+
+#define ADC_SMPR1_SMP13 ((uint32_t)0x00000E00) /*!<SMP13[2:0] bits (Channel 13 Sample time selection) */
+#define ADC_SMPR1_SMP13_0 ((uint32_t)0x00000200) /*!<Bit 0 */
+#define ADC_SMPR1_SMP13_1 ((uint32_t)0x00000400) /*!<Bit 1 */
+#define ADC_SMPR1_SMP13_2 ((uint32_t)0x00000800) /*!<Bit 2 */
+
+#define ADC_SMPR1_SMP14 ((uint32_t)0x00007000) /*!<SMP14[2:0] bits (Channel 14 Sample time selection) */
+#define ADC_SMPR1_SMP14_0 ((uint32_t)0x00001000) /*!<Bit 0 */
+#define ADC_SMPR1_SMP14_1 ((uint32_t)0x00002000) /*!<Bit 1 */
+#define ADC_SMPR1_SMP14_2 ((uint32_t)0x00004000) /*!<Bit 2 */
+
+#define ADC_SMPR1_SMP15 ((uint32_t)0x00038000) /*!<SMP15[2:0] bits (Channel 15 Sample time selection) */
+#define ADC_SMPR1_SMP15_0 ((uint32_t)0x00008000) /*!<Bit 0 */
+#define ADC_SMPR1_SMP15_1 ((uint32_t)0x00010000) /*!<Bit 1 */
+#define ADC_SMPR1_SMP15_2 ((uint32_t)0x00020000) /*!<Bit 2 */
+
+#define ADC_SMPR1_SMP16 ((uint32_t)0x001C0000) /*!<SMP16[2:0] bits (Channel 16 Sample time selection) */
+#define ADC_SMPR1_SMP16_0 ((uint32_t)0x00040000) /*!<Bit 0 */
+#define ADC_SMPR1_SMP16_1 ((uint32_t)0x00080000) /*!<Bit 1 */
+#define ADC_SMPR1_SMP16_2 ((uint32_t)0x00100000) /*!<Bit 2 */
+
+#define ADC_SMPR1_SMP17 ((uint32_t)0x00E00000) /*!<SMP17[2:0] bits (Channel 17 Sample time selection) */
+#define ADC_SMPR1_SMP17_0 ((uint32_t)0x00200000) /*!<Bit 0 */
+#define ADC_SMPR1_SMP17_1 ((uint32_t)0x00400000) /*!<Bit 1 */
+#define ADC_SMPR1_SMP17_2 ((uint32_t)0x00800000) /*!<Bit 2 */
+
+/****************** Bit definition for ADC_SMPR2 register *******************/
+#define ADC_SMPR2_SMP0 ((uint32_t)0x00000007) /*!<SMP0[2:0] bits (Channel 0 Sample time selection) */
+#define ADC_SMPR2_SMP0_0 ((uint32_t)0x00000001) /*!<Bit 0 */
+#define ADC_SMPR2_SMP0_1 ((uint32_t)0x00000002) /*!<Bit 1 */
+#define ADC_SMPR2_SMP0_2 ((uint32_t)0x00000004) /*!<Bit 2 */
+
+#define ADC_SMPR2_SMP1 ((uint32_t)0x00000038) /*!<SMP1[2:0] bits (Channel 1 Sample time selection) */
+#define ADC_SMPR2_SMP1_0 ((uint32_t)0x00000008) /*!<Bit 0 */
+#define ADC_SMPR2_SMP1_1 ((uint32_t)0x00000010) /*!<Bit 1 */
+#define ADC_SMPR2_SMP1_2 ((uint32_t)0x00000020) /*!<Bit 2 */
+
+#define ADC_SMPR2_SMP2 ((uint32_t)0x000001C0) /*!<SMP2[2:0] bits (Channel 2 Sample time selection) */
+#define ADC_SMPR2_SMP2_0 ((uint32_t)0x00000040) /*!<Bit 0 */
+#define ADC_SMPR2_SMP2_1 ((uint32_t)0x00000080) /*!<Bit 1 */
+#define ADC_SMPR2_SMP2_2 ((uint32_t)0x00000100) /*!<Bit 2 */
+
+#define ADC_SMPR2_SMP3 ((uint32_t)0x00000E00) /*!<SMP3[2:0] bits (Channel 3 Sample time selection) */
+#define ADC_SMPR2_SMP3_0 ((uint32_t)0x00000200) /*!<Bit 0 */
+#define ADC_SMPR2_SMP3_1 ((uint32_t)0x00000400) /*!<Bit 1 */
+#define ADC_SMPR2_SMP3_2 ((uint32_t)0x00000800) /*!<Bit 2 */
+
+#define ADC_SMPR2_SMP4 ((uint32_t)0x00007000) /*!<SMP4[2:0] bits (Channel 4 Sample time selection) */
+#define ADC_SMPR2_SMP4_0 ((uint32_t)0x00001000) /*!<Bit 0 */
+#define ADC_SMPR2_SMP4_1 ((uint32_t)0x00002000) /*!<Bit 1 */
+#define ADC_SMPR2_SMP4_2 ((uint32_t)0x00004000) /*!<Bit 2 */
+
+#define ADC_SMPR2_SMP5 ((uint32_t)0x00038000) /*!<SMP5[2:0] bits (Channel 5 Sample time selection) */
+#define ADC_SMPR2_SMP5_0 ((uint32_t)0x00008000) /*!<Bit 0 */
+#define ADC_SMPR2_SMP5_1 ((uint32_t)0x00010000) /*!<Bit 1 */
+#define ADC_SMPR2_SMP5_2 ((uint32_t)0x00020000) /*!<Bit 2 */
+
+#define ADC_SMPR2_SMP6 ((uint32_t)0x001C0000) /*!<SMP6[2:0] bits (Channel 6 Sample time selection) */
+#define ADC_SMPR2_SMP6_0 ((uint32_t)0x00040000) /*!<Bit 0 */
+#define ADC_SMPR2_SMP6_1 ((uint32_t)0x00080000) /*!<Bit 1 */
+#define ADC_SMPR2_SMP6_2 ((uint32_t)0x00100000) /*!<Bit 2 */
+
+#define ADC_SMPR2_SMP7 ((uint32_t)0x00E00000) /*!<SMP7[2:0] bits (Channel 7 Sample time selection) */
+#define ADC_SMPR2_SMP7_0 ((uint32_t)0x00200000) /*!<Bit 0 */
+#define ADC_SMPR2_SMP7_1 ((uint32_t)0x00400000) /*!<Bit 1 */
+#define ADC_SMPR2_SMP7_2 ((uint32_t)0x00800000) /*!<Bit 2 */
+
+#define ADC_SMPR2_SMP8 ((uint32_t)0x07000000) /*!<SMP8[2:0] bits (Channel 8 Sample time selection) */
+#define ADC_SMPR2_SMP8_0 ((uint32_t)0x01000000) /*!<Bit 0 */
+#define ADC_SMPR2_SMP8_1 ((uint32_t)0x02000000) /*!<Bit 1 */
+#define ADC_SMPR2_SMP8_2 ((uint32_t)0x04000000) /*!<Bit 2 */
+
+#define ADC_SMPR2_SMP9 ((uint32_t)0x38000000) /*!<SMP9[2:0] bits (Channel 9 Sample time selection) */
+#define ADC_SMPR2_SMP9_0 ((uint32_t)0x08000000) /*!<Bit 0 */
+#define ADC_SMPR2_SMP9_1 ((uint32_t)0x10000000) /*!<Bit 1 */
+#define ADC_SMPR2_SMP9_2 ((uint32_t)0x20000000) /*!<Bit 2 */
+
+/****************** Bit definition for ADC_JOFR1 register *******************/
+#define ADC_JOFR1_JOFFSET1 ((uint16_t)0x0FFF) /*!<Data offset for injected channel 1 */
+
+/****************** Bit definition for ADC_JOFR2 register *******************/
+#define ADC_JOFR2_JOFFSET2 ((uint16_t)0x0FFF) /*!<Data offset for injected channel 2 */
+
+/****************** Bit definition for ADC_JOFR3 register *******************/
+#define ADC_JOFR3_JOFFSET3 ((uint16_t)0x0FFF) /*!<Data offset for injected channel 3 */
+
+/****************** Bit definition for ADC_JOFR4 register *******************/
+#define ADC_JOFR4_JOFFSET4 ((uint16_t)0x0FFF) /*!<Data offset for injected channel 4 */
+
+/******************* Bit definition for ADC_HTR register ********************/
+#define ADC_HTR_HT ((uint16_t)0x0FFF) /*!<Analog watchdog high threshold */
+
+/******************* Bit definition for ADC_LTR register ********************/
+#define ADC_LTR_LT ((uint16_t)0x0FFF) /*!<Analog watchdog low threshold */
+
+/******************* Bit definition for ADC_SQR1 register *******************/
+#define ADC_SQR1_SQ13 ((uint32_t)0x0000001F) /*!<SQ13[4:0] bits (13th conversion in regular sequence) */
+#define ADC_SQR1_SQ13_0 ((uint32_t)0x00000001) /*!<Bit 0 */
+#define ADC_SQR1_SQ13_1 ((uint32_t)0x00000002) /*!<Bit 1 */
+#define ADC_SQR1_SQ13_2 ((uint32_t)0x00000004) /*!<Bit 2 */
+#define ADC_SQR1_SQ13_3 ((uint32_t)0x00000008) /*!<Bit 3 */
+#define ADC_SQR1_SQ13_4 ((uint32_t)0x00000010) /*!<Bit 4 */
+
+#define ADC_SQR1_SQ14 ((uint32_t)0x000003E0) /*!<SQ14[4:0] bits (14th conversion in regular sequence) */
+#define ADC_SQR1_SQ14_0 ((uint32_t)0x00000020) /*!<Bit 0 */
+#define ADC_SQR1_SQ14_1 ((uint32_t)0x00000040) /*!<Bit 1 */
+#define ADC_SQR1_SQ14_2 ((uint32_t)0x00000080) /*!<Bit 2 */
+#define ADC_SQR1_SQ14_3 ((uint32_t)0x00000100) /*!<Bit 3 */
+#define ADC_SQR1_SQ14_4 ((uint32_t)0x00000200) /*!<Bit 4 */
+
+#define ADC_SQR1_SQ15 ((uint32_t)0x00007C00) /*!<SQ15[4:0] bits (15th conversion in regular sequence) */
+#define ADC_SQR1_SQ15_0 ((uint32_t)0x00000400) /*!<Bit 0 */
+#define ADC_SQR1_SQ15_1 ((uint32_t)0x00000800) /*!<Bit 1 */
+#define ADC_SQR1_SQ15_2 ((uint32_t)0x00001000) /*!<Bit 2 */
+#define ADC_SQR1_SQ15_3 ((uint32_t)0x00002000) /*!<Bit 3 */
+#define ADC_SQR1_SQ15_4 ((uint32_t)0x00004000) /*!<Bit 4 */
+
+#define ADC_SQR1_SQ16 ((uint32_t)0x000F8000) /*!<SQ16[4:0] bits (16th conversion in regular sequence) */
+#define ADC_SQR1_SQ16_0 ((uint32_t)0x00008000) /*!<Bit 0 */
+#define ADC_SQR1_SQ16_1 ((uint32_t)0x00010000) /*!<Bit 1 */
+#define ADC_SQR1_SQ16_2 ((uint32_t)0x00020000) /*!<Bit 2 */
+#define ADC_SQR1_SQ16_3 ((uint32_t)0x00040000) /*!<Bit 3 */
+#define ADC_SQR1_SQ16_4 ((uint32_t)0x00080000) /*!<Bit 4 */
+
+#define ADC_SQR1_L ((uint32_t)0x00F00000) /*!<L[3:0] bits (Regular channel sequence length) */
+#define ADC_SQR1_L_0 ((uint32_t)0x00100000) /*!<Bit 0 */
+#define ADC_SQR1_L_1 ((uint32_t)0x00200000) /*!<Bit 1 */
+#define ADC_SQR1_L_2 ((uint32_t)0x00400000) /*!<Bit 2 */
+#define ADC_SQR1_L_3 ((uint32_t)0x00800000) /*!<Bit 3 */
+
+/******************* Bit definition for ADC_SQR2 register *******************/
+#define ADC_SQR2_SQ7 ((uint32_t)0x0000001F) /*!<SQ7[4:0] bits (7th conversion in regular sequence) */
+#define ADC_SQR2_SQ7_0 ((uint32_t)0x00000001) /*!<Bit 0 */
+#define ADC_SQR2_SQ7_1 ((uint32_t)0x00000002) /*!<Bit 1 */
+#define ADC_SQR2_SQ7_2 ((uint32_t)0x00000004) /*!<Bit 2 */
+#define ADC_SQR2_SQ7_3 ((uint32_t)0x00000008) /*!<Bit 3 */
+#define ADC_SQR2_SQ7_4 ((uint32_t)0x00000010) /*!<Bit 4 */
+
+#define ADC_SQR2_SQ8 ((uint32_t)0x000003E0) /*!<SQ8[4:0] bits (8th conversion in regular sequence) */
+#define ADC_SQR2_SQ8_0 ((uint32_t)0x00000020) /*!<Bit 0 */
+#define ADC_SQR2_SQ8_1 ((uint32_t)0x00000040) /*!<Bit 1 */
+#define ADC_SQR2_SQ8_2 ((uint32_t)0x00000080) /*!<Bit 2 */
+#define ADC_SQR2_SQ8_3 ((uint32_t)0x00000100) /*!<Bit 3 */
+#define ADC_SQR2_SQ8_4 ((uint32_t)0x00000200) /*!<Bit 4 */
+
+#define ADC_SQR2_SQ9 ((uint32_t)0x00007C00) /*!<SQ9[4:0] bits (9th conversion in regular sequence) */
+#define ADC_SQR2_SQ9_0 ((uint32_t)0x00000400) /*!<Bit 0 */
+#define ADC_SQR2_SQ9_1 ((uint32_t)0x00000800) /*!<Bit 1 */
+#define ADC_SQR2_SQ9_2 ((uint32_t)0x00001000) /*!<Bit 2 */
+#define ADC_SQR2_SQ9_3 ((uint32_t)0x00002000) /*!<Bit 3 */
+#define ADC_SQR2_SQ9_4 ((uint32_t)0x00004000) /*!<Bit 4 */
+
+#define ADC_SQR2_SQ10 ((uint32_t)0x000F8000) /*!<SQ10[4:0] bits (10th conversion in regular sequence) */
+#define ADC_SQR2_SQ10_0 ((uint32_t)0x00008000) /*!<Bit 0 */
+#define ADC_SQR2_SQ10_1 ((uint32_t)0x00010000) /*!<Bit 1 */
+#define ADC_SQR2_SQ10_2 ((uint32_t)0x00020000) /*!<Bit 2 */
+#define ADC_SQR2_SQ10_3 ((uint32_t)0x00040000) /*!<Bit 3 */
+#define ADC_SQR2_SQ10_4 ((uint32_t)0x00080000) /*!<Bit 4 */
+
+#define ADC_SQR2_SQ11 ((uint32_t)0x01F00000) /*!<SQ11[4:0] bits (11th conversion in regular sequence) */
+#define ADC_SQR2_SQ11_0 ((uint32_t)0x00100000) /*!<Bit 0 */
+#define ADC_SQR2_SQ11_1 ((uint32_t)0x00200000) /*!<Bit 1 */
+#define ADC_SQR2_SQ11_2 ((uint32_t)0x00400000) /*!<Bit 2 */
+#define ADC_SQR2_SQ11_3 ((uint32_t)0x00800000) /*!<Bit 3 */
+#define ADC_SQR2_SQ11_4 ((uint32_t)0x01000000) /*!<Bit 4 */
+
+#define ADC_SQR2_SQ12 ((uint32_t)0x3E000000) /*!<SQ12[4:0] bits (12th conversion in regular sequence) */
+#define ADC_SQR2_SQ12_0 ((uint32_t)0x02000000) /*!<Bit 0 */
+#define ADC_SQR2_SQ12_1 ((uint32_t)0x04000000) /*!<Bit 1 */
+#define ADC_SQR2_SQ12_2 ((uint32_t)0x08000000) /*!<Bit 2 */
+#define ADC_SQR2_SQ12_3 ((uint32_t)0x10000000) /*!<Bit 3 */
+#define ADC_SQR2_SQ12_4 ((uint32_t)0x20000000) /*!<Bit 4 */
+
+/******************* Bit definition for ADC_SQR3 register *******************/
+#define ADC_SQR3_SQ1 ((uint32_t)0x0000001F) /*!<SQ1[4:0] bits (1st conversion in regular sequence) */
+#define ADC_SQR3_SQ1_0 ((uint32_t)0x00000001) /*!<Bit 0 */
+#define ADC_SQR3_SQ1_1 ((uint32_t)0x00000002) /*!<Bit 1 */
+#define ADC_SQR3_SQ1_2 ((uint32_t)0x00000004) /*!<Bit 2 */
+#define ADC_SQR3_SQ1_3 ((uint32_t)0x00000008) /*!<Bit 3 */
+#define ADC_SQR3_SQ1_4 ((uint32_t)0x00000010) /*!<Bit 4 */
+
+#define ADC_SQR3_SQ2 ((uint32_t)0x000003E0) /*!<SQ2[4:0] bits (2nd conversion in regular sequence) */
+#define ADC_SQR3_SQ2_0 ((uint32_t)0x00000020) /*!<Bit 0 */
+#define ADC_SQR3_SQ2_1 ((uint32_t)0x00000040) /*!<Bit 1 */
+#define ADC_SQR3_SQ2_2 ((uint32_t)0x00000080) /*!<Bit 2 */
+#define ADC_SQR3_SQ2_3 ((uint32_t)0x00000100) /*!<Bit 3 */
+#define ADC_SQR3_SQ2_4 ((uint32_t)0x00000200) /*!<Bit 4 */
+
+#define ADC_SQR3_SQ3 ((uint32_t)0x00007C00) /*!<SQ3[4:0] bits (3rd conversion in regular sequence) */
+#define ADC_SQR3_SQ3_0 ((uint32_t)0x00000400) /*!<Bit 0 */
+#define ADC_SQR3_SQ3_1 ((uint32_t)0x00000800) /*!<Bit 1 */
+#define ADC_SQR3_SQ3_2 ((uint32_t)0x00001000) /*!<Bit 2 */
+#define ADC_SQR3_SQ3_3 ((uint32_t)0x00002000) /*!<Bit 3 */
+#define ADC_SQR3_SQ3_4 ((uint32_t)0x00004000) /*!<Bit 4 */
+
+#define ADC_SQR3_SQ4 ((uint32_t)0x000F8000) /*!<SQ4[4:0] bits (4th conversion in regular sequence) */
+#define ADC_SQR3_SQ4_0 ((uint32_t)0x00008000) /*!<Bit 0 */
+#define ADC_SQR3_SQ4_1 ((uint32_t)0x00010000) /*!<Bit 1 */
+#define ADC_SQR3_SQ4_2 ((uint32_t)0x00020000) /*!<Bit 2 */
+#define ADC_SQR3_SQ4_3 ((uint32_t)0x00040000) /*!<Bit 3 */
+#define ADC_SQR3_SQ4_4 ((uint32_t)0x00080000) /*!<Bit 4 */
+
+#define ADC_SQR3_SQ5 ((uint32_t)0x01F00000) /*!<SQ5[4:0] bits (5th conversion in regular sequence) */
+#define ADC_SQR3_SQ5_0 ((uint32_t)0x00100000) /*!<Bit 0 */
+#define ADC_SQR3_SQ5_1 ((uint32_t)0x00200000) /*!<Bit 1 */
+#define ADC_SQR3_SQ5_2 ((uint32_t)0x00400000) /*!<Bit 2 */
+#define ADC_SQR3_SQ5_3 ((uint32_t)0x00800000) /*!<Bit 3 */
+#define ADC_SQR3_SQ5_4 ((uint32_t)0x01000000) /*!<Bit 4 */
+
+#define ADC_SQR3_SQ6 ((uint32_t)0x3E000000) /*!<SQ6[4:0] bits (6th conversion in regular sequence) */
+#define ADC_SQR3_SQ6_0 ((uint32_t)0x02000000) /*!<Bit 0 */
+#define ADC_SQR3_SQ6_1 ((uint32_t)0x04000000) /*!<Bit 1 */
+#define ADC_SQR3_SQ6_2 ((uint32_t)0x08000000) /*!<Bit 2 */
+#define ADC_SQR3_SQ6_3 ((uint32_t)0x10000000) /*!<Bit 3 */
+#define ADC_SQR3_SQ6_4 ((uint32_t)0x20000000) /*!<Bit 4 */
+
+/******************* Bit definition for ADC_JSQR register *******************/
+#define ADC_JSQR_JSQ1 ((uint32_t)0x0000001F) /*!<JSQ1[4:0] bits (1st conversion in injected sequence) */
+#define ADC_JSQR_JSQ1_0 ((uint32_t)0x00000001) /*!<Bit 0 */
+#define ADC_JSQR_JSQ1_1 ((uint32_t)0x00000002) /*!<Bit 1 */
+#define ADC_JSQR_JSQ1_2 ((uint32_t)0x00000004) /*!<Bit 2 */
+#define ADC_JSQR_JSQ1_3 ((uint32_t)0x00000008) /*!<Bit 3 */
+#define ADC_JSQR_JSQ1_4 ((uint32_t)0x00000010) /*!<Bit 4 */
+
+#define ADC_JSQR_JSQ2 ((uint32_t)0x000003E0) /*!<JSQ2[4:0] bits (2nd conversion in injected sequence) */
+#define ADC_JSQR_JSQ2_0 ((uint32_t)0x00000020) /*!<Bit 0 */
+#define ADC_JSQR_JSQ2_1 ((uint32_t)0x00000040) /*!<Bit 1 */
+#define ADC_JSQR_JSQ2_2 ((uint32_t)0x00000080) /*!<Bit 2 */
+#define ADC_JSQR_JSQ2_3 ((uint32_t)0x00000100) /*!<Bit 3 */
+#define ADC_JSQR_JSQ2_4 ((uint32_t)0x00000200) /*!<Bit 4 */
+
+#define ADC_JSQR_JSQ3 ((uint32_t)0x00007C00) /*!<JSQ3[4:0] bits (3rd conversion in injected sequence) */
+#define ADC_JSQR_JSQ3_0 ((uint32_t)0x00000400) /*!<Bit 0 */
+#define ADC_JSQR_JSQ3_1 ((uint32_t)0x00000800) /*!<Bit 1 */
+#define ADC_JSQR_JSQ3_2 ((uint32_t)0x00001000) /*!<Bit 2 */
+#define ADC_JSQR_JSQ3_3 ((uint32_t)0x00002000) /*!<Bit 3 */
+#define ADC_JSQR_JSQ3_4 ((uint32_t)0x00004000) /*!<Bit 4 */
+
+#define ADC_JSQR_JSQ4 ((uint32_t)0x000F8000) /*!<JSQ4[4:0] bits (4th conversion in injected sequence) */
+#define ADC_JSQR_JSQ4_0 ((uint32_t)0x00008000) /*!<Bit 0 */
+#define ADC_JSQR_JSQ4_1 ((uint32_t)0x00010000) /*!<Bit 1 */
+#define ADC_JSQR_JSQ4_2 ((uint32_t)0x00020000) /*!<Bit 2 */
+#define ADC_JSQR_JSQ4_3 ((uint32_t)0x00040000) /*!<Bit 3 */
+#define ADC_JSQR_JSQ4_4 ((uint32_t)0x00080000) /*!<Bit 4 */
+
+#define ADC_JSQR_JL ((uint32_t)0x00300000) /*!<JL[1:0] bits (Injected Sequence length) */
+#define ADC_JSQR_JL_0 ((uint32_t)0x00100000) /*!<Bit 0 */
+#define ADC_JSQR_JL_1 ((uint32_t)0x00200000) /*!<Bit 1 */
+
+/******************* Bit definition for ADC_JDR1 register *******************/
+#define ADC_JDR1_JDATA ((uint16_t)0xFFFF) /*!<Injected data */
+
+/******************* Bit definition for ADC_JDR2 register *******************/
+#define ADC_JDR2_JDATA ((uint16_t)0xFFFF) /*!<Injected data */
+
+/******************* Bit definition for ADC_JDR3 register *******************/
+#define ADC_JDR3_JDATA ((uint16_t)0xFFFF) /*!<Injected data */
+
+/******************* Bit definition for ADC_JDR4 register *******************/
+#define ADC_JDR4_JDATA ((uint16_t)0xFFFF) /*!<Injected data */
+
+/******************** Bit definition for ADC_DR register ********************/
+#define ADC_DR_DATA ((uint32_t)0x0000FFFF) /*!<Regular data */
+#define ADC_DR_ADC2DATA ((uint32_t)0xFFFF0000) /*!<ADC2 data */
+
+/******************************************************************************/
+/* */
+/* Digital to Analog Converter */
+/* */
+/******************************************************************************/
+
+/******************** Bit definition for DAC_CR register ********************/
+#define DAC_CR_EN1 ((uint32_t)0x00000001) /*!<DAC channel1 enable */
+#define DAC_CR_BOFF1 ((uint32_t)0x00000002) /*!<DAC channel1 output buffer disable */
+#define DAC_CR_TEN1 ((uint32_t)0x00000004) /*!<DAC channel1 Trigger enable */
+
+#define DAC_CR_TSEL1 ((uint32_t)0x00000038) /*!<TSEL1[2:0] (DAC channel1 Trigger selection) */
+#define DAC_CR_TSEL1_0 ((uint32_t)0x00000008) /*!<Bit 0 */
+#define DAC_CR_TSEL1_1 ((uint32_t)0x00000010) /*!<Bit 1 */
+#define DAC_CR_TSEL1_2 ((uint32_t)0x00000020) /*!<Bit 2 */
+
+#define DAC_CR_WAVE1 ((uint32_t)0x000000C0) /*!<WAVE1[1:0] (DAC channel1 noise/triangle wave generation enable) */
+#define DAC_CR_WAVE1_0 ((uint32_t)0x00000040) /*!<Bit 0 */
+#define DAC_CR_WAVE1_1 ((uint32_t)0x00000080) /*!<Bit 1 */
+
+#define DAC_CR_MAMP1 ((uint32_t)0x00000F00) /*!<MAMP1[3:0] (DAC channel1 Mask/Amplitude selector) */
+#define DAC_CR_MAMP1_0 ((uint32_t)0x00000100) /*!<Bit 0 */
+#define DAC_CR_MAMP1_1 ((uint32_t)0x00000200) /*!<Bit 1 */
+#define DAC_CR_MAMP1_2 ((uint32_t)0x00000400) /*!<Bit 2 */
+#define DAC_CR_MAMP1_3 ((uint32_t)0x00000800) /*!<Bit 3 */
+
+#define DAC_CR_DMAEN1 ((uint32_t)0x00001000) /*!<DAC channel1 DMA enable */
+#define DAC_CR_EN2 ((uint32_t)0x00010000) /*!<DAC channel2 enable */
+#define DAC_CR_BOFF2 ((uint32_t)0x00020000) /*!<DAC channel2 output buffer disable */
+#define DAC_CR_TEN2 ((uint32_t)0x00040000) /*!<DAC channel2 Trigger enable */
+
+#define DAC_CR_TSEL2 ((uint32_t)0x00380000) /*!<TSEL2[2:0] (DAC channel2 Trigger selection) */
+#define DAC_CR_TSEL2_0 ((uint32_t)0x00080000) /*!<Bit 0 */
+#define DAC_CR_TSEL2_1 ((uint32_t)0x00100000) /*!<Bit 1 */
+#define DAC_CR_TSEL2_2 ((uint32_t)0x00200000) /*!<Bit 2 */
+
+#define DAC_CR_WAVE2 ((uint32_t)0x00C00000) /*!<WAVE2[1:0] (DAC channel2 noise/triangle wave generation enable) */
+#define DAC_CR_WAVE2_0 ((uint32_t)0x00400000) /*!<Bit 0 */
+#define DAC_CR_WAVE2_1 ((uint32_t)0x00800000) /*!<Bit 1 */
+
+#define DAC_CR_MAMP2 ((uint32_t)0x0F000000) /*!<MAMP2[3:0] (DAC channel2 Mask/Amplitude selector) */
+#define DAC_CR_MAMP2_0 ((uint32_t)0x01000000) /*!<Bit 0 */
+#define DAC_CR_MAMP2_1 ((uint32_t)0x02000000) /*!<Bit 1 */
+#define DAC_CR_MAMP2_2 ((uint32_t)0x04000000) /*!<Bit 2 */
+#define DAC_CR_MAMP2_3 ((uint32_t)0x08000000) /*!<Bit 3 */
+
+#define DAC_CR_DMAEN2 ((uint32_t)0x10000000) /*!<DAC channel2 DMA enabled */
+
+/***************** Bit definition for DAC_SWTRIGR register ******************/
+#define DAC_SWTRIGR_SWTRIG1 ((uint8_t)0x01) /*!<DAC channel1 software trigger */
+#define DAC_SWTRIGR_SWTRIG2 ((uint8_t)0x02) /*!<DAC channel2 software trigger */
+
+/***************** Bit definition for DAC_DHR12R1 register ******************/
+#define DAC_DHR12R1_DACC1DHR ((uint16_t)0x0FFF) /*!<DAC channel1 12-bit Right aligned data */
+
+/***************** Bit definition for DAC_DHR12L1 register ******************/
+#define DAC_DHR12L1_DACC1DHR ((uint16_t)0xFFF0) /*!<DAC channel1 12-bit Left aligned data */
+
+/****************** Bit definition for DAC_DHR8R1 register ******************/
+#define DAC_DHR8R1_DACC1DHR ((uint8_t)0xFF) /*!<DAC channel1 8-bit Right aligned data */
+
+/***************** Bit definition for DAC_DHR12R2 register ******************/
+#define DAC_DHR12R2_DACC2DHR ((uint16_t)0x0FFF) /*!<DAC channel2 12-bit Right aligned data */
+
+/***************** Bit definition for DAC_DHR12L2 register ******************/
+#define DAC_DHR12L2_DACC2DHR ((uint16_t)0xFFF0) /*!<DAC channel2 12-bit Left aligned data */
+
+/****************** Bit definition for DAC_DHR8R2 register ******************/
+#define DAC_DHR8R2_DACC2DHR ((uint8_t)0xFF) /*!<DAC channel2 8-bit Right aligned data */
+
+/***************** Bit definition for DAC_DHR12RD register ******************/
+#define DAC_DHR12RD_DACC1DHR ((uint32_t)0x00000FFF) /*!<DAC channel1 12-bit Right aligned data */
+#define DAC_DHR12RD_DACC2DHR ((uint32_t)0x0FFF0000) /*!<DAC channel2 12-bit Right aligned data */
+
+/***************** Bit definition for DAC_DHR12LD register ******************/
+#define DAC_DHR12LD_DACC1DHR ((uint32_t)0x0000FFF0) /*!<DAC channel1 12-bit Left aligned data */
+#define DAC_DHR12LD_DACC2DHR ((uint32_t)0xFFF00000) /*!<DAC channel2 12-bit Left aligned data */
+
+/****************** Bit definition for DAC_DHR8RD register ******************/
+#define DAC_DHR8RD_DACC1DHR ((uint16_t)0x00FF) /*!<DAC channel1 8-bit Right aligned data */
+#define DAC_DHR8RD_DACC2DHR ((uint16_t)0xFF00) /*!<DAC channel2 8-bit Right aligned data */
+
+/******************* Bit definition for DAC_DOR1 register *******************/
+#define DAC_DOR1_DACC1DOR ((uint16_t)0x0FFF) /*!<DAC channel1 data output */
+
+/******************* Bit definition for DAC_DOR2 register *******************/
+#define DAC_DOR2_DACC2DOR ((uint16_t)0x0FFF) /*!<DAC channel2 data output */
+
+/******************************************************************************/
+/* */
+/* TIM */
+/* */
+/******************************************************************************/
+
+/******************* Bit definition for TIM_CR1 register ********************/
+#define TIM_CR1_CEN ((uint16_t)0x0001) /*!<Counter enable */
+#define TIM_CR1_UDIS ((uint16_t)0x0002) /*!<Update disable */
+#define TIM_CR1_URS ((uint16_t)0x0004) /*!<Update request source */
+#define TIM_CR1_OPM ((uint16_t)0x0008) /*!<One pulse mode */
+#define TIM_CR1_DIR ((uint16_t)0x0010) /*!<Direction */
+
+#define TIM_CR1_CMS ((uint16_t)0x0060) /*!<CMS[1:0] bits (Center-aligned mode selection) */
+#define TIM_CR1_CMS_0 ((uint16_t)0x0020) /*!<Bit 0 */
+#define TIM_CR1_CMS_1 ((uint16_t)0x0040) /*!<Bit 1 */
+
+#define TIM_CR1_ARPE ((uint16_t)0x0080) /*!<Auto-reload preload enable */
+
+#define TIM_CR1_CKD ((uint16_t)0x0300) /*!<CKD[1:0] bits (clock division) */
+#define TIM_CR1_CKD_0 ((uint16_t)0x0100) /*!<Bit 0 */
+#define TIM_CR1_CKD_1 ((uint16_t)0x0200) /*!<Bit 1 */
+
+/******************* Bit definition for TIM_CR2 register ********************/
+#define TIM_CR2_CCPC ((uint16_t)0x0001) /*!<Capture/Compare Preloaded Control */
+#define TIM_CR2_CCUS ((uint16_t)0x0004) /*!<Capture/Compare Control Update Selection */
+#define TIM_CR2_CCDS ((uint16_t)0x0008) /*!<Capture/Compare DMA Selection */
+
+#define TIM_CR2_MMS ((uint16_t)0x0070) /*!<MMS[2:0] bits (Master Mode Selection) */
+#define TIM_CR2_MMS_0 ((uint16_t)0x0010) /*!<Bit 0 */
+#define TIM_CR2_MMS_1 ((uint16_t)0x0020) /*!<Bit 1 */
+#define TIM_CR2_MMS_2 ((uint16_t)0x0040) /*!<Bit 2 */
+
+#define TIM_CR2_TI1S ((uint16_t)0x0080) /*!<TI1 Selection */
+#define TIM_CR2_OIS1 ((uint16_t)0x0100) /*!<Output Idle state 1 (OC1 output) */
+#define TIM_CR2_OIS1N ((uint16_t)0x0200) /*!<Output Idle state 1 (OC1N output) */
+#define TIM_CR2_OIS2 ((uint16_t)0x0400) /*!<Output Idle state 2 (OC2 output) */
+#define TIM_CR2_OIS2N ((uint16_t)0x0800) /*!<Output Idle state 2 (OC2N output) */
+#define TIM_CR2_OIS3 ((uint16_t)0x1000) /*!<Output Idle state 3 (OC3 output) */
+#define TIM_CR2_OIS3N ((uint16_t)0x2000) /*!<Output Idle state 3 (OC3N output) */
+#define TIM_CR2_OIS4 ((uint16_t)0x4000) /*!<Output Idle state 4 (OC4 output) */
+
+/******************* Bit definition for TIM_SMCR register *******************/
+#define TIM_SMCR_SMS ((uint16_t)0x0007) /*!<SMS[2:0] bits (Slave mode selection) */
+#define TIM_SMCR_SMS_0 ((uint16_t)0x0001) /*!<Bit 0 */
+#define TIM_SMCR_SMS_1 ((uint16_t)0x0002) /*!<Bit 1 */
+#define TIM_SMCR_SMS_2 ((uint16_t)0x0004) /*!<Bit 2 */
+
+#define TIM_SMCR_TS ((uint16_t)0x0070) /*!<TS[2:0] bits (Trigger selection) */
+#define TIM_SMCR_TS_0 ((uint16_t)0x0010) /*!<Bit 0 */
+#define TIM_SMCR_TS_1 ((uint16_t)0x0020) /*!<Bit 1 */
+#define TIM_SMCR_TS_2 ((uint16_t)0x0040) /*!<Bit 2 */
+
+#define TIM_SMCR_MSM ((uint16_t)0x0080) /*!<Master/slave mode */
+
+#define TIM_SMCR_ETF ((uint16_t)0x0F00) /*!<ETF[3:0] bits (External trigger filter) */
+#define TIM_SMCR_ETF_0 ((uint16_t)0x0100) /*!<Bit 0 */
+#define TIM_SMCR_ETF_1 ((uint16_t)0x0200) /*!<Bit 1 */
+#define TIM_SMCR_ETF_2 ((uint16_t)0x0400) /*!<Bit 2 */
+#define TIM_SMCR_ETF_3 ((uint16_t)0x0800) /*!<Bit 3 */
+
+#define TIM_SMCR_ETPS ((uint16_t)0x3000) /*!<ETPS[1:0] bits (External trigger prescaler) */
+#define TIM_SMCR_ETPS_0 ((uint16_t)0x1000) /*!<Bit 0 */
+#define TIM_SMCR_ETPS_1 ((uint16_t)0x2000) /*!<Bit 1 */
+
+#define TIM_SMCR_ECE ((uint16_t)0x4000) /*!<External clock enable */
+#define TIM_SMCR_ETP ((uint16_t)0x8000) /*!<External trigger polarity */
+
+/******************* Bit definition for TIM_DIER register *******************/
+#define TIM_DIER_UIE ((uint16_t)0x0001) /*!<Update interrupt enable */
+#define TIM_DIER_CC1IE ((uint16_t)0x0002) /*!<Capture/Compare 1 interrupt enable */
+#define TIM_DIER_CC2IE ((uint16_t)0x0004) /*!<Capture/Compare 2 interrupt enable */
+#define TIM_DIER_CC3IE ((uint16_t)0x0008) /*!<Capture/Compare 3 interrupt enable */
+#define TIM_DIER_CC4IE ((uint16_t)0x0010) /*!<Capture/Compare 4 interrupt enable */
+#define TIM_DIER_COMIE ((uint16_t)0x0020) /*!<COM interrupt enable */
+#define TIM_DIER_TIE ((uint16_t)0x0040) /*!<Trigger interrupt enable */
+#define TIM_DIER_BIE ((uint16_t)0x0080) /*!<Break interrupt enable */
+#define TIM_DIER_UDE ((uint16_t)0x0100) /*!<Update DMA request enable */
+#define TIM_DIER_CC1DE ((uint16_t)0x0200) /*!<Capture/Compare 1 DMA request enable */
+#define TIM_DIER_CC2DE ((uint16_t)0x0400) /*!<Capture/Compare 2 DMA request enable */
+#define TIM_DIER_CC3DE ((uint16_t)0x0800) /*!<Capture/Compare 3 DMA request enable */
+#define TIM_DIER_CC4DE ((uint16_t)0x1000) /*!<Capture/Compare 4 DMA request enable */
+#define TIM_DIER_COMDE ((uint16_t)0x2000) /*!<COM DMA request enable */
+#define TIM_DIER_TDE ((uint16_t)0x4000) /*!<Trigger DMA request enable */
+
+/******************** Bit definition for TIM_SR register ********************/
+#define TIM_SR_UIF ((uint16_t)0x0001) /*!<Update interrupt Flag */
+#define TIM_SR_CC1IF ((uint16_t)0x0002) /*!<Capture/Compare 1 interrupt Flag */
+#define TIM_SR_CC2IF ((uint16_t)0x0004) /*!<Capture/Compare 2 interrupt Flag */
+#define TIM_SR_CC3IF ((uint16_t)0x0008) /*!<Capture/Compare 3 interrupt Flag */
+#define TIM_SR_CC4IF ((uint16_t)0x0010) /*!<Capture/Compare 4 interrupt Flag */
+#define TIM_SR_COMIF ((uint16_t)0x0020) /*!<COM interrupt Flag */
+#define TIM_SR_TIF ((uint16_t)0x0040) /*!<Trigger interrupt Flag */
+#define TIM_SR_BIF ((uint16_t)0x0080) /*!<Break interrupt Flag */
+#define TIM_SR_CC1OF ((uint16_t)0x0200) /*!<Capture/Compare 1 Overcapture Flag */
+#define TIM_SR_CC2OF ((uint16_t)0x0400) /*!<Capture/Compare 2 Overcapture Flag */
+#define TIM_SR_CC3OF ((uint16_t)0x0800) /*!<Capture/Compare 3 Overcapture Flag */
+#define TIM_SR_CC4OF ((uint16_t)0x1000) /*!<Capture/Compare 4 Overcapture Flag */
+
+/******************* Bit definition for TIM_EGR register ********************/
+#define TIM_EGR_UG ((uint8_t)0x01) /*!<Update Generation */
+#define TIM_EGR_CC1G ((uint8_t)0x02) /*!<Capture/Compare 1 Generation */
+#define TIM_EGR_CC2G ((uint8_t)0x04) /*!<Capture/Compare 2 Generation */
+#define TIM_EGR_CC3G ((uint8_t)0x08) /*!<Capture/Compare 3 Generation */
+#define TIM_EGR_CC4G ((uint8_t)0x10) /*!<Capture/Compare 4 Generation */
+#define TIM_EGR_COMG ((uint8_t)0x20) /*!<Capture/Compare Control Update Generation */
+#define TIM_EGR_TG ((uint8_t)0x40) /*!<Trigger Generation */
+#define TIM_EGR_BG ((uint8_t)0x80) /*!<Break Generation */
+
+/****************** Bit definition for TIM_CCMR1 register *******************/
+#define TIM_CCMR1_CC1S ((uint16_t)0x0003) /*!<CC1S[1:0] bits (Capture/Compare 1 Selection) */
+#define TIM_CCMR1_CC1S_0 ((uint16_t)0x0001) /*!<Bit 0 */
+#define TIM_CCMR1_CC1S_1 ((uint16_t)0x0002) /*!<Bit 1 */
+
+#define TIM_CCMR1_OC1FE ((uint16_t)0x0004) /*!<Output Compare 1 Fast enable */
+#define TIM_CCMR1_OC1PE ((uint16_t)0x0008) /*!<Output Compare 1 Preload enable */
+
+#define TIM_CCMR1_OC1M ((uint16_t)0x0070) /*!<OC1M[2:0] bits (Output Compare 1 Mode) */
+#define TIM_CCMR1_OC1M_0 ((uint16_t)0x0010) /*!<Bit 0 */
+#define TIM_CCMR1_OC1M_1 ((uint16_t)0x0020) /*!<Bit 1 */
+#define TIM_CCMR1_OC1M_2 ((uint16_t)0x0040) /*!<Bit 2 */
+
+#define TIM_CCMR1_OC1CE ((uint16_t)0x0080) /*!<Output Compare 1Clear Enable */
+
+#define TIM_CCMR1_CC2S ((uint16_t)0x0300) /*!<CC2S[1:0] bits (Capture/Compare 2 Selection) */
+#define TIM_CCMR1_CC2S_0 ((uint16_t)0x0100) /*!<Bit 0 */
+#define TIM_CCMR1_CC2S_1 ((uint16_t)0x0200) /*!<Bit 1 */
+
+#define TIM_CCMR1_OC2FE ((uint16_t)0x0400) /*!<Output Compare 2 Fast enable */
+#define TIM_CCMR1_OC2PE ((uint16_t)0x0800) /*!<Output Compare 2 Preload enable */
+
+#define TIM_CCMR1_OC2M ((uint16_t)0x7000) /*!<OC2M[2:0] bits (Output Compare 2 Mode) */
+#define TIM_CCMR1_OC2M_0 ((uint16_t)0x1000) /*!<Bit 0 */
+#define TIM_CCMR1_OC2M_1 ((uint16_t)0x2000) /*!<Bit 1 */
+#define TIM_CCMR1_OC2M_2 ((uint16_t)0x4000) /*!<Bit 2 */
+
+#define TIM_CCMR1_OC2CE ((uint16_t)0x8000) /*!<Output Compare 2 Clear Enable */
+
+/*----------------------------------------------------------------------------*/
+
+#define TIM_CCMR1_IC1PSC ((uint16_t)0x000C) /*!<IC1PSC[1:0] bits (Input Capture 1 Prescaler) */
+#define TIM_CCMR1_IC1PSC_0 ((uint16_t)0x0004) /*!<Bit 0 */
+#define TIM_CCMR1_IC1PSC_1 ((uint16_t)0x0008) /*!<Bit 1 */
+
+#define TIM_CCMR1_IC1F ((uint16_t)0x00F0) /*!<IC1F[3:0] bits (Input Capture 1 Filter) */
+#define TIM_CCMR1_IC1F_0 ((uint16_t)0x0010) /*!<Bit 0 */
+#define TIM_CCMR1_IC1F_1 ((uint16_t)0x0020) /*!<Bit 1 */
+#define TIM_CCMR1_IC1F_2 ((uint16_t)0x0040) /*!<Bit 2 */
+#define TIM_CCMR1_IC1F_3 ((uint16_t)0x0080) /*!<Bit 3 */
+
+#define TIM_CCMR1_IC2PSC ((uint16_t)0x0C00) /*!<IC2PSC[1:0] bits (Input Capture 2 Prescaler) */
+#define TIM_CCMR1_IC2PSC_0 ((uint16_t)0x0400) /*!<Bit 0 */
+#define TIM_CCMR1_IC2PSC_1 ((uint16_t)0x0800) /*!<Bit 1 */
+
+#define TIM_CCMR1_IC2F ((uint16_t)0xF000) /*!<IC2F[3:0] bits (Input Capture 2 Filter) */
+#define TIM_CCMR1_IC2F_0 ((uint16_t)0x1000) /*!<Bit 0 */
+#define TIM_CCMR1_IC2F_1 ((uint16_t)0x2000) /*!<Bit 1 */
+#define TIM_CCMR1_IC2F_2 ((uint16_t)0x4000) /*!<Bit 2 */
+#define TIM_CCMR1_IC2F_3 ((uint16_t)0x8000) /*!<Bit 3 */
+
+/****************** Bit definition for TIM_CCMR2 register *******************/
+#define TIM_CCMR2_CC3S ((uint16_t)0x0003) /*!<CC3S[1:0] bits (Capture/Compare 3 Selection) */
+#define TIM_CCMR2_CC3S_0 ((uint16_t)0x0001) /*!<Bit 0 */
+#define TIM_CCMR2_CC3S_1 ((uint16_t)0x0002) /*!<Bit 1 */
+
+#define TIM_CCMR2_OC3FE ((uint16_t)0x0004) /*!<Output Compare 3 Fast enable */
+#define TIM_CCMR2_OC3PE ((uint16_t)0x0008) /*!<Output Compare 3 Preload enable */
+
+#define TIM_CCMR2_OC3M ((uint16_t)0x0070) /*!<OC3M[2:0] bits (Output Compare 3 Mode) */
+#define TIM_CCMR2_OC3M_0 ((uint16_t)0x0010) /*!<Bit 0 */
+#define TIM_CCMR2_OC3M_1 ((uint16_t)0x0020) /*!<Bit 1 */
+#define TIM_CCMR2_OC3M_2 ((uint16_t)0x0040) /*!<Bit 2 */
+
+#define TIM_CCMR2_OC3CE ((uint16_t)0x0080) /*!<Output Compare 3 Clear Enable */
+
+#define TIM_CCMR2_CC4S ((uint16_t)0x0300) /*!<CC4S[1:0] bits (Capture/Compare 4 Selection) */
+#define TIM_CCMR2_CC4S_0 ((uint16_t)0x0100) /*!<Bit 0 */
+#define TIM_CCMR2_CC4S_1 ((uint16_t)0x0200) /*!<Bit 1 */
+
+#define TIM_CCMR2_OC4FE ((uint16_t)0x0400) /*!<Output Compare 4 Fast enable */
+#define TIM_CCMR2_OC4PE ((uint16_t)0x0800) /*!<Output Compare 4 Preload enable */
+
+#define TIM_CCMR2_OC4M ((uint16_t)0x7000) /*!<OC4M[2:0] bits (Output Compare 4 Mode) */
+#define TIM_CCMR2_OC4M_0 ((uint16_t)0x1000) /*!<Bit 0 */
+#define TIM_CCMR2_OC4M_1 ((uint16_t)0x2000) /*!<Bit 1 */
+#define TIM_CCMR2_OC4M_2 ((uint16_t)0x4000) /*!<Bit 2 */
+
+#define TIM_CCMR2_OC4CE ((uint16_t)0x8000) /*!<Output Compare 4 Clear Enable */
+
+/*----------------------------------------------------------------------------*/
+
+#define TIM_CCMR2_IC3PSC ((uint16_t)0x000C) /*!<IC3PSC[1:0] bits (Input Capture 3 Prescaler) */
+#define TIM_CCMR2_IC3PSC_0 ((uint16_t)0x0004) /*!<Bit 0 */
+#define TIM_CCMR2_IC3PSC_1 ((uint16_t)0x0008) /*!<Bit 1 */
+
+#define TIM_CCMR2_IC3F ((uint16_t)0x00F0) /*!<IC3F[3:0] bits (Input Capture 3 Filter) */
+#define TIM_CCMR2_IC3F_0 ((uint16_t)0x0010) /*!<Bit 0 */
+#define TIM_CCMR2_IC3F_1 ((uint16_t)0x0020) /*!<Bit 1 */
+#define TIM_CCMR2_IC3F_2 ((uint16_t)0x0040) /*!<Bit 2 */
+#define TIM_CCMR2_IC3F_3 ((uint16_t)0x0080) /*!<Bit 3 */
+
+#define TIM_CCMR2_IC4PSC ((uint16_t)0x0C00) /*!<IC4PSC[1:0] bits (Input Capture 4 Prescaler) */
+#define TIM_CCMR2_IC4PSC_0 ((uint16_t)0x0400) /*!<Bit 0 */
+#define TIM_CCMR2_IC4PSC_1 ((uint16_t)0x0800) /*!<Bit 1 */
+
+#define TIM_CCMR2_IC4F ((uint16_t)0xF000) /*!<IC4F[3:0] bits (Input Capture 4 Filter) */
+#define TIM_CCMR2_IC4F_0 ((uint16_t)0x1000) /*!<Bit 0 */
+#define TIM_CCMR2_IC4F_1 ((uint16_t)0x2000) /*!<Bit 1 */
+#define TIM_CCMR2_IC4F_2 ((uint16_t)0x4000) /*!<Bit 2 */
+#define TIM_CCMR2_IC4F_3 ((uint16_t)0x8000) /*!<Bit 3 */
+
+/******************* Bit definition for TIM_CCER register *******************/
+#define TIM_CCER_CC1E ((uint16_t)0x0001) /*!<Capture/Compare 1 output enable */
+#define TIM_CCER_CC1P ((uint16_t)0x0002) /*!<Capture/Compare 1 output Polarity */
+#define TIM_CCER_CC1NE ((uint16_t)0x0004) /*!<Capture/Compare 1 Complementary output enable */
+#define TIM_CCER_CC1NP ((uint16_t)0x0008) /*!<Capture/Compare 1 Complementary output Polarity */
+#define TIM_CCER_CC2E ((uint16_t)0x0010) /*!<Capture/Compare 2 output enable */
+#define TIM_CCER_CC2P ((uint16_t)0x0020) /*!<Capture/Compare 2 output Polarity */
+#define TIM_CCER_CC2NE ((uint16_t)0x0040) /*!<Capture/Compare 2 Complementary output enable */
+#define TIM_CCER_CC2NP ((uint16_t)0x0080) /*!<Capture/Compare 2 Complementary output Polarity */
+#define TIM_CCER_CC3E ((uint16_t)0x0100) /*!<Capture/Compare 3 output enable */
+#define TIM_CCER_CC3P ((uint16_t)0x0200) /*!<Capture/Compare 3 output Polarity */
+#define TIM_CCER_CC3NE ((uint16_t)0x0400) /*!<Capture/Compare 3 Complementary output enable */
+#define TIM_CCER_CC3NP ((uint16_t)0x0800) /*!<Capture/Compare 3 Complementary output Polarity */
+#define TIM_CCER_CC4E ((uint16_t)0x1000) /*!<Capture/Compare 4 output enable */
+#define TIM_CCER_CC4P ((uint16_t)0x2000) /*!<Capture/Compare 4 output Polarity */
+
+/******************* Bit definition for TIM_CNT register ********************/
+#define TIM_CNT_CNT ((uint16_t)0xFFFF) /*!<Counter Value */
+
+/******************* Bit definition for TIM_PSC register ********************/
+#define TIM_PSC_PSC ((uint16_t)0xFFFF) /*!<Prescaler Value */
+
+/******************* Bit definition for TIM_ARR register ********************/
+#define TIM_ARR_ARR ((uint16_t)0xFFFF) /*!<actual auto-reload Value */
+
+/******************* Bit definition for TIM_RCR register ********************/
+#define TIM_RCR_REP ((uint8_t)0xFF) /*!<Repetition Counter Value */
+
+/******************* Bit definition for TIM_CCR1 register *******************/
+#define TIM_CCR1_CCR1 ((uint16_t)0xFFFF) /*!<Capture/Compare 1 Value */
+
+/******************* Bit definition for TIM_CCR2 register *******************/
+#define TIM_CCR2_CCR2 ((uint16_t)0xFFFF) /*!<Capture/Compare 2 Value */
+
+/******************* Bit definition for TIM_CCR3 register *******************/
+#define TIM_CCR3_CCR3 ((uint16_t)0xFFFF) /*!<Capture/Compare 3 Value */
+
+/******************* Bit definition for TIM_CCR4 register *******************/
+#define TIM_CCR4_CCR4 ((uint16_t)0xFFFF) /*!<Capture/Compare 4 Value */
+
+/******************* Bit definition for TIM_BDTR register *******************/
+#define TIM_BDTR_DTG ((uint16_t)0x00FF) /*!<DTG[0:7] bits (Dead-Time Generator set-up) */
+#define TIM_BDTR_DTG_0 ((uint16_t)0x0001) /*!<Bit 0 */
+#define TIM_BDTR_DTG_1 ((uint16_t)0x0002) /*!<Bit 1 */
+#define TIM_BDTR_DTG_2 ((uint16_t)0x0004) /*!<Bit 2 */
+#define TIM_BDTR_DTG_3 ((uint16_t)0x0008) /*!<Bit 3 */
+#define TIM_BDTR_DTG_4 ((uint16_t)0x0010) /*!<Bit 4 */
+#define TIM_BDTR_DTG_5 ((uint16_t)0x0020) /*!<Bit 5 */
+#define TIM_BDTR_DTG_6 ((uint16_t)0x0040) /*!<Bit 6 */
+#define TIM_BDTR_DTG_7 ((uint16_t)0x0080) /*!<Bit 7 */
+
+#define TIM_BDTR_LOCK ((uint16_t)0x0300) /*!<LOCK[1:0] bits (Lock Configuration) */
+#define TIM_BDTR_LOCK_0 ((uint16_t)0x0100) /*!<Bit 0 */
+#define TIM_BDTR_LOCK_1 ((uint16_t)0x0200) /*!<Bit 1 */
+
+#define TIM_BDTR_OSSI ((uint16_t)0x0400) /*!<Off-State Selection for Idle mode */
+#define TIM_BDTR_OSSR ((uint16_t)0x0800) /*!<Off-State Selection for Run mode */
+#define TIM_BDTR_BKE ((uint16_t)0x1000) /*!<Break enable */
+#define TIM_BDTR_BKP ((uint16_t)0x2000) /*!<Break Polarity */
+#define TIM_BDTR_AOE ((uint16_t)0x4000) /*!<Automatic Output enable */
+#define TIM_BDTR_MOE ((uint16_t)0x8000) /*!<Main Output enable */
+
+/******************* Bit definition for TIM_DCR register ********************/
+#define TIM_DCR_DBA ((uint16_t)0x001F) /*!<DBA[4:0] bits (DMA Base Address) */
+#define TIM_DCR_DBA_0 ((uint16_t)0x0001) /*!<Bit 0 */
+#define TIM_DCR_DBA_1 ((uint16_t)0x0002) /*!<Bit 1 */
+#define TIM_DCR_DBA_2 ((uint16_t)0x0004) /*!<Bit 2 */
+#define TIM_DCR_DBA_3 ((uint16_t)0x0008) /*!<Bit 3 */
+#define TIM_DCR_DBA_4 ((uint16_t)0x0010) /*!<Bit 4 */
+
+#define TIM_DCR_DBL ((uint16_t)0x1F00) /*!<DBL[4:0] bits (DMA Burst Length) */
+#define TIM_DCR_DBL_0 ((uint16_t)0x0100) /*!<Bit 0 */
+#define TIM_DCR_DBL_1 ((uint16_t)0x0200) /*!<Bit 1 */
+#define TIM_DCR_DBL_2 ((uint16_t)0x0400) /*!<Bit 2 */
+#define TIM_DCR_DBL_3 ((uint16_t)0x0800) /*!<Bit 3 */
+#define TIM_DCR_DBL_4 ((uint16_t)0x1000) /*!<Bit 4 */
+
+/******************* Bit definition for TIM_DMAR register *******************/
+#define TIM_DMAR_DMAB ((uint16_t)0xFFFF) /*!<DMA register for burst accesses */
+
+/******************************************************************************/
+/* */
+/* Real-Time Clock */
+/* */
+/******************************************************************************/
+
+/******************* Bit definition for RTC_CRH register ********************/
+#define RTC_CRH_SECIE ((uint8_t)0x01) /*!<Second Interrupt Enable */
+#define RTC_CRH_ALRIE ((uint8_t)0x02) /*!<Alarm Interrupt Enable */
+#define RTC_CRH_OWIE ((uint8_t)0x04) /*!<OverfloW Interrupt Enable */
+
+/******************* Bit definition for RTC_CRL register ********************/
+#define RTC_CRL_SECF ((uint8_t)0x01) /*!<Second Flag */
+#define RTC_CRL_ALRF ((uint8_t)0x02) /*!<Alarm Flag */
+#define RTC_CRL_OWF ((uint8_t)0x04) /*!<OverfloW Flag */
+#define RTC_CRL_RSF ((uint8_t)0x08) /*!<Registers Synchronized Flag */
+#define RTC_CRL_CNF ((uint8_t)0x10) /*!<Configuration Flag */
+#define RTC_CRL_RTOFF ((uint8_t)0x20) /*!<RTC operation OFF */
+
+/******************* Bit definition for RTC_PRLH register *******************/
+#define RTC_PRLH_PRL ((uint16_t)0x000F) /*!<RTC Prescaler Reload Value High */
+
+/******************* Bit definition for RTC_PRLL register *******************/
+#define RTC_PRLL_PRL ((uint16_t)0xFFFF) /*!<RTC Prescaler Reload Value Low */
+
+/******************* Bit definition for RTC_DIVH register *******************/
+#define RTC_DIVH_RTC_DIV ((uint16_t)0x000F) /*!<RTC Clock Divider High */
+
+/******************* Bit definition for RTC_DIVL register *******************/
+#define RTC_DIVL_RTC_DIV ((uint16_t)0xFFFF) /*!<RTC Clock Divider Low */
+
+/******************* Bit definition for RTC_CNTH register *******************/
+#define RTC_CNTH_RTC_CNT ((uint16_t)0xFFFF) /*!<RTC Counter High */
+
+/******************* Bit definition for RTC_CNTL register *******************/
+#define RTC_CNTL_RTC_CNT ((uint16_t)0xFFFF) /*!<RTC Counter Low */
+
+/******************* Bit definition for RTC_ALRH register *******************/
+#define RTC_ALRH_RTC_ALR ((uint16_t)0xFFFF) /*!<RTC Alarm High */
+
+/******************* Bit definition for RTC_ALRL register *******************/
+#define RTC_ALRL_RTC_ALR ((uint16_t)0xFFFF) /*!<RTC Alarm Low */
+
+/******************************************************************************/
+/* */
+/* Independent WATCHDOG */
+/* */
+/******************************************************************************/
+
+/******************* Bit definition for IWDG_KR register ********************/
+#define IWDG_KR_KEY ((uint16_t)0xFFFF) /*!<Key value (write only, read 0000h) */
+
+/******************* Bit definition for IWDG_PR register ********************/
+#define IWDG_PR_PR ((uint8_t)0x07) /*!<PR[2:0] (Prescaler divider) */
+#define IWDG_PR_PR_0 ((uint8_t)0x01) /*!<Bit 0 */
+#define IWDG_PR_PR_1 ((uint8_t)0x02) /*!<Bit 1 */
+#define IWDG_PR_PR_2 ((uint8_t)0x04) /*!<Bit 2 */
+
+/******************* Bit definition for IWDG_RLR register *******************/
+#define IWDG_RLR_RL ((uint16_t)0x0FFF) /*!<Watchdog counter reload value */
+
+/******************* Bit definition for IWDG_SR register ********************/
+#define IWDG_SR_PVU ((uint8_t)0x01) /*!<Watchdog prescaler value update */
+#define IWDG_SR_RVU ((uint8_t)0x02) /*!<Watchdog counter reload value update */
+
+/******************************************************************************/
+/* */
+/* Window WATCHDOG */
+/* */
+/******************************************************************************/
+
+/******************* Bit definition for WWDG_CR register ********************/
+#define WWDG_CR_T ((uint8_t)0x7F) /*!<T[6:0] bits (7-Bit counter (MSB to LSB)) */
+#define WWDG_CR_T0 ((uint8_t)0x01) /*!<Bit 0 */
+#define WWDG_CR_T1 ((uint8_t)0x02) /*!<Bit 1 */
+#define WWDG_CR_T2 ((uint8_t)0x04) /*!<Bit 2 */
+#define WWDG_CR_T3 ((uint8_t)0x08) /*!<Bit 3 */
+#define WWDG_CR_T4 ((uint8_t)0x10) /*!<Bit 4 */
+#define WWDG_CR_T5 ((uint8_t)0x20) /*!<Bit 5 */
+#define WWDG_CR_T6 ((uint8_t)0x40) /*!<Bit 6 */
+
+#define WWDG_CR_WDGA ((uint8_t)0x80) /*!<Activation bit */
+
+/******************* Bit definition for WWDG_CFR register *******************/
+#define WWDG_CFR_W ((uint16_t)0x007F) /*!<W[6:0] bits (7-bit window value) */
+#define WWDG_CFR_W0 ((uint16_t)0x0001) /*!<Bit 0 */
+#define WWDG_CFR_W1 ((uint16_t)0x0002) /*!<Bit 1 */
+#define WWDG_CFR_W2 ((uint16_t)0x0004) /*!<Bit 2 */
+#define WWDG_CFR_W3 ((uint16_t)0x0008) /*!<Bit 3 */
+#define WWDG_CFR_W4 ((uint16_t)0x0010) /*!<Bit 4 */
+#define WWDG_CFR_W5 ((uint16_t)0x0020) /*!<Bit 5 */
+#define WWDG_CFR_W6 ((uint16_t)0x0040) /*!<Bit 6 */
+
+#define WWDG_CFR_WDGTB ((uint16_t)0x0180) /*!<WDGTB[1:0] bits (Timer Base) */
+#define WWDG_CFR_WDGTB0 ((uint16_t)0x0080) /*!<Bit 0 */
+#define WWDG_CFR_WDGTB1 ((uint16_t)0x0100) /*!<Bit 1 */
+
+#define WWDG_CFR_EWI ((uint16_t)0x0200) /*!<Early Wakeup Interrupt */
+
+/******************* Bit definition for WWDG_SR register ********************/
+#define WWDG_SR_EWIF ((uint8_t)0x01) /*!<Early Wakeup Interrupt Flag */
+
+/******************************************************************************/
+/* */
+/* Flexible Static Memory Controller */
+/* */
+/******************************************************************************/
+
+/****************** Bit definition for FSMC_BCR1 register *******************/
+#define FSMC_BCR1_MBKEN ((uint32_t)0x00000001) /*!<Memory bank enable bit */
+#define FSMC_BCR1_MUXEN ((uint32_t)0x00000002) /*!<Address/data multiplexing enable bit */
+
+#define FSMC_BCR1_MTYP ((uint32_t)0x0000000C) /*!<MTYP[1:0] bits (Memory type) */
+#define FSMC_BCR1_MTYP_0 ((uint32_t)0x00000004) /*!<Bit 0 */
+#define FSMC_BCR1_MTYP_1 ((uint32_t)0x00000008) /*!<Bit 1 */
+
+#define FSMC_BCR1_MWID ((uint32_t)0x00000030) /*!<MWID[1:0] bits (Memory data bus width) */
+#define FSMC_BCR1_MWID_0 ((uint32_t)0x00000010) /*!<Bit 0 */
+#define FSMC_BCR1_MWID_1 ((uint32_t)0x00000020) /*!<Bit 1 */
+
+#define FSMC_BCR1_FACCEN ((uint32_t)0x00000040) /*!<Flash access enable */
+#define FSMC_BCR1_BURSTEN ((uint32_t)0x00000100) /*!<Burst enable bit */
+#define FSMC_BCR1_WAITPOL ((uint32_t)0x00000200) /*!<Wait signal polarity bit */
+#define FSMC_BCR1_WRAPMOD ((uint32_t)0x00000400) /*!<Wrapped burst mode support */
+#define FSMC_BCR1_WAITCFG ((uint32_t)0x00000800) /*!<Wait timing configuration */
+#define FSMC_BCR1_WREN ((uint32_t)0x00001000) /*!<Write enable bit */
+#define FSMC_BCR1_WAITEN ((uint32_t)0x00002000) /*!<Wait enable bit */
+#define FSMC_BCR1_EXTMOD ((uint32_t)0x00004000) /*!<Extended mode enable */
+#define FSMC_BCR1_CBURSTRW ((uint32_t)0x00080000) /*!<Write burst enable */
+
+/****************** Bit definition for FSMC_BCR2 register *******************/
+#define FSMC_BCR2_MBKEN ((uint32_t)0x00000001) /*!<Memory bank enable bit */
+#define FSMC_BCR2_MUXEN ((uint32_t)0x00000002) /*!<Address/data multiplexing enable bit */
+
+#define FSMC_BCR2_MTYP ((uint32_t)0x0000000C) /*!<MTYP[1:0] bits (Memory type) */
+#define FSMC_BCR2_MTYP_0 ((uint32_t)0x00000004) /*!<Bit 0 */
+#define FSMC_BCR2_MTYP_1 ((uint32_t)0x00000008) /*!<Bit 1 */
+
+#define FSMC_BCR2_MWID ((uint32_t)0x00000030) /*!<MWID[1:0] bits (Memory data bus width) */
+#define FSMC_BCR2_MWID_0 ((uint32_t)0x00000010) /*!<Bit 0 */
+#define FSMC_BCR2_MWID_1 ((uint32_t)0x00000020) /*!<Bit 1 */
+
+#define FSMC_BCR2_FACCEN ((uint32_t)0x00000040) /*!<Flash access enable */
+#define FSMC_BCR2_BURSTEN ((uint32_t)0x00000100) /*!<Burst enable bit */
+#define FSMC_BCR2_WAITPOL ((uint32_t)0x00000200) /*!<Wait signal polarity bit */
+#define FSMC_BCR2_WRAPMOD ((uint32_t)0x00000400) /*!<Wrapped burst mode support */
+#define FSMC_BCR2_WAITCFG ((uint32_t)0x00000800) /*!<Wait timing configuration */
+#define FSMC_BCR2_WREN ((uint32_t)0x00001000) /*!<Write enable bit */
+#define FSMC_BCR2_WAITEN ((uint32_t)0x00002000) /*!<Wait enable bit */
+#define FSMC_BCR2_EXTMOD ((uint32_t)0x00004000) /*!<Extended mode enable */
+#define FSMC_BCR2_CBURSTRW ((uint32_t)0x00080000) /*!<Write burst enable */
+
+/****************** Bit definition for FSMC_BCR3 register *******************/
+#define FSMC_BCR3_MBKEN ((uint32_t)0x00000001) /*!<Memory bank enable bit */
+#define FSMC_BCR3_MUXEN ((uint32_t)0x00000002) /*!<Address/data multiplexing enable bit */
+
+#define FSMC_BCR3_MTYP ((uint32_t)0x0000000C) /*!<MTYP[1:0] bits (Memory type) */
+#define FSMC_BCR3_MTYP_0 ((uint32_t)0x00000004) /*!<Bit 0 */
+#define FSMC_BCR3_MTYP_1 ((uint32_t)0x00000008) /*!<Bit 1 */
+
+#define FSMC_BCR3_MWID ((uint32_t)0x00000030) /*!<MWID[1:0] bits (Memory data bus width) */
+#define FSMC_BCR3_MWID_0 ((uint32_t)0x00000010) /*!<Bit 0 */
+#define FSMC_BCR3_MWID_1 ((uint32_t)0x00000020) /*!<Bit 1 */
+
+#define FSMC_BCR3_FACCEN ((uint32_t)0x00000040) /*!<Flash access enable */
+#define FSMC_BCR3_BURSTEN ((uint32_t)0x00000100) /*!<Burst enable bit */
+#define FSMC_BCR3_WAITPOL ((uint32_t)0x00000200) /*!<Wait signal polarity bit. */
+#define FSMC_BCR3_WRAPMOD ((uint32_t)0x00000400) /*!<Wrapped burst mode support */
+#define FSMC_BCR3_WAITCFG ((uint32_t)0x00000800) /*!<Wait timing configuration */
+#define FSMC_BCR3_WREN ((uint32_t)0x00001000) /*!<Write enable bit */
+#define FSMC_BCR3_WAITEN ((uint32_t)0x00002000) /*!<Wait enable bit */
+#define FSMC_BCR3_EXTMOD ((uint32_t)0x00004000) /*!<Extended mode enable */
+#define FSMC_BCR3_CBURSTRW ((uint32_t)0x00080000) /*!<Write burst enable */
+
+/****************** Bit definition for FSMC_BCR4 register *******************/
+#define FSMC_BCR4_MBKEN ((uint32_t)0x00000001) /*!<Memory bank enable bit */
+#define FSMC_BCR4_MUXEN ((uint32_t)0x00000002) /*!<Address/data multiplexing enable bit */
+
+#define FSMC_BCR4_MTYP ((uint32_t)0x0000000C) /*!<MTYP[1:0] bits (Memory type) */
+#define FSMC_BCR4_MTYP_0 ((uint32_t)0x00000004) /*!<Bit 0 */
+#define FSMC_BCR4_MTYP_1 ((uint32_t)0x00000008) /*!<Bit 1 */
+
+#define FSMC_BCR4_MWID ((uint32_t)0x00000030) /*!<MWID[1:0] bits (Memory data bus width) */
+#define FSMC_BCR4_MWID_0 ((uint32_t)0x00000010) /*!<Bit 0 */
+#define FSMC_BCR4_MWID_1 ((uint32_t)0x00000020) /*!<Bit 1 */
+
+#define FSMC_BCR4_FACCEN ((uint32_t)0x00000040) /*!<Flash access enable */
+#define FSMC_BCR4_BURSTEN ((uint32_t)0x00000100) /*!<Burst enable bit */
+#define FSMC_BCR4_WAITPOL ((uint32_t)0x00000200) /*!<Wait signal polarity bit */
+#define FSMC_BCR4_WRAPMOD ((uint32_t)0x00000400) /*!<Wrapped burst mode support */
+#define FSMC_BCR4_WAITCFG ((uint32_t)0x00000800) /*!<Wait timing configuration */
+#define FSMC_BCR4_WREN ((uint32_t)0x00001000) /*!<Write enable bit */
+#define FSMC_BCR4_WAITEN ((uint32_t)0x00002000) /*!<Wait enable bit */
+#define FSMC_BCR4_EXTMOD ((uint32_t)0x00004000) /*!<Extended mode enable */
+#define FSMC_BCR4_CBURSTRW ((uint32_t)0x00080000) /*!<Write burst enable */
+
+/****************** Bit definition for FSMC_BTR1 register ******************/
+#define FSMC_BTR1_ADDSET ((uint32_t)0x0000000F) /*!<ADDSET[3:0] bits (Address setup phase duration) */
+#define FSMC_BTR1_ADDSET_0 ((uint32_t)0x00000001) /*!<Bit 0 */
+#define FSMC_BTR1_ADDSET_1 ((uint32_t)0x00000002) /*!<Bit 1 */
+#define FSMC_BTR1_ADDSET_2 ((uint32_t)0x00000004) /*!<Bit 2 */
+#define FSMC_BTR1_ADDSET_3 ((uint32_t)0x00000008) /*!<Bit 3 */
+
+#define FSMC_BTR1_ADDHLD ((uint32_t)0x000000F0) /*!<ADDHLD[3:0] bits (Address-hold phase duration) */
+#define FSMC_BTR1_ADDHLD_0 ((uint32_t)0x00000010) /*!<Bit 0 */
+#define FSMC_BTR1_ADDHLD_1 ((uint32_t)0x00000020) /*!<Bit 1 */
+#define FSMC_BTR1_ADDHLD_2 ((uint32_t)0x00000040) /*!<Bit 2 */
+#define FSMC_BTR1_ADDHLD_3 ((uint32_t)0x00000080) /*!<Bit 3 */
+
+#define FSMC_BTR1_DATAST ((uint32_t)0x0000FF00) /*!<DATAST [3:0] bits (Data-phase duration) */
+#define FSMC_BTR1_DATAST_0 ((uint32_t)0x00000100) /*!<Bit 0 */
+#define FSMC_BTR1_DATAST_1 ((uint32_t)0x00000200) /*!<Bit 1 */
+#define FSMC_BTR1_DATAST_2 ((uint32_t)0x00000400) /*!<Bit 2 */
+#define FSMC_BTR1_DATAST_3 ((uint32_t)0x00000800) /*!<Bit 3 */
+
+#define FSMC_BTR1_BUSTURN ((uint32_t)0x000F0000) /*!<BUSTURN[3:0] bits (Bus turnaround phase duration) */
+#define FSMC_BTR1_BUSTURN_0 ((uint32_t)0x00010000) /*!<Bit 0 */
+#define FSMC_BTR1_BUSTURN_1 ((uint32_t)0x00020000) /*!<Bit 1 */
+#define FSMC_BTR1_BUSTURN_2 ((uint32_t)0x00040000) /*!<Bit 2 */
+#define FSMC_BTR1_BUSTURN_3 ((uint32_t)0x00080000) /*!<Bit 3 */
+
+#define FSMC_BTR1_CLKDIV ((uint32_t)0x00F00000) /*!<CLKDIV[3:0] bits (Clock divide ratio) */
+#define FSMC_BTR1_CLKDIV_0 ((uint32_t)0x00100000) /*!<Bit 0 */
+#define FSMC_BTR1_CLKDIV_1 ((uint32_t)0x00200000) /*!<Bit 1 */
+#define FSMC_BTR1_CLKDIV_2 ((uint32_t)0x00400000) /*!<Bit 2 */
+#define FSMC_BTR1_CLKDIV_3 ((uint32_t)0x00800000) /*!<Bit 3 */
+
+#define FSMC_BTR1_DATLAT ((uint32_t)0x0F000000) /*!<DATLA[3:0] bits (Data latency) */
+#define FSMC_BTR1_DATLAT_0 ((uint32_t)0x01000000) /*!<Bit 0 */
+#define FSMC_BTR1_DATLAT_1 ((uint32_t)0x02000000) /*!<Bit 1 */
+#define FSMC_BTR1_DATLAT_2 ((uint32_t)0x04000000) /*!<Bit 2 */
+#define FSMC_BTR1_DATLAT_3 ((uint32_t)0x08000000) /*!<Bit 3 */
+
+#define FSMC_BTR1_ACCMOD ((uint32_t)0x30000000) /*!<ACCMOD[1:0] bits (Access mode) */
+#define FSMC_BTR1_ACCMOD_0 ((uint32_t)0x10000000) /*!<Bit 0 */
+#define FSMC_BTR1_ACCMOD_1 ((uint32_t)0x20000000) /*!<Bit 1 */
+
+/****************** Bit definition for FSMC_BTR2 register *******************/
+#define FSMC_BTR2_ADDSET ((uint32_t)0x0000000F) /*!<ADDSET[3:0] bits (Address setup phase duration) */
+#define FSMC_BTR2_ADDSET_0 ((uint32_t)0x00000001) /*!<Bit 0 */
+#define FSMC_BTR2_ADDSET_1 ((uint32_t)0x00000002) /*!<Bit 1 */
+#define FSMC_BTR2_ADDSET_2 ((uint32_t)0x00000004) /*!<Bit 2 */
+#define FSMC_BTR2_ADDSET_3 ((uint32_t)0x00000008) /*!<Bit 3 */
+
+#define FSMC_BTR2_ADDHLD ((uint32_t)0x000000F0) /*!<ADDHLD[3:0] bits (Address-hold phase duration) */
+#define FSMC_BTR2_ADDHLD_0 ((uint32_t)0x00000010) /*!<Bit 0 */
+#define FSMC_BTR2_ADDHLD_1 ((uint32_t)0x00000020) /*!<Bit 1 */
+#define FSMC_BTR2_ADDHLD_2 ((uint32_t)0x00000040) /*!<Bit 2 */
+#define FSMC_BTR2_ADDHLD_3 ((uint32_t)0x00000080) /*!<Bit 3 */
+
+#define FSMC_BTR2_DATAST ((uint32_t)0x0000FF00) /*!<DATAST [3:0] bits (Data-phase duration) */
+#define FSMC_BTR2_DATAST_0 ((uint32_t)0x00000100) /*!<Bit 0 */
+#define FSMC_BTR2_DATAST_1 ((uint32_t)0x00000200) /*!<Bit 1 */
+#define FSMC_BTR2_DATAST_2 ((uint32_t)0x00000400) /*!<Bit 2 */
+#define FSMC_BTR2_DATAST_3 ((uint32_t)0x00000800) /*!<Bit 3 */
+
+#define FSMC_BTR2_BUSTURN ((uint32_t)0x000F0000) /*!<BUSTURN[3:0] bits (Bus turnaround phase duration) */
+#define FSMC_BTR2_BUSTURN_0 ((uint32_t)0x00010000) /*!<Bit 0 */
+#define FSMC_BTR2_BUSTURN_1 ((uint32_t)0x00020000) /*!<Bit 1 */
+#define FSMC_BTR2_BUSTURN_2 ((uint32_t)0x00040000) /*!<Bit 2 */
+#define FSMC_BTR2_BUSTURN_3 ((uint32_t)0x00080000) /*!<Bit 3 */
+
+#define FSMC_BTR2_CLKDIV ((uint32_t)0x00F00000) /*!<CLKDIV[3:0] bits (Clock divide ratio) */
+#define FSMC_BTR2_CLKDIV_0 ((uint32_t)0x00100000) /*!<Bit 0 */
+#define FSMC_BTR2_CLKDIV_1 ((uint32_t)0x00200000) /*!<Bit 1 */
+#define FSMC_BTR2_CLKDIV_2 ((uint32_t)0x00400000) /*!<Bit 2 */
+#define FSMC_BTR2_CLKDIV_3 ((uint32_t)0x00800000) /*!<Bit 3 */
+
+#define FSMC_BTR2_DATLAT ((uint32_t)0x0F000000) /*!<DATLA[3:0] bits (Data latency) */
+#define FSMC_BTR2_DATLAT_0 ((uint32_t)0x01000000) /*!<Bit 0 */
+#define FSMC_BTR2_DATLAT_1 ((uint32_t)0x02000000) /*!<Bit 1 */
+#define FSMC_BTR2_DATLAT_2 ((uint32_t)0x04000000) /*!<Bit 2 */
+#define FSMC_BTR2_DATLAT_3 ((uint32_t)0x08000000) /*!<Bit 3 */
+
+#define FSMC_BTR2_ACCMOD ((uint32_t)0x30000000) /*!<ACCMOD[1:0] bits (Access mode) */
+#define FSMC_BTR2_ACCMOD_0 ((uint32_t)0x10000000) /*!<Bit 0 */
+#define FSMC_BTR2_ACCMOD_1 ((uint32_t)0x20000000) /*!<Bit 1 */
+
+/******************* Bit definition for FSMC_BTR3 register *******************/
+#define FSMC_BTR3_ADDSET ((uint32_t)0x0000000F) /*!<ADDSET[3:0] bits (Address setup phase duration) */
+#define FSMC_BTR3_ADDSET_0 ((uint32_t)0x00000001) /*!<Bit 0 */
+#define FSMC_BTR3_ADDSET_1 ((uint32_t)0x00000002) /*!<Bit 1 */
+#define FSMC_BTR3_ADDSET_2 ((uint32_t)0x00000004) /*!<Bit 2 */
+#define FSMC_BTR3_ADDSET_3 ((uint32_t)0x00000008) /*!<Bit 3 */
+
+#define FSMC_BTR3_ADDHLD ((uint32_t)0x000000F0) /*!<ADDHLD[3:0] bits (Address-hold phase duration) */
+#define FSMC_BTR3_ADDHLD_0 ((uint32_t)0x00000010) /*!<Bit 0 */
+#define FSMC_BTR3_ADDHLD_1 ((uint32_t)0x00000020) /*!<Bit 1 */
+#define FSMC_BTR3_ADDHLD_2 ((uint32_t)0x00000040) /*!<Bit 2 */
+#define FSMC_BTR3_ADDHLD_3 ((uint32_t)0x00000080) /*!<Bit 3 */
+
+#define FSMC_BTR3_DATAST ((uint32_t)0x0000FF00) /*!<DATAST [3:0] bits (Data-phase duration) */
+#define FSMC_BTR3_DATAST_0 ((uint32_t)0x00000100) /*!<Bit 0 */
+#define FSMC_BTR3_DATAST_1 ((uint32_t)0x00000200) /*!<Bit 1 */
+#define FSMC_BTR3_DATAST_2 ((uint32_t)0x00000400) /*!<Bit 2 */
+#define FSMC_BTR3_DATAST_3 ((uint32_t)0x00000800) /*!<Bit 3 */
+
+#define FSMC_BTR3_BUSTURN ((uint32_t)0x000F0000) /*!<BUSTURN[3:0] bits (Bus turnaround phase duration) */
+#define FSMC_BTR3_BUSTURN_0 ((uint32_t)0x00010000) /*!<Bit 0 */
+#define FSMC_BTR3_BUSTURN_1 ((uint32_t)0x00020000) /*!<Bit 1 */
+#define FSMC_BTR3_BUSTURN_2 ((uint32_t)0x00040000) /*!<Bit 2 */
+#define FSMC_BTR3_BUSTURN_3 ((uint32_t)0x00080000) /*!<Bit 3 */
+
+#define FSMC_BTR3_CLKDIV ((uint32_t)0x00F00000) /*!<CLKDIV[3:0] bits (Clock divide ratio) */
+#define FSMC_BTR3_CLKDIV_0 ((uint32_t)0x00100000) /*!<Bit 0 */
+#define FSMC_BTR3_CLKDIV_1 ((uint32_t)0x00200000) /*!<Bit 1 */
+#define FSMC_BTR3_CLKDIV_2 ((uint32_t)0x00400000) /*!<Bit 2 */
+#define FSMC_BTR3_CLKDIV_3 ((uint32_t)0x00800000) /*!<Bit 3 */
+
+#define FSMC_BTR3_DATLAT ((uint32_t)0x0F000000) /*!<DATLA[3:0] bits (Data latency) */
+#define FSMC_BTR3_DATLAT_0 ((uint32_t)0x01000000) /*!<Bit 0 */
+#define FSMC_BTR3_DATLAT_1 ((uint32_t)0x02000000) /*!<Bit 1 */
+#define FSMC_BTR3_DATLAT_2 ((uint32_t)0x04000000) /*!<Bit 2 */
+#define FSMC_BTR3_DATLAT_3 ((uint32_t)0x08000000) /*!<Bit 3 */
+
+#define FSMC_BTR3_ACCMOD ((uint32_t)0x30000000) /*!<ACCMOD[1:0] bits (Access mode) */
+#define FSMC_BTR3_ACCMOD_0 ((uint32_t)0x10000000) /*!<Bit 0 */
+#define FSMC_BTR3_ACCMOD_1 ((uint32_t)0x20000000) /*!<Bit 1 */
+
+/****************** Bit definition for FSMC_BTR4 register *******************/
+#define FSMC_BTR4_ADDSET ((uint32_t)0x0000000F) /*!<ADDSET[3:0] bits (Address setup phase duration) */
+#define FSMC_BTR4_ADDSET_0 ((uint32_t)0x00000001) /*!<Bit 0 */
+#define FSMC_BTR4_ADDSET_1 ((uint32_t)0x00000002) /*!<Bit 1 */
+#define FSMC_BTR4_ADDSET_2 ((uint32_t)0x00000004) /*!<Bit 2 */
+#define FSMC_BTR4_ADDSET_3 ((uint32_t)0x00000008) /*!<Bit 3 */
+
+#define FSMC_BTR4_ADDHLD ((uint32_t)0x000000F0) /*!<ADDHLD[3:0] bits (Address-hold phase duration) */
+#define FSMC_BTR4_ADDHLD_0 ((uint32_t)0x00000010) /*!<Bit 0 */
+#define FSMC_BTR4_ADDHLD_1 ((uint32_t)0x00000020) /*!<Bit 1 */
+#define FSMC_BTR4_ADDHLD_2 ((uint32_t)0x00000040) /*!<Bit 2 */
+#define FSMC_BTR4_ADDHLD_3 ((uint32_t)0x00000080) /*!<Bit 3 */
+
+#define FSMC_BTR4_DATAST ((uint32_t)0x0000FF00) /*!<DATAST [3:0] bits (Data-phase duration) */
+#define FSMC_BTR4_DATAST_0 ((uint32_t)0x00000100) /*!<Bit 0 */
+#define FSMC_BTR4_DATAST_1 ((uint32_t)0x00000200) /*!<Bit 1 */
+#define FSMC_BTR4_DATAST_2 ((uint32_t)0x00000400) /*!<Bit 2 */
+#define FSMC_BTR4_DATAST_3 ((uint32_t)0x00000800) /*!<Bit 3 */
+
+#define FSMC_BTR4_BUSTURN ((uint32_t)0x000F0000) /*!<BUSTURN[3:0] bits (Bus turnaround phase duration) */
+#define FSMC_BTR4_BUSTURN_0 ((uint32_t)0x00010000) /*!<Bit 0 */
+#define FSMC_BTR4_BUSTURN_1 ((uint32_t)0x00020000) /*!<Bit 1 */
+#define FSMC_BTR4_BUSTURN_2 ((uint32_t)0x00040000) /*!<Bit 2 */
+#define FSMC_BTR4_BUSTURN_3 ((uint32_t)0x00080000) /*!<Bit 3 */
+
+#define FSMC_BTR4_CLKDIV ((uint32_t)0x00F00000) /*!<CLKDIV[3:0] bits (Clock divide ratio) */
+#define FSMC_BTR4_CLKDIV_0 ((uint32_t)0x00100000) /*!<Bit 0 */
+#define FSMC_BTR4_CLKDIV_1 ((uint32_t)0x00200000) /*!<Bit 1 */
+#define FSMC_BTR4_CLKDIV_2 ((uint32_t)0x00400000) /*!<Bit 2 */
+#define FSMC_BTR4_CLKDIV_3 ((uint32_t)0x00800000) /*!<Bit 3 */
+
+#define FSMC_BTR4_DATLAT ((uint32_t)0x0F000000) /*!<DATLA[3:0] bits (Data latency) */
+#define FSMC_BTR4_DATLAT_0 ((uint32_t)0x01000000) /*!<Bit 0 */
+#define FSMC_BTR4_DATLAT_1 ((uint32_t)0x02000000) /*!<Bit 1 */
+#define FSMC_BTR4_DATLAT_2 ((uint32_t)0x04000000) /*!<Bit 2 */
+#define FSMC_BTR4_DATLAT_3 ((uint32_t)0x08000000) /*!<Bit 3 */
+
+#define FSMC_BTR4_ACCMOD ((uint32_t)0x30000000) /*!<ACCMOD[1:0] bits (Access mode) */
+#define FSMC_BTR4_ACCMOD_0 ((uint32_t)0x10000000) /*!<Bit 0 */
+#define FSMC_BTR4_ACCMOD_1 ((uint32_t)0x20000000) /*!<Bit 1 */
+
+/****************** Bit definition for FSMC_BWTR1 register ******************/
+#define FSMC_BWTR1_ADDSET ((uint32_t)0x0000000F) /*!<ADDSET[3:0] bits (Address setup phase duration) */
+#define FSMC_BWTR1_ADDSET_0 ((uint32_t)0x00000001) /*!<Bit 0 */
+#define FSMC_BWTR1_ADDSET_1 ((uint32_t)0x00000002) /*!<Bit 1 */
+#define FSMC_BWTR1_ADDSET_2 ((uint32_t)0x00000004) /*!<Bit 2 */
+#define FSMC_BWTR1_ADDSET_3 ((uint32_t)0x00000008) /*!<Bit 3 */
+
+#define FSMC_BWTR1_ADDHLD ((uint32_t)0x000000F0) /*!<ADDHLD[3:0] bits (Address-hold phase duration) */
+#define FSMC_BWTR1_ADDHLD_0 ((uint32_t)0x00000010) /*!<Bit 0 */
+#define FSMC_BWTR1_ADDHLD_1 ((uint32_t)0x00000020) /*!<Bit 1 */
+#define FSMC_BWTR1_ADDHLD_2 ((uint32_t)0x00000040) /*!<Bit 2 */
+#define FSMC_BWTR1_ADDHLD_3 ((uint32_t)0x00000080) /*!<Bit 3 */
+
+#define FSMC_BWTR1_DATAST ((uint32_t)0x0000FF00) /*!<DATAST [3:0] bits (Data-phase duration) */
+#define FSMC_BWTR1_DATAST_0 ((uint32_t)0x00000100) /*!<Bit 0 */
+#define FSMC_BWTR1_DATAST_1 ((uint32_t)0x00000200) /*!<Bit 1 */
+#define FSMC_BWTR1_DATAST_2 ((uint32_t)0x00000400) /*!<Bit 2 */
+#define FSMC_BWTR1_DATAST_3 ((uint32_t)0x00000800) /*!<Bit 3 */
+
+#define FSMC_BWTR1_CLKDIV ((uint32_t)0x00F00000) /*!<CLKDIV[3:0] bits (Clock divide ratio) */
+#define FSMC_BWTR1_CLKDIV_0 ((uint32_t)0x00100000) /*!<Bit 0 */
+#define FSMC_BWTR1_CLKDIV_1 ((uint32_t)0x00200000) /*!<Bit 1 */
+#define FSMC_BWTR1_CLKDIV_2 ((uint32_t)0x00400000) /*!<Bit 2 */
+#define FSMC_BWTR1_CLKDIV_3 ((uint32_t)0x00800000) /*!<Bit 3 */
+
+#define FSMC_BWTR1_DATLAT ((uint32_t)0x0F000000) /*!<DATLA[3:0] bits (Data latency) */
+#define FSMC_BWTR1_DATLAT_0 ((uint32_t)0x01000000) /*!<Bit 0 */
+#define FSMC_BWTR1_DATLAT_1 ((uint32_t)0x02000000) /*!<Bit 1 */
+#define FSMC_BWTR1_DATLAT_2 ((uint32_t)0x04000000) /*!<Bit 2 */
+#define FSMC_BWTR1_DATLAT_3 ((uint32_t)0x08000000) /*!<Bit 3 */
+
+#define FSMC_BWTR1_ACCMOD ((uint32_t)0x30000000) /*!<ACCMOD[1:0] bits (Access mode) */
+#define FSMC_BWTR1_ACCMOD_0 ((uint32_t)0x10000000) /*!<Bit 0 */
+#define FSMC_BWTR1_ACCMOD_1 ((uint32_t)0x20000000) /*!<Bit 1 */
+
+/****************** Bit definition for FSMC_BWTR2 register ******************/
+#define FSMC_BWTR2_ADDSET ((uint32_t)0x0000000F) /*!<ADDSET[3:0] bits (Address setup phase duration) */
+#define FSMC_BWTR2_ADDSET_0 ((uint32_t)0x00000001) /*!<Bit 0 */
+#define FSMC_BWTR2_ADDSET_1 ((uint32_t)0x00000002) /*!<Bit 1 */
+#define FSMC_BWTR2_ADDSET_2 ((uint32_t)0x00000004) /*!<Bit 2 */
+#define FSMC_BWTR2_ADDSET_3 ((uint32_t)0x00000008) /*!<Bit 3 */
+
+#define FSMC_BWTR2_ADDHLD ((uint32_t)0x000000F0) /*!<ADDHLD[3:0] bits (Address-hold phase duration) */
+#define FSMC_BWTR2_ADDHLD_0 ((uint32_t)0x00000010) /*!<Bit 0 */
+#define FSMC_BWTR2_ADDHLD_1 ((uint32_t)0x00000020) /*!<Bit 1 */
+#define FSMC_BWTR2_ADDHLD_2 ((uint32_t)0x00000040) /*!<Bit 2 */
+#define FSMC_BWTR2_ADDHLD_3 ((uint32_t)0x00000080) /*!<Bit 3 */
+
+#define FSMC_BWTR2_DATAST ((uint32_t)0x0000FF00) /*!<DATAST [3:0] bits (Data-phase duration) */
+#define FSMC_BWTR2_DATAST_0 ((uint32_t)0x00000100) /*!<Bit 0 */
+#define FSMC_BWTR2_DATAST_1 ((uint32_t)0x00000200) /*!<Bit 1 */
+#define FSMC_BWTR2_DATAST_2 ((uint32_t)0x00000400) /*!<Bit 2 */
+#define FSMC_BWTR2_DATAST_3 ((uint32_t)0x00000800) /*!<Bit 3 */
+
+#define FSMC_BWTR2_CLKDIV ((uint32_t)0x00F00000) /*!<CLKDIV[3:0] bits (Clock divide ratio) */
+#define FSMC_BWTR2_CLKDIV_0 ((uint32_t)0x00100000) /*!<Bit 0 */
+#define FSMC_BWTR2_CLKDIV_1 ((uint32_t)0x00200000) /*!<Bit 1*/
+#define FSMC_BWTR2_CLKDIV_2 ((uint32_t)0x00400000) /*!<Bit 2 */
+#define FSMC_BWTR2_CLKDIV_3 ((uint32_t)0x00800000) /*!<Bit 3 */
+
+#define FSMC_BWTR2_DATLAT ((uint32_t)0x0F000000) /*!<DATLA[3:0] bits (Data latency) */
+#define FSMC_BWTR2_DATLAT_0 ((uint32_t)0x01000000) /*!<Bit 0 */
+#define FSMC_BWTR2_DATLAT_1 ((uint32_t)0x02000000) /*!<Bit 1 */
+#define FSMC_BWTR2_DATLAT_2 ((uint32_t)0x04000000) /*!<Bit 2 */
+#define FSMC_BWTR2_DATLAT_3 ((uint32_t)0x08000000) /*!<Bit 3 */
+
+#define FSMC_BWTR2_ACCMOD ((uint32_t)0x30000000) /*!<ACCMOD[1:0] bits (Access mode) */
+#define FSMC_BWTR2_ACCMOD_0 ((uint32_t)0x10000000) /*!<Bit 0 */
+#define FSMC_BWTR2_ACCMOD_1 ((uint32_t)0x20000000) /*!<Bit 1 */
+
+/****************** Bit definition for FSMC_BWTR3 register ******************/
+#define FSMC_BWTR3_ADDSET ((uint32_t)0x0000000F) /*!<ADDSET[3:0] bits (Address setup phase duration) */
+#define FSMC_BWTR3_ADDSET_0 ((uint32_t)0x00000001) /*!<Bit 0 */
+#define FSMC_BWTR3_ADDSET_1 ((uint32_t)0x00000002) /*!<Bit 1 */
+#define FSMC_BWTR3_ADDSET_2 ((uint32_t)0x00000004) /*!<Bit 2 */
+#define FSMC_BWTR3_ADDSET_3 ((uint32_t)0x00000008) /*!<Bit 3 */
+
+#define FSMC_BWTR3_ADDHLD ((uint32_t)0x000000F0) /*!<ADDHLD[3:0] bits (Address-hold phase duration) */
+#define FSMC_BWTR3_ADDHLD_0 ((uint32_t)0x00000010) /*!<Bit 0 */
+#define FSMC_BWTR3_ADDHLD_1 ((uint32_t)0x00000020) /*!<Bit 1 */
+#define FSMC_BWTR3_ADDHLD_2 ((uint32_t)0x00000040) /*!<Bit 2 */
+#define FSMC_BWTR3_ADDHLD_3 ((uint32_t)0x00000080) /*!<Bit 3 */
+
+#define FSMC_BWTR3_DATAST ((uint32_t)0x0000FF00) /*!<DATAST [3:0] bits (Data-phase duration) */
+#define FSMC_BWTR3_DATAST_0 ((uint32_t)0x00000100) /*!<Bit 0 */
+#define FSMC_BWTR3_DATAST_1 ((uint32_t)0x00000200) /*!<Bit 1 */
+#define FSMC_BWTR3_DATAST_2 ((uint32_t)0x00000400) /*!<Bit 2 */
+#define FSMC_BWTR3_DATAST_3 ((uint32_t)0x00000800) /*!<Bit 3 */
+
+#define FSMC_BWTR3_CLKDIV ((uint32_t)0x00F00000) /*!<CLKDIV[3:0] bits (Clock divide ratio) */
+#define FSMC_BWTR3_CLKDIV_0 ((uint32_t)0x00100000) /*!<Bit 0 */
+#define FSMC_BWTR3_CLKDIV_1 ((uint32_t)0x00200000) /*!<Bit 1 */
+#define FSMC_BWTR3_CLKDIV_2 ((uint32_t)0x00400000) /*!<Bit 2 */
+#define FSMC_BWTR3_CLKDIV_3 ((uint32_t)0x00800000) /*!<Bit 3 */
+
+#define FSMC_BWTR3_DATLAT ((uint32_t)0x0F000000) /*!<DATLA[3:0] bits (Data latency) */
+#define FSMC_BWTR3_DATLAT_0 ((uint32_t)0x01000000) /*!<Bit 0 */
+#define FSMC_BWTR3_DATLAT_1 ((uint32_t)0x02000000) /*!<Bit 1 */
+#define FSMC_BWTR3_DATLAT_2 ((uint32_t)0x04000000) /*!<Bit 2 */
+#define FSMC_BWTR3_DATLAT_3 ((uint32_t)0x08000000) /*!<Bit 3 */
+
+#define FSMC_BWTR3_ACCMOD ((uint32_t)0x30000000) /*!<ACCMOD[1:0] bits (Access mode) */
+#define FSMC_BWTR3_ACCMOD_0 ((uint32_t)0x10000000) /*!<Bit 0 */
+#define FSMC_BWTR3_ACCMOD_1 ((uint32_t)0x20000000) /*!<Bit 1 */
+
+/****************** Bit definition for FSMC_BWTR4 register ******************/
+#define FSMC_BWTR4_ADDSET ((uint32_t)0x0000000F) /*!<ADDSET[3:0] bits (Address setup phase duration) */
+#define FSMC_BWTR4_ADDSET_0 ((uint32_t)0x00000001) /*!<Bit 0 */
+#define FSMC_BWTR4_ADDSET_1 ((uint32_t)0x00000002) /*!<Bit 1 */
+#define FSMC_BWTR4_ADDSET_2 ((uint32_t)0x00000004) /*!<Bit 2 */
+#define FSMC_BWTR4_ADDSET_3 ((uint32_t)0x00000008) /*!<Bit 3 */
+
+#define FSMC_BWTR4_ADDHLD ((uint32_t)0x000000F0) /*!<ADDHLD[3:0] bits (Address-hold phase duration) */
+#define FSMC_BWTR4_ADDHLD_0 ((uint32_t)0x00000010) /*!<Bit 0 */
+#define FSMC_BWTR4_ADDHLD_1 ((uint32_t)0x00000020) /*!<Bit 1 */
+#define FSMC_BWTR4_ADDHLD_2 ((uint32_t)0x00000040) /*!<Bit 2 */
+#define FSMC_BWTR4_ADDHLD_3 ((uint32_t)0x00000080) /*!<Bit 3 */
+
+#define FSMC_BWTR4_DATAST ((uint32_t)0x0000FF00) /*!<DATAST [3:0] bits (Data-phase duration) */
+#define FSMC_BWTR4_DATAST_0 ((uint32_t)0x00000100) /*!<Bit 0 */
+#define FSMC_BWTR4_DATAST_1 ((uint32_t)0x00000200) /*!<Bit 1 */
+#define FSMC_BWTR4_DATAST_2 ((uint32_t)0x00000400) /*!<Bit 2 */
+#define FSMC_BWTR4_DATAST_3 ((uint32_t)0x00000800) /*!<Bit 3 */
+
+#define FSMC_BWTR4_CLKDIV ((uint32_t)0x00F00000) /*!<CLKDIV[3:0] bits (Clock divide ratio) */
+#define FSMC_BWTR4_CLKDIV_0 ((uint32_t)0x00100000) /*!<Bit 0 */
+#define FSMC_BWTR4_CLKDIV_1 ((uint32_t)0x00200000) /*!<Bit 1 */
+#define FSMC_BWTR4_CLKDIV_2 ((uint32_t)0x00400000) /*!<Bit 2 */
+#define FSMC_BWTR4_CLKDIV_3 ((uint32_t)0x00800000) /*!<Bit 3 */
+
+#define FSMC_BWTR4_DATLAT ((uint32_t)0x0F000000) /*!<DATLA[3:0] bits (Data latency) */
+#define FSMC_BWTR4_DATLAT_0 ((uint32_t)0x01000000) /*!<Bit 0 */
+#define FSMC_BWTR4_DATLAT_1 ((uint32_t)0x02000000) /*!<Bit 1 */
+#define FSMC_BWTR4_DATLAT_2 ((uint32_t)0x04000000) /*!<Bit 2 */
+#define FSMC_BWTR4_DATLAT_3 ((uint32_t)0x08000000) /*!<Bit 3 */
+
+#define FSMC_BWTR4_ACCMOD ((uint32_t)0x30000000) /*!<ACCMOD[1:0] bits (Access mode) */
+#define FSMC_BWTR4_ACCMOD_0 ((uint32_t)0x10000000) /*!<Bit 0 */
+#define FSMC_BWTR4_ACCMOD_1 ((uint32_t)0x20000000) /*!<Bit 1 */
+
+/****************** Bit definition for FSMC_PCR2 register *******************/
+#define FSMC_PCR2_PWAITEN ((uint32_t)0x00000002) /*!<Wait feature enable bit */
+#define FSMC_PCR2_PBKEN ((uint32_t)0x00000004) /*!<PC Card/NAND Flash memory bank enable bit */
+#define FSMC_PCR2_PTYP ((uint32_t)0x00000008) /*!<Memory type */
+
+#define FSMC_PCR2_PWID ((uint32_t)0x00000030) /*!<PWID[1:0] bits (NAND Flash databus width) */
+#define FSMC_PCR2_PWID_0 ((uint32_t)0x00000010) /*!<Bit 0 */
+#define FSMC_PCR2_PWID_1 ((uint32_t)0x00000020) /*!<Bit 1 */
+
+#define FSMC_PCR2_ECCEN ((uint32_t)0x00000040) /*!<ECC computation logic enable bit */
+
+#define FSMC_PCR2_TCLR ((uint32_t)0x00001E00) /*!<TCLR[3:0] bits (CLE to RE delay) */
+#define FSMC_PCR2_TCLR_0 ((uint32_t)0x00000200) /*!<Bit 0 */
+#define FSMC_PCR2_TCLR_1 ((uint32_t)0x00000400) /*!<Bit 1 */
+#define FSMC_PCR2_TCLR_2 ((uint32_t)0x00000800) /*!<Bit 2 */
+#define FSMC_PCR2_TCLR_3 ((uint32_t)0x00001000) /*!<Bit 3 */
+
+#define FSMC_PCR2_TAR ((uint32_t)0x0001E000) /*!<TAR[3:0] bits (ALE to RE delay) */
+#define FSMC_PCR2_TAR_0 ((uint32_t)0x00002000) /*!<Bit 0 */
+#define FSMC_PCR2_TAR_1 ((uint32_t)0x00004000) /*!<Bit 1 */
+#define FSMC_PCR2_TAR_2 ((uint32_t)0x00008000) /*!<Bit 2 */
+#define FSMC_PCR2_TAR_3 ((uint32_t)0x00010000) /*!<Bit 3 */
+
+#define FSMC_PCR2_ECCPS ((uint32_t)0x000E0000) /*!<ECCPS[1:0] bits (ECC page size) */
+#define FSMC_PCR2_ECCPS_0 ((uint32_t)0x00020000) /*!<Bit 0 */
+#define FSMC_PCR2_ECCPS_1 ((uint32_t)0x00040000) /*!<Bit 1 */
+#define FSMC_PCR2_ECCPS_2 ((uint32_t)0x00080000) /*!<Bit 2 */
+
+/****************** Bit definition for FSMC_PCR3 register *******************/
+#define FSMC_PCR3_PWAITEN ((uint32_t)0x00000002) /*!<Wait feature enable bit */
+#define FSMC_PCR3_PBKEN ((uint32_t)0x00000004) /*!<PC Card/NAND Flash memory bank enable bit */
+#define FSMC_PCR3_PTYP ((uint32_t)0x00000008) /*!<Memory type */
+
+#define FSMC_PCR3_PWID ((uint32_t)0x00000030) /*!<PWID[1:0] bits (NAND Flash databus width) */
+#define FSMC_PCR3_PWID_0 ((uint32_t)0x00000010) /*!<Bit 0 */
+#define FSMC_PCR3_PWID_1 ((uint32_t)0x00000020) /*!<Bit 1 */
+
+#define FSMC_PCR3_ECCEN ((uint32_t)0x00000040) /*!<ECC computation logic enable bit */
+
+#define FSMC_PCR3_TCLR ((uint32_t)0x00001E00) /*!<TCLR[3:0] bits (CLE to RE delay) */
+#define FSMC_PCR3_TCLR_0 ((uint32_t)0x00000200) /*!<Bit 0 */
+#define FSMC_PCR3_TCLR_1 ((uint32_t)0x00000400) /*!<Bit 1 */
+#define FSMC_PCR3_TCLR_2 ((uint32_t)0x00000800) /*!<Bit 2 */
+#define FSMC_PCR3_TCLR_3 ((uint32_t)0x00001000) /*!<Bit 3 */
+
+#define FSMC_PCR3_TAR ((uint32_t)0x0001E000) /*!<TAR[3:0] bits (ALE to RE delay) */
+#define FSMC_PCR3_TAR_0 ((uint32_t)0x00002000) /*!<Bit 0 */
+#define FSMC_PCR3_TAR_1 ((uint32_t)0x00004000) /*!<Bit 1 */
+#define FSMC_PCR3_TAR_2 ((uint32_t)0x00008000) /*!<Bit 2 */
+#define FSMC_PCR3_TAR_3 ((uint32_t)0x00010000) /*!<Bit 3 */
+
+#define FSMC_PCR3_ECCPS ((uint32_t)0x000E0000) /*!<ECCPS[2:0] bits (ECC page size) */
+#define FSMC_PCR3_ECCPS_0 ((uint32_t)0x00020000) /*!<Bit 0 */
+#define FSMC_PCR3_ECCPS_1 ((uint32_t)0x00040000) /*!<Bit 1 */
+#define FSMC_PCR3_ECCPS_2 ((uint32_t)0x00080000) /*!<Bit 2 */
+
+/****************** Bit definition for FSMC_PCR4 register *******************/
+#define FSMC_PCR4_PWAITEN ((uint32_t)0x00000002) /*!<Wait feature enable bit */
+#define FSMC_PCR4_PBKEN ((uint32_t)0x00000004) /*!<PC Card/NAND Flash memory bank enable bit */
+#define FSMC_PCR4_PTYP ((uint32_t)0x00000008) /*!<Memory type */
+
+#define FSMC_PCR4_PWID ((uint32_t)0x00000030) /*!<PWID[1:0] bits (NAND Flash databus width) */
+#define FSMC_PCR4_PWID_0 ((uint32_t)0x00000010) /*!<Bit 0 */
+#define FSMC_PCR4_PWID_1 ((uint32_t)0x00000020) /*!<Bit 1 */
+
+#define FSMC_PCR4_ECCEN ((uint32_t)0x00000040) /*!<ECC computation logic enable bit */
+
+#define FSMC_PCR4_TCLR ((uint32_t)0x00001E00) /*!<TCLR[3:0] bits (CLE to RE delay) */
+#define FSMC_PCR4_TCLR_0 ((uint32_t)0x00000200) /*!<Bit 0 */
+#define FSMC_PCR4_TCLR_1 ((uint32_t)0x00000400) /*!<Bit 1 */
+#define FSMC_PCR4_TCLR_2 ((uint32_t)0x00000800) /*!<Bit 2 */
+#define FSMC_PCR4_TCLR_3 ((uint32_t)0x00001000) /*!<Bit 3 */
+
+#define FSMC_PCR4_TAR ((uint32_t)0x0001E000) /*!<TAR[3:0] bits (ALE to RE delay) */
+#define FSMC_PCR4_TAR_0 ((uint32_t)0x00002000) /*!<Bit 0 */
+#define FSMC_PCR4_TAR_1 ((uint32_t)0x00004000) /*!<Bit 1 */
+#define FSMC_PCR4_TAR_2 ((uint32_t)0x00008000) /*!<Bit 2 */
+#define FSMC_PCR4_TAR_3 ((uint32_t)0x00010000) /*!<Bit 3 */
+
+#define FSMC_PCR4_ECCPS ((uint32_t)0x000E0000) /*!<ECCPS[2:0] bits (ECC page size) */
+#define FSMC_PCR4_ECCPS_0 ((uint32_t)0x00020000) /*!<Bit 0 */
+#define FSMC_PCR4_ECCPS_1 ((uint32_t)0x00040000) /*!<Bit 1 */
+#define FSMC_PCR4_ECCPS_2 ((uint32_t)0x00080000) /*!<Bit 2 */
+
+/******************* Bit definition for FSMC_SR2 register *******************/
+#define FSMC_SR2_IRS ((uint8_t)0x01) /*!<Interrupt Rising Edge status */
+#define FSMC_SR2_ILS ((uint8_t)0x02) /*!<Interrupt Level status */
+#define FSMC_SR2_IFS ((uint8_t)0x04) /*!<Interrupt Falling Edge status */
+#define FSMC_SR2_IREN ((uint8_t)0x08) /*!<Interrupt Rising Edge detection Enable bit */
+#define FSMC_SR2_ILEN ((uint8_t)0x10) /*!<Interrupt Level detection Enable bit */
+#define FSMC_SR2_IFEN ((uint8_t)0x20) /*!<Interrupt Falling Edge detection Enable bit */
+#define FSMC_SR2_FEMPT ((uint8_t)0x40) /*!<FIFO empty */
+
+/******************* Bit definition for FSMC_SR3 register *******************/
+#define FSMC_SR3_IRS ((uint8_t)0x01) /*!<Interrupt Rising Edge status */
+#define FSMC_SR3_ILS ((uint8_t)0x02) /*!<Interrupt Level status */
+#define FSMC_SR3_IFS ((uint8_t)0x04) /*!<Interrupt Falling Edge status */
+#define FSMC_SR3_IREN ((uint8_t)0x08) /*!<Interrupt Rising Edge detection Enable bit */
+#define FSMC_SR3_ILEN ((uint8_t)0x10) /*!<Interrupt Level detection Enable bit */
+#define FSMC_SR3_IFEN ((uint8_t)0x20) /*!<Interrupt Falling Edge detection Enable bit */
+#define FSMC_SR3_FEMPT ((uint8_t)0x40) /*!<FIFO empty */
+
+/******************* Bit definition for FSMC_SR4 register *******************/
+#define FSMC_SR4_IRS ((uint8_t)0x01) /*!<Interrupt Rising Edge status */
+#define FSMC_SR4_ILS ((uint8_t)0x02) /*!<Interrupt Level status */
+#define FSMC_SR4_IFS ((uint8_t)0x04) /*!<Interrupt Falling Edge status */
+#define FSMC_SR4_IREN ((uint8_t)0x08) /*!<Interrupt Rising Edge detection Enable bit */
+#define FSMC_SR4_ILEN ((uint8_t)0x10) /*!<Interrupt Level detection Enable bit */
+#define FSMC_SR4_IFEN ((uint8_t)0x20) /*!<Interrupt Falling Edge detection Enable bit */
+#define FSMC_SR4_FEMPT ((uint8_t)0x40) /*!<FIFO empty */
+
+/****************** Bit definition for FSMC_PMEM2 register ******************/
+#define FSMC_PMEM2_MEMSET2 ((uint32_t)0x000000FF) /*!<MEMSET2[7:0] bits (Common memory 2 setup time) */
+#define FSMC_PMEM2_MEMSET2_0 ((uint32_t)0x00000001) /*!<Bit 0 */
+#define FSMC_PMEM2_MEMSET2_1 ((uint32_t)0x00000002) /*!<Bit 1 */
+#define FSMC_PMEM2_MEMSET2_2 ((uint32_t)0x00000004) /*!<Bit 2 */
+#define FSMC_PMEM2_MEMSET2_3 ((uint32_t)0x00000008) /*!<Bit 3 */
+#define FSMC_PMEM2_MEMSET2_4 ((uint32_t)0x00000010) /*!<Bit 4 */
+#define FSMC_PMEM2_MEMSET2_5 ((uint32_t)0x00000020) /*!<Bit 5 */
+#define FSMC_PMEM2_MEMSET2_6 ((uint32_t)0x00000040) /*!<Bit 6 */
+#define FSMC_PMEM2_MEMSET2_7 ((uint32_t)0x00000080) /*!<Bit 7 */
+
+#define FSMC_PMEM2_MEMWAIT2 ((uint32_t)0x0000FF00) /*!<MEMWAIT2[7:0] bits (Common memory 2 wait time) */
+#define FSMC_PMEM2_MEMWAIT2_0 ((uint32_t)0x00000100) /*!<Bit 0 */
+#define FSMC_PMEM2_MEMWAIT2_1 ((uint32_t)0x00000200) /*!<Bit 1 */
+#define FSMC_PMEM2_MEMWAIT2_2 ((uint32_t)0x00000400) /*!<Bit 2 */
+#define FSMC_PMEM2_MEMWAIT2_3 ((uint32_t)0x00000800) /*!<Bit 3 */
+#define FSMC_PMEM2_MEMWAIT2_4 ((uint32_t)0x00001000) /*!<Bit 4 */
+#define FSMC_PMEM2_MEMWAIT2_5 ((uint32_t)0x00002000) /*!<Bit 5 */
+#define FSMC_PMEM2_MEMWAIT2_6 ((uint32_t)0x00004000) /*!<Bit 6 */
+#define FSMC_PMEM2_MEMWAIT2_7 ((uint32_t)0x00008000) /*!<Bit 7 */
+
+#define FSMC_PMEM2_MEMHOLD2 ((uint32_t)0x00FF0000) /*!<MEMHOLD2[7:0] bits (Common memory 2 hold time) */
+#define FSMC_PMEM2_MEMHOLD2_0 ((uint32_t)0x00010000) /*!<Bit 0 */
+#define FSMC_PMEM2_MEMHOLD2_1 ((uint32_t)0x00020000) /*!<Bit 1 */
+#define FSMC_PMEM2_MEMHOLD2_2 ((uint32_t)0x00040000) /*!<Bit 2 */
+#define FSMC_PMEM2_MEMHOLD2_3 ((uint32_t)0x00080000) /*!<Bit 3 */
+#define FSMC_PMEM2_MEMHOLD2_4 ((uint32_t)0x00100000) /*!<Bit 4 */
+#define FSMC_PMEM2_MEMHOLD2_5 ((uint32_t)0x00200000) /*!<Bit 5 */
+#define FSMC_PMEM2_MEMHOLD2_6 ((uint32_t)0x00400000) /*!<Bit 6 */
+#define FSMC_PMEM2_MEMHOLD2_7 ((uint32_t)0x00800000) /*!<Bit 7 */
+
+#define FSMC_PMEM2_MEMHIZ2 ((uint32_t)0xFF000000) /*!<MEMHIZ2[7:0] bits (Common memory 2 databus HiZ time) */
+#define FSMC_PMEM2_MEMHIZ2_0 ((uint32_t)0x01000000) /*!<Bit 0 */
+#define FSMC_PMEM2_MEMHIZ2_1 ((uint32_t)0x02000000) /*!<Bit 1 */
+#define FSMC_PMEM2_MEMHIZ2_2 ((uint32_t)0x04000000) /*!<Bit 2 */
+#define FSMC_PMEM2_MEMHIZ2_3 ((uint32_t)0x08000000) /*!<Bit 3 */
+#define FSMC_PMEM2_MEMHIZ2_4 ((uint32_t)0x10000000) /*!<Bit 4 */
+#define FSMC_PMEM2_MEMHIZ2_5 ((uint32_t)0x20000000) /*!<Bit 5 */
+#define FSMC_PMEM2_MEMHIZ2_6 ((uint32_t)0x40000000) /*!<Bit 6 */
+#define FSMC_PMEM2_MEMHIZ2_7 ((uint32_t)0x80000000) /*!<Bit 7 */
+
+/****************** Bit definition for FSMC_PMEM3 register ******************/
+#define FSMC_PMEM3_MEMSET3 ((uint32_t)0x000000FF) /*!<MEMSET3[7:0] bits (Common memory 3 setup time) */
+#define FSMC_PMEM3_MEMSET3_0 ((uint32_t)0x00000001) /*!<Bit 0 */
+#define FSMC_PMEM3_MEMSET3_1 ((uint32_t)0x00000002) /*!<Bit 1 */
+#define FSMC_PMEM3_MEMSET3_2 ((uint32_t)0x00000004) /*!<Bit 2 */
+#define FSMC_PMEM3_MEMSET3_3 ((uint32_t)0x00000008) /*!<Bit 3 */
+#define FSMC_PMEM3_MEMSET3_4 ((uint32_t)0x00000010) /*!<Bit 4 */
+#define FSMC_PMEM3_MEMSET3_5 ((uint32_t)0x00000020) /*!<Bit 5 */
+#define FSMC_PMEM3_MEMSET3_6 ((uint32_t)0x00000040) /*!<Bit 6 */
+#define FSMC_PMEM3_MEMSET3_7 ((uint32_t)0x00000080) /*!<Bit 7 */
+
+#define FSMC_PMEM3_MEMWAIT3 ((uint32_t)0x0000FF00) /*!<MEMWAIT3[7:0] bits (Common memory 3 wait time) */
+#define FSMC_PMEM3_MEMWAIT3_0 ((uint32_t)0x00000100) /*!<Bit 0 */
+#define FSMC_PMEM3_MEMWAIT3_1 ((uint32_t)0x00000200) /*!<Bit 1 */
+#define FSMC_PMEM3_MEMWAIT3_2 ((uint32_t)0x00000400) /*!<Bit 2 */
+#define FSMC_PMEM3_MEMWAIT3_3 ((uint32_t)0x00000800) /*!<Bit 3 */
+#define FSMC_PMEM3_MEMWAIT3_4 ((uint32_t)0x00001000) /*!<Bit 4 */
+#define FSMC_PMEM3_MEMWAIT3_5 ((uint32_t)0x00002000) /*!<Bit 5 */
+#define FSMC_PMEM3_MEMWAIT3_6 ((uint32_t)0x00004000) /*!<Bit 6 */
+#define FSMC_PMEM3_MEMWAIT3_7 ((uint32_t)0x00008000) /*!<Bit 7 */
+
+#define FSMC_PMEM3_MEMHOLD3 ((uint32_t)0x00FF0000) /*!<MEMHOLD3[7:0] bits (Common memory 3 hold time) */
+#define FSMC_PMEM3_MEMHOLD3_0 ((uint32_t)0x00010000) /*!<Bit 0 */
+#define FSMC_PMEM3_MEMHOLD3_1 ((uint32_t)0x00020000) /*!<Bit 1 */
+#define FSMC_PMEM3_MEMHOLD3_2 ((uint32_t)0x00040000) /*!<Bit 2 */
+#define FSMC_PMEM3_MEMHOLD3_3 ((uint32_t)0x00080000) /*!<Bit 3 */
+#define FSMC_PMEM3_MEMHOLD3_4 ((uint32_t)0x00100000) /*!<Bit 4 */
+#define FSMC_PMEM3_MEMHOLD3_5 ((uint32_t)0x00200000) /*!<Bit 5 */
+#define FSMC_PMEM3_MEMHOLD3_6 ((uint32_t)0x00400000) /*!<Bit 6 */
+#define FSMC_PMEM3_MEMHOLD3_7 ((uint32_t)0x00800000) /*!<Bit 7 */
+
+#define FSMC_PMEM3_MEMHIZ3 ((uint32_t)0xFF000000) /*!<MEMHIZ3[7:0] bits (Common memory 3 databus HiZ time) */
+#define FSMC_PMEM3_MEMHIZ3_0 ((uint32_t)0x01000000) /*!<Bit 0 */
+#define FSMC_PMEM3_MEMHIZ3_1 ((uint32_t)0x02000000) /*!<Bit 1 */
+#define FSMC_PMEM3_MEMHIZ3_2 ((uint32_t)0x04000000) /*!<Bit 2 */
+#define FSMC_PMEM3_MEMHIZ3_3 ((uint32_t)0x08000000) /*!<Bit 3 */
+#define FSMC_PMEM3_MEMHIZ3_4 ((uint32_t)0x10000000) /*!<Bit 4 */
+#define FSMC_PMEM3_MEMHIZ3_5 ((uint32_t)0x20000000) /*!<Bit 5 */
+#define FSMC_PMEM3_MEMHIZ3_6 ((uint32_t)0x40000000) /*!<Bit 6 */
+#define FSMC_PMEM3_MEMHIZ3_7 ((uint32_t)0x80000000) /*!<Bit 7 */
+
+/****************** Bit definition for FSMC_PMEM4 register ******************/
+#define FSMC_PMEM4_MEMSET4 ((uint32_t)0x000000FF) /*!<MEMSET4[7:0] bits (Common memory 4 setup time) */
+#define FSMC_PMEM4_MEMSET4_0 ((uint32_t)0x00000001) /*!<Bit 0 */
+#define FSMC_PMEM4_MEMSET4_1 ((uint32_t)0x00000002) /*!<Bit 1 */
+#define FSMC_PMEM4_MEMSET4_2 ((uint32_t)0x00000004) /*!<Bit 2 */
+#define FSMC_PMEM4_MEMSET4_3 ((uint32_t)0x00000008) /*!<Bit 3 */
+#define FSMC_PMEM4_MEMSET4_4 ((uint32_t)0x00000010) /*!<Bit 4 */
+#define FSMC_PMEM4_MEMSET4_5 ((uint32_t)0x00000020) /*!<Bit 5 */
+#define FSMC_PMEM4_MEMSET4_6 ((uint32_t)0x00000040) /*!<Bit 6 */
+#define FSMC_PMEM4_MEMSET4_7 ((uint32_t)0x00000080) /*!<Bit 7 */
+
+#define FSMC_PMEM4_MEMWAIT4 ((uint32_t)0x0000FF00) /*!<MEMWAIT4[7:0] bits (Common memory 4 wait time) */
+#define FSMC_PMEM4_MEMWAIT4_0 ((uint32_t)0x00000100) /*!<Bit 0 */
+#define FSMC_PMEM4_MEMWAIT4_1 ((uint32_t)0x00000200) /*!<Bit 1 */
+#define FSMC_PMEM4_MEMWAIT4_2 ((uint32_t)0x00000400) /*!<Bit 2 */
+#define FSMC_PMEM4_MEMWAIT4_3 ((uint32_t)0x00000800) /*!<Bit 3 */
+#define FSMC_PMEM4_MEMWAIT4_4 ((uint32_t)0x00001000) /*!<Bit 4 */
+#define FSMC_PMEM4_MEMWAIT4_5 ((uint32_t)0x00002000) /*!<Bit 5 */
+#define FSMC_PMEM4_MEMWAIT4_6 ((uint32_t)0x00004000) /*!<Bit 6 */
+#define FSMC_PMEM4_MEMWAIT4_7 ((uint32_t)0x00008000) /*!<Bit 7 */
+
+#define FSMC_PMEM4_MEMHOLD4 ((uint32_t)0x00FF0000) /*!<MEMHOLD4[7:0] bits (Common memory 4 hold time) */
+#define FSMC_PMEM4_MEMHOLD4_0 ((uint32_t)0x00010000) /*!<Bit 0 */
+#define FSMC_PMEM4_MEMHOLD4_1 ((uint32_t)0x00020000) /*!<Bit 1 */
+#define FSMC_PMEM4_MEMHOLD4_2 ((uint32_t)0x00040000) /*!<Bit 2 */
+#define FSMC_PMEM4_MEMHOLD4_3 ((uint32_t)0x00080000) /*!<Bit 3 */
+#define FSMC_PMEM4_MEMHOLD4_4 ((uint32_t)0x00100000) /*!<Bit 4 */
+#define FSMC_PMEM4_MEMHOLD4_5 ((uint32_t)0x00200000) /*!<Bit 5 */
+#define FSMC_PMEM4_MEMHOLD4_6 ((uint32_t)0x00400000) /*!<Bit 6 */
+#define FSMC_PMEM4_MEMHOLD4_7 ((uint32_t)0x00800000) /*!<Bit 7 */
+
+#define FSMC_PMEM4_MEMHIZ4 ((uint32_t)0xFF000000) /*!<MEMHIZ4[7:0] bits (Common memory 4 databus HiZ time) */
+#define FSMC_PMEM4_MEMHIZ4_0 ((uint32_t)0x01000000) /*!<Bit 0 */
+#define FSMC_PMEM4_MEMHIZ4_1 ((uint32_t)0x02000000) /*!<Bit 1 */
+#define FSMC_PMEM4_MEMHIZ4_2 ((uint32_t)0x04000000) /*!<Bit 2 */
+#define FSMC_PMEM4_MEMHIZ4_3 ((uint32_t)0x08000000) /*!<Bit 3 */
+#define FSMC_PMEM4_MEMHIZ4_4 ((uint32_t)0x10000000) /*!<Bit 4 */
+#define FSMC_PMEM4_MEMHIZ4_5 ((uint32_t)0x20000000) /*!<Bit 5 */
+#define FSMC_PMEM4_MEMHIZ4_6 ((uint32_t)0x40000000) /*!<Bit 6 */
+#define FSMC_PMEM4_MEMHIZ4_7 ((uint32_t)0x80000000) /*!<Bit 7 */
+
+/****************** Bit definition for FSMC_PATT2 register ******************/
+#define FSMC_PATT2_ATTSET2 ((uint32_t)0x000000FF) /*!<ATTSET2[7:0] bits (Attribute memory 2 setup time) */
+#define FSMC_PATT2_ATTSET2_0 ((uint32_t)0x00000001) /*!<Bit 0 */
+#define FSMC_PATT2_ATTSET2_1 ((uint32_t)0x00000002) /*!<Bit 1 */
+#define FSMC_PATT2_ATTSET2_2 ((uint32_t)0x00000004) /*!<Bit 2 */
+#define FSMC_PATT2_ATTSET2_3 ((uint32_t)0x00000008) /*!<Bit 3 */
+#define FSMC_PATT2_ATTSET2_4 ((uint32_t)0x00000010) /*!<Bit 4 */
+#define FSMC_PATT2_ATTSET2_5 ((uint32_t)0x00000020) /*!<Bit 5 */
+#define FSMC_PATT2_ATTSET2_6 ((uint32_t)0x00000040) /*!<Bit 6 */
+#define FSMC_PATT2_ATTSET2_7 ((uint32_t)0x00000080) /*!<Bit 7 */
+
+#define FSMC_PATT2_ATTWAIT2 ((uint32_t)0x0000FF00) /*!<ATTWAIT2[7:0] bits (Attribute memory 2 wait time) */
+#define FSMC_PATT2_ATTWAIT2_0 ((uint32_t)0x00000100) /*!<Bit 0 */
+#define FSMC_PATT2_ATTWAIT2_1 ((uint32_t)0x00000200) /*!<Bit 1 */
+#define FSMC_PATT2_ATTWAIT2_2 ((uint32_t)0x00000400) /*!<Bit 2 */
+#define FSMC_PATT2_ATTWAIT2_3 ((uint32_t)0x00000800) /*!<Bit 3 */
+#define FSMC_PATT2_ATTWAIT2_4 ((uint32_t)0x00001000) /*!<Bit 4 */
+#define FSMC_PATT2_ATTWAIT2_5 ((uint32_t)0x00002000) /*!<Bit 5 */
+#define FSMC_PATT2_ATTWAIT2_6 ((uint32_t)0x00004000) /*!<Bit 6 */
+#define FSMC_PATT2_ATTWAIT2_7 ((uint32_t)0x00008000) /*!<Bit 7 */
+
+#define FSMC_PATT2_ATTHOLD2 ((uint32_t)0x00FF0000) /*!<ATTHOLD2[7:0] bits (Attribute memory 2 hold time) */
+#define FSMC_PATT2_ATTHOLD2_0 ((uint32_t)0x00010000) /*!<Bit 0 */
+#define FSMC_PATT2_ATTHOLD2_1 ((uint32_t)0x00020000) /*!<Bit 1 */
+#define FSMC_PATT2_ATTHOLD2_2 ((uint32_t)0x00040000) /*!<Bit 2 */
+#define FSMC_PATT2_ATTHOLD2_3 ((uint32_t)0x00080000) /*!<Bit 3 */
+#define FSMC_PATT2_ATTHOLD2_4 ((uint32_t)0x00100000) /*!<Bit 4 */
+#define FSMC_PATT2_ATTHOLD2_5 ((uint32_t)0x00200000) /*!<Bit 5 */
+#define FSMC_PATT2_ATTHOLD2_6 ((uint32_t)0x00400000) /*!<Bit 6 */
+#define FSMC_PATT2_ATTHOLD2_7 ((uint32_t)0x00800000) /*!<Bit 7 */
+
+#define FSMC_PATT2_ATTHIZ2 ((uint32_t)0xFF000000) /*!<ATTHIZ2[7:0] bits (Attribute memory 2 databus HiZ time) */
+#define FSMC_PATT2_ATTHIZ2_0 ((uint32_t)0x01000000) /*!<Bit 0 */
+#define FSMC_PATT2_ATTHIZ2_1 ((uint32_t)0x02000000) /*!<Bit 1 */
+#define FSMC_PATT2_ATTHIZ2_2 ((uint32_t)0x04000000) /*!<Bit 2 */
+#define FSMC_PATT2_ATTHIZ2_3 ((uint32_t)0x08000000) /*!<Bit 3 */
+#define FSMC_PATT2_ATTHIZ2_4 ((uint32_t)0x10000000) /*!<Bit 4 */
+#define FSMC_PATT2_ATTHIZ2_5 ((uint32_t)0x20000000) /*!<Bit 5 */
+#define FSMC_PATT2_ATTHIZ2_6 ((uint32_t)0x40000000) /*!<Bit 6 */
+#define FSMC_PATT2_ATTHIZ2_7 ((uint32_t)0x80000000) /*!<Bit 7 */
+
+/****************** Bit definition for FSMC_PATT3 register ******************/
+#define FSMC_PATT3_ATTSET3 ((uint32_t)0x000000FF) /*!<ATTSET3[7:0] bits (Attribute memory 3 setup time) */
+#define FSMC_PATT3_ATTSET3_0 ((uint32_t)0x00000001) /*!<Bit 0 */
+#define FSMC_PATT3_ATTSET3_1 ((uint32_t)0x00000002) /*!<Bit 1 */
+#define FSMC_PATT3_ATTSET3_2 ((uint32_t)0x00000004) /*!<Bit 2 */
+#define FSMC_PATT3_ATTSET3_3 ((uint32_t)0x00000008) /*!<Bit 3 */
+#define FSMC_PATT3_ATTSET3_4 ((uint32_t)0x00000010) /*!<Bit 4 */
+#define FSMC_PATT3_ATTSET3_5 ((uint32_t)0x00000020) /*!<Bit 5 */
+#define FSMC_PATT3_ATTSET3_6 ((uint32_t)0x00000040) /*!<Bit 6 */
+#define FSMC_PATT3_ATTSET3_7 ((uint32_t)0x00000080) /*!<Bit 7 */
+
+#define FSMC_PATT3_ATTWAIT3 ((uint32_t)0x0000FF00) /*!<ATTWAIT3[7:0] bits (Attribute memory 3 wait time) */
+#define FSMC_PATT3_ATTWAIT3_0 ((uint32_t)0x00000100) /*!<Bit 0 */
+#define FSMC_PATT3_ATTWAIT3_1 ((uint32_t)0x00000200) /*!<Bit 1 */
+#define FSMC_PATT3_ATTWAIT3_2 ((uint32_t)0x00000400) /*!<Bit 2 */
+#define FSMC_PATT3_ATTWAIT3_3 ((uint32_t)0x00000800) /*!<Bit 3 */
+#define FSMC_PATT3_ATTWAIT3_4 ((uint32_t)0x00001000) /*!<Bit 4 */
+#define FSMC_PATT3_ATTWAIT3_5 ((uint32_t)0x00002000) /*!<Bit 5 */
+#define FSMC_PATT3_ATTWAIT3_6 ((uint32_t)0x00004000) /*!<Bit 6 */
+#define FSMC_PATT3_ATTWAIT3_7 ((uint32_t)0x00008000) /*!<Bit 7 */
+
+#define FSMC_PATT3_ATTHOLD3 ((uint32_t)0x00FF0000) /*!<ATTHOLD3[7:0] bits (Attribute memory 3 hold time) */
+#define FSMC_PATT3_ATTHOLD3_0 ((uint32_t)0x00010000) /*!<Bit 0 */
+#define FSMC_PATT3_ATTHOLD3_1 ((uint32_t)0x00020000) /*!<Bit 1 */
+#define FSMC_PATT3_ATTHOLD3_2 ((uint32_t)0x00040000) /*!<Bit 2 */
+#define FSMC_PATT3_ATTHOLD3_3 ((uint32_t)0x00080000) /*!<Bit 3 */
+#define FSMC_PATT3_ATTHOLD3_4 ((uint32_t)0x00100000) /*!<Bit 4 */
+#define FSMC_PATT3_ATTHOLD3_5 ((uint32_t)0x00200000) /*!<Bit 5 */
+#define FSMC_PATT3_ATTHOLD3_6 ((uint32_t)0x00400000) /*!<Bit 6 */
+#define FSMC_PATT3_ATTHOLD3_7 ((uint32_t)0x00800000) /*!<Bit 7 */
+
+#define FSMC_PATT3_ATTHIZ3 ((uint32_t)0xFF000000) /*!<ATTHIZ3[7:0] bits (Attribute memory 3 databus HiZ time) */
+#define FSMC_PATT3_ATTHIZ3_0 ((uint32_t)0x01000000) /*!<Bit 0 */
+#define FSMC_PATT3_ATTHIZ3_1 ((uint32_t)0x02000000) /*!<Bit 1 */
+#define FSMC_PATT3_ATTHIZ3_2 ((uint32_t)0x04000000) /*!<Bit 2 */
+#define FSMC_PATT3_ATTHIZ3_3 ((uint32_t)0x08000000) /*!<Bit 3 */
+#define FSMC_PATT3_ATTHIZ3_4 ((uint32_t)0x10000000) /*!<Bit 4 */
+#define FSMC_PATT3_ATTHIZ3_5 ((uint32_t)0x20000000) /*!<Bit 5 */
+#define FSMC_PATT3_ATTHIZ3_6 ((uint32_t)0x40000000) /*!<Bit 6 */
+#define FSMC_PATT3_ATTHIZ3_7 ((uint32_t)0x80000000) /*!<Bit 7 */
+
+/****************** Bit definition for FSMC_PATT4 register ******************/
+#define FSMC_PATT4_ATTSET4 ((uint32_t)0x000000FF) /*!<ATTSET4[7:0] bits (Attribute memory 4 setup time) */
+#define FSMC_PATT4_ATTSET4_0 ((uint32_t)0x00000001) /*!<Bit 0 */
+#define FSMC_PATT4_ATTSET4_1 ((uint32_t)0x00000002) /*!<Bit 1 */
+#define FSMC_PATT4_ATTSET4_2 ((uint32_t)0x00000004) /*!<Bit 2 */
+#define FSMC_PATT4_ATTSET4_3 ((uint32_t)0x00000008) /*!<Bit 3 */
+#define FSMC_PATT4_ATTSET4_4 ((uint32_t)0x00000010) /*!<Bit 4 */
+#define FSMC_PATT4_ATTSET4_5 ((uint32_t)0x00000020) /*!<Bit 5 */
+#define FSMC_PATT4_ATTSET4_6 ((uint32_t)0x00000040) /*!<Bit 6 */
+#define FSMC_PATT4_ATTSET4_7 ((uint32_t)0x00000080) /*!<Bit 7 */
+
+#define FSMC_PATT4_ATTWAIT4 ((uint32_t)0x0000FF00) /*!<ATTWAIT4[7:0] bits (Attribute memory 4 wait time) */
+#define FSMC_PATT4_ATTWAIT4_0 ((uint32_t)0x00000100) /*!<Bit 0 */
+#define FSMC_PATT4_ATTWAIT4_1 ((uint32_t)0x00000200) /*!<Bit 1 */
+#define FSMC_PATT4_ATTWAIT4_2 ((uint32_t)0x00000400) /*!<Bit 2 */
+#define FSMC_PATT4_ATTWAIT4_3 ((uint32_t)0x00000800) /*!<Bit 3 */
+#define FSMC_PATT4_ATTWAIT4_4 ((uint32_t)0x00001000) /*!<Bit 4 */
+#define FSMC_PATT4_ATTWAIT4_5 ((uint32_t)0x00002000) /*!<Bit 5 */
+#define FSMC_PATT4_ATTWAIT4_6 ((uint32_t)0x00004000) /*!<Bit 6 */
+#define FSMC_PATT4_ATTWAIT4_7 ((uint32_t)0x00008000) /*!<Bit 7 */
+
+#define FSMC_PATT4_ATTHOLD4 ((uint32_t)0x00FF0000) /*!<ATTHOLD4[7:0] bits (Attribute memory 4 hold time) */
+#define FSMC_PATT4_ATTHOLD4_0 ((uint32_t)0x00010000) /*!<Bit 0 */
+#define FSMC_PATT4_ATTHOLD4_1 ((uint32_t)0x00020000) /*!<Bit 1 */
+#define FSMC_PATT4_ATTHOLD4_2 ((uint32_t)0x00040000) /*!<Bit 2 */
+#define FSMC_PATT4_ATTHOLD4_3 ((uint32_t)0x00080000) /*!<Bit 3 */
+#define FSMC_PATT4_ATTHOLD4_4 ((uint32_t)0x00100000) /*!<Bit 4 */
+#define FSMC_PATT4_ATTHOLD4_5 ((uint32_t)0x00200000) /*!<Bit 5 */
+#define FSMC_PATT4_ATTHOLD4_6 ((uint32_t)0x00400000) /*!<Bit 6 */
+#define FSMC_PATT4_ATTHOLD4_7 ((uint32_t)0x00800000) /*!<Bit 7 */
+
+#define FSMC_PATT4_ATTHIZ4 ((uint32_t)0xFF000000) /*!<ATTHIZ4[7:0] bits (Attribute memory 4 databus HiZ time) */
+#define FSMC_PATT4_ATTHIZ4_0 ((uint32_t)0x01000000) /*!<Bit 0 */
+#define FSMC_PATT4_ATTHIZ4_1 ((uint32_t)0x02000000) /*!<Bit 1 */
+#define FSMC_PATT4_ATTHIZ4_2 ((uint32_t)0x04000000) /*!<Bit 2 */
+#define FSMC_PATT4_ATTHIZ4_3 ((uint32_t)0x08000000) /*!<Bit 3 */
+#define FSMC_PATT4_ATTHIZ4_4 ((uint32_t)0x10000000) /*!<Bit 4 */
+#define FSMC_PATT4_ATTHIZ4_5 ((uint32_t)0x20000000) /*!<Bit 5 */
+#define FSMC_PATT4_ATTHIZ4_6 ((uint32_t)0x40000000) /*!<Bit 6 */
+#define FSMC_PATT4_ATTHIZ4_7 ((uint32_t)0x80000000) /*!<Bit 7 */
+
+/****************** Bit definition for FSMC_PIO4 register *******************/
+#define FSMC_PIO4_IOSET4 ((uint32_t)0x000000FF) /*!<IOSET4[7:0] bits (I/O 4 setup time) */
+#define FSMC_PIO4_IOSET4_0 ((uint32_t)0x00000001) /*!<Bit 0 */
+#define FSMC_PIO4_IOSET4_1 ((uint32_t)0x00000002) /*!<Bit 1 */
+#define FSMC_PIO4_IOSET4_2 ((uint32_t)0x00000004) /*!<Bit 2 */
+#define FSMC_PIO4_IOSET4_3 ((uint32_t)0x00000008) /*!<Bit 3 */
+#define FSMC_PIO4_IOSET4_4 ((uint32_t)0x00000010) /*!<Bit 4 */
+#define FSMC_PIO4_IOSET4_5 ((uint32_t)0x00000020) /*!<Bit 5 */
+#define FSMC_PIO4_IOSET4_6 ((uint32_t)0x00000040) /*!<Bit 6 */
+#define FSMC_PIO4_IOSET4_7 ((uint32_t)0x00000080) /*!<Bit 7 */
+
+#define FSMC_PIO4_IOWAIT4 ((uint32_t)0x0000FF00) /*!<IOWAIT4[7:0] bits (I/O 4 wait time) */
+#define FSMC_PIO4_IOWAIT4_0 ((uint32_t)0x00000100) /*!<Bit 0 */
+#define FSMC_PIO4_IOWAIT4_1 ((uint32_t)0x00000200) /*!<Bit 1 */
+#define FSMC_PIO4_IOWAIT4_2 ((uint32_t)0x00000400) /*!<Bit 2 */
+#define FSMC_PIO4_IOWAIT4_3 ((uint32_t)0x00000800) /*!<Bit 3 */
+#define FSMC_PIO4_IOWAIT4_4 ((uint32_t)0x00001000) /*!<Bit 4 */
+#define FSMC_PIO4_IOWAIT4_5 ((uint32_t)0x00002000) /*!<Bit 5 */
+#define FSMC_PIO4_IOWAIT4_6 ((uint32_t)0x00004000) /*!<Bit 6 */
+#define FSMC_PIO4_IOWAIT4_7 ((uint32_t)0x00008000) /*!<Bit 7 */
+
+#define FSMC_PIO4_IOHOLD4 ((uint32_t)0x00FF0000) /*!<IOHOLD4[7:0] bits (I/O 4 hold time) */
+#define FSMC_PIO4_IOHOLD4_0 ((uint32_t)0x00010000) /*!<Bit 0 */
+#define FSMC_PIO4_IOHOLD4_1 ((uint32_t)0x00020000) /*!<Bit 1 */
+#define FSMC_PIO4_IOHOLD4_2 ((uint32_t)0x00040000) /*!<Bit 2 */
+#define FSMC_PIO4_IOHOLD4_3 ((uint32_t)0x00080000) /*!<Bit 3 */
+#define FSMC_PIO4_IOHOLD4_4 ((uint32_t)0x00100000) /*!<Bit 4 */
+#define FSMC_PIO4_IOHOLD4_5 ((uint32_t)0x00200000) /*!<Bit 5 */
+#define FSMC_PIO4_IOHOLD4_6 ((uint32_t)0x00400000) /*!<Bit 6 */
+#define FSMC_PIO4_IOHOLD4_7 ((uint32_t)0x00800000) /*!<Bit 7 */
+
+#define FSMC_PIO4_IOHIZ4 ((uint32_t)0xFF000000) /*!<IOHIZ4[7:0] bits (I/O 4 databus HiZ time) */
+#define FSMC_PIO4_IOHIZ4_0 ((uint32_t)0x01000000) /*!<Bit 0 */
+#define FSMC_PIO4_IOHIZ4_1 ((uint32_t)0x02000000) /*!<Bit 1 */
+#define FSMC_PIO4_IOHIZ4_2 ((uint32_t)0x04000000) /*!<Bit 2 */
+#define FSMC_PIO4_IOHIZ4_3 ((uint32_t)0x08000000) /*!<Bit 3 */
+#define FSMC_PIO4_IOHIZ4_4 ((uint32_t)0x10000000) /*!<Bit 4 */
+#define FSMC_PIO4_IOHIZ4_5 ((uint32_t)0x20000000) /*!<Bit 5 */
+#define FSMC_PIO4_IOHIZ4_6 ((uint32_t)0x40000000) /*!<Bit 6 */
+#define FSMC_PIO4_IOHIZ4_7 ((uint32_t)0x80000000) /*!<Bit 7 */
+
+/****************** Bit definition for FSMC_ECCR2 register ******************/
+#define FSMC_ECCR2_ECC2 ((uint32_t)0xFFFFFFFF) /*!<ECC result */
+
+/****************** Bit definition for FSMC_ECCR3 register ******************/
+#define FSMC_ECCR3_ECC3 ((uint32_t)0xFFFFFFFF) /*!<ECC result */
+
+/******************************************************************************/
+/* */
+/* SD host Interface */
+/* */
+/******************************************************************************/
+
+/****************** Bit definition for SDIO_POWER register ******************/
+#define SDIO_POWER_PWRCTRL ((uint8_t)0x03) /*!<PWRCTRL[1:0] bits (Power supply control bits) */
+#define SDIO_POWER_PWRCTRL_0 ((uint8_t)0x01) /*!<Bit 0 */
+#define SDIO_POWER_PWRCTRL_1 ((uint8_t)0x02) /*!<Bit 1 */
+
+/****************** Bit definition for SDIO_CLKCR register ******************/
+#define SDIO_CLKCR_CLKDIV ((uint16_t)0x00FF) /*!<Clock divide factor */
+#define SDIO_CLKCR_CLKEN ((uint16_t)0x0100) /*!<Clock enable bit */
+#define SDIO_CLKCR_PWRSAV ((uint16_t)0x0200) /*!<Power saving configuration bit */
+#define SDIO_CLKCR_BYPASS ((uint16_t)0x0400) /*!<Clock divider bypass enable bit */
+
+#define SDIO_CLKCR_WIDBUS ((uint16_t)0x1800) /*!<WIDBUS[1:0] bits (Wide bus mode enable bit) */
+#define SDIO_CLKCR_WIDBUS_0 ((uint16_t)0x0800) /*!<Bit 0 */
+#define SDIO_CLKCR_WIDBUS_1 ((uint16_t)0x1000) /*!<Bit 1 */
+
+#define SDIO_CLKCR_NEGEDGE ((uint16_t)0x2000) /*!<SDIO_CK dephasing selection bit */
+#define SDIO_CLKCR_HWFC_EN ((uint16_t)0x4000) /*!<HW Flow Control enable */
+
+/******************* Bit definition for SDIO_ARG register *******************/
+#define SDIO_ARG_CMDARG ((uint32_t)0xFFFFFFFF) /*!<Command argument */
+
+/******************* Bit definition for SDIO_CMD register *******************/
+#define SDIO_CMD_CMDINDEX ((uint16_t)0x003F) /*!<Command Index */
+
+#define SDIO_CMD_WAITRESP ((uint16_t)0x00C0) /*!<WAITRESP[1:0] bits (Wait for response bits) */
+#define SDIO_CMD_WAITRESP_0 ((uint16_t)0x0040) /*!< Bit 0 */
+#define SDIO_CMD_WAITRESP_1 ((uint16_t)0x0080) /*!< Bit 1 */
+
+#define SDIO_CMD_WAITINT ((uint16_t)0x0100) /*!<CPSM Waits for Interrupt Request */
+#define SDIO_CMD_WAITPEND ((uint16_t)0x0200) /*!<CPSM Waits for ends of data transfer (CmdPend internal signal) */
+#define SDIO_CMD_CPSMEN ((uint16_t)0x0400) /*!<Command path state machine (CPSM) Enable bit */
+#define SDIO_CMD_SDIOSUSPEND ((uint16_t)0x0800) /*!<SD I/O suspend command */
+#define SDIO_CMD_ENCMDCOMPL ((uint16_t)0x1000) /*!<Enable CMD completion */
+#define SDIO_CMD_NIEN ((uint16_t)0x2000) /*!<Not Interrupt Enable */
+#define SDIO_CMD_CEATACMD ((uint16_t)0x4000) /*!<CE-ATA command */
+
+/***************** Bit definition for SDIO_RESPCMD register *****************/
+#define SDIO_RESPCMD_RESPCMD ((uint8_t)0x3F) /*!<Response command index */
+
+/****************** Bit definition for SDIO_RESP0 register ******************/
+#define SDIO_RESP0_CARDSTATUS0 ((uint32_t)0xFFFFFFFF) /*!<Card Status */
+
+/****************** Bit definition for SDIO_RESP1 register ******************/
+#define SDIO_RESP1_CARDSTATUS1 ((uint32_t)0xFFFFFFFF) /*!<Card Status */
+
+/****************** Bit definition for SDIO_RESP2 register ******************/
+#define SDIO_RESP2_CARDSTATUS2 ((uint32_t)0xFFFFFFFF) /*!<Card Status */
+
+/****************** Bit definition for SDIO_RESP3 register ******************/
+#define SDIO_RESP3_CARDSTATUS3 ((uint32_t)0xFFFFFFFF) /*!<Card Status */
+
+/****************** Bit definition for SDIO_RESP4 register ******************/
+#define SDIO_RESP4_CARDSTATUS4 ((uint32_t)0xFFFFFFFF) /*!<Card Status */
+
+/****************** Bit definition for SDIO_DTIMER register *****************/
+#define SDIO_DTIMER_DATATIME ((uint32_t)0xFFFFFFFF) /*!<Data timeout period. */
+
+/****************** Bit definition for SDIO_DLEN register *******************/
+#define SDIO_DLEN_DATALENGTH ((uint32_t)0x01FFFFFF) /*!<Data length value */
+
+/****************** Bit definition for SDIO_DCTRL register ******************/
+#define SDIO_DCTRL_DTEN ((uint16_t)0x0001) /*!<Data transfer enabled bit */
+#define SDIO_DCTRL_DTDIR ((uint16_t)0x0002) /*!<Data transfer direction selection */
+#define SDIO_DCTRL_DTMODE ((uint16_t)0x0004) /*!<Data transfer mode selection */
+#define SDIO_DCTRL_DMAEN ((uint16_t)0x0008) /*!<DMA enabled bit */
+
+#define SDIO_DCTRL_DBLOCKSIZE ((uint16_t)0x00F0) /*!<DBLOCKSIZE[3:0] bits (Data block size) */
+#define SDIO_DCTRL_DBLOCKSIZE_0 ((uint16_t)0x0010) /*!<Bit 0 */
+#define SDIO_DCTRL_DBLOCKSIZE_1 ((uint16_t)0x0020) /*!<Bit 1 */
+#define SDIO_DCTRL_DBLOCKSIZE_2 ((uint16_t)0x0040) /*!<Bit 2 */
+#define SDIO_DCTRL_DBLOCKSIZE_3 ((uint16_t)0x0080) /*!<Bit 3 */
+
+#define SDIO_DCTRL_RWSTART ((uint16_t)0x0100) /*!<Read wait start */
+#define SDIO_DCTRL_RWSTOP ((uint16_t)0x0200) /*!<Read wait stop */
+#define SDIO_DCTRL_RWMOD ((uint16_t)0x0400) /*!<Read wait mode */
+#define SDIO_DCTRL_SDIOEN ((uint16_t)0x0800) /*!<SD I/O enable functions */
+
+/****************** Bit definition for SDIO_DCOUNT register *****************/
+#define SDIO_DCOUNT_DATACOUNT ((uint32_t)0x01FFFFFF) /*!<Data count value */
+
+/****************** Bit definition for SDIO_STA register ********************/
+#define SDIO_STA_CCRCFAIL ((uint32_t)0x00000001) /*!<Command response received (CRC check failed) */
+#define SDIO_STA_DCRCFAIL ((uint32_t)0x00000002) /*!<Data block sent/received (CRC check failed) */
+#define SDIO_STA_CTIMEOUT ((uint32_t)0x00000004) /*!<Command response timeout */
+#define SDIO_STA_DTIMEOUT ((uint32_t)0x00000008) /*!<Data timeout */
+#define SDIO_STA_TXUNDERR ((uint32_t)0x00000010) /*!<Transmit FIFO underrun error */
+#define SDIO_STA_RXOVERR ((uint32_t)0x00000020) /*!<Received FIFO overrun error */
+#define SDIO_STA_CMDREND ((uint32_t)0x00000040) /*!<Command response received (CRC check passed) */
+#define SDIO_STA_CMDSENT ((uint32_t)0x00000080) /*!<Command sent (no response required) */
+#define SDIO_STA_DATAEND ((uint32_t)0x00000100) /*!<Data end (data counter, SDIDCOUNT, is zero) */
+#define SDIO_STA_STBITERR ((uint32_t)0x00000200) /*!<Start bit not detected on all data signals in wide bus mode */
+#define SDIO_STA_DBCKEND ((uint32_t)0x00000400) /*!<Data block sent/received (CRC check passed) */
+#define SDIO_STA_CMDACT ((uint32_t)0x00000800) /*!<Command transfer in progress */
+#define SDIO_STA_TXACT ((uint32_t)0x00001000) /*!<Data transmit in progress */
+#define SDIO_STA_RXACT ((uint32_t)0x00002000) /*!<Data receive in progress */
+#define SDIO_STA_TXFIFOHE ((uint32_t)0x00004000) /*!<Transmit FIFO Half Empty: at least 8 words can be written into the FIFO */
+#define SDIO_STA_RXFIFOHF ((uint32_t)0x00008000) /*!<Receive FIFO Half Full: there are at least 8 words in the FIFO */
+#define SDIO_STA_TXFIFOF ((uint32_t)0x00010000) /*!<Transmit FIFO full */
+#define SDIO_STA_RXFIFOF ((uint32_t)0x00020000) /*!<Receive FIFO full */
+#define SDIO_STA_TXFIFOE ((uint32_t)0x00040000) /*!<Transmit FIFO empty */
+#define SDIO_STA_RXFIFOE ((uint32_t)0x00080000) /*!<Receive FIFO empty */
+#define SDIO_STA_TXDAVL ((uint32_t)0x00100000) /*!<Data available in transmit FIFO */
+#define SDIO_STA_RXDAVL ((uint32_t)0x00200000) /*!<Data available in receive FIFO */
+#define SDIO_STA_SDIOIT ((uint32_t)0x00400000) /*!<SDIO interrupt received */
+#define SDIO_STA_CEATAEND ((uint32_t)0x00800000) /*!<CE-ATA command completion signal received for CMD61 */
+
+/******************* Bit definition for SDIO_ICR register *******************/
+#define SDIO_ICR_CCRCFAILC ((uint32_t)0x00000001) /*!<CCRCFAIL flag clear bit */
+#define SDIO_ICR_DCRCFAILC ((uint32_t)0x00000002) /*!<DCRCFAIL flag clear bit */
+#define SDIO_ICR_CTIMEOUTC ((uint32_t)0x00000004) /*!<CTIMEOUT flag clear bit */
+#define SDIO_ICR_DTIMEOUTC ((uint32_t)0x00000008) /*!<DTIMEOUT flag clear bit */
+#define SDIO_ICR_TXUNDERRC ((uint32_t)0x00000010) /*!<TXUNDERR flag clear bit */
+#define SDIO_ICR_RXOVERRC ((uint32_t)0x00000020) /*!<RXOVERR flag clear bit */
+#define SDIO_ICR_CMDRENDC ((uint32_t)0x00000040) /*!<CMDREND flag clear bit */
+#define SDIO_ICR_CMDSENTC ((uint32_t)0x00000080) /*!<CMDSENT flag clear bit */
+#define SDIO_ICR_DATAENDC ((uint32_t)0x00000100) /*!<DATAEND flag clear bit */
+#define SDIO_ICR_STBITERRC ((uint32_t)0x00000200) /*!<STBITERR flag clear bit */
+#define SDIO_ICR_DBCKENDC ((uint32_t)0x00000400) /*!<DBCKEND flag clear bit */
+#define SDIO_ICR_SDIOITC ((uint32_t)0x00400000) /*!<SDIOIT flag clear bit */
+#define SDIO_ICR_CEATAENDC ((uint32_t)0x00800000) /*!<CEATAEND flag clear bit */
+
+/****************** Bit definition for SDIO_MASK register *******************/
+#define SDIO_MASK_CCRCFAILIE ((uint32_t)0x00000001) /*!<Command CRC Fail Interrupt Enable */
+#define SDIO_MASK_DCRCFAILIE ((uint32_t)0x00000002) /*!<Data CRC Fail Interrupt Enable */
+#define SDIO_MASK_CTIMEOUTIE ((uint32_t)0x00000004) /*!<Command TimeOut Interrupt Enable */
+#define SDIO_MASK_DTIMEOUTIE ((uint32_t)0x00000008) /*!<Data TimeOut Interrupt Enable */
+#define SDIO_MASK_TXUNDERRIE ((uint32_t)0x00000010) /*!<Tx FIFO UnderRun Error Interrupt Enable */
+#define SDIO_MASK_RXOVERRIE ((uint32_t)0x00000020) /*!<Rx FIFO OverRun Error Interrupt Enable */
+#define SDIO_MASK_CMDRENDIE ((uint32_t)0x00000040) /*!<Command Response Received Interrupt Enable */
+#define SDIO_MASK_CMDSENTIE ((uint32_t)0x00000080) /*!<Command Sent Interrupt Enable */
+#define SDIO_MASK_DATAENDIE ((uint32_t)0x00000100) /*!<Data End Interrupt Enable */
+#define SDIO_MASK_STBITERRIE ((uint32_t)0x00000200) /*!<Start Bit Error Interrupt Enable */
+#define SDIO_MASK_DBCKENDIE ((uint32_t)0x00000400) /*!<Data Block End Interrupt Enable */
+#define SDIO_MASK_CMDACTIE ((uint32_t)0x00000800) /*!<CCommand Acting Interrupt Enable */
+#define SDIO_MASK_TXACTIE ((uint32_t)0x00001000) /*!<Data Transmit Acting Interrupt Enable */
+#define SDIO_MASK_RXACTIE ((uint32_t)0x00002000) /*!<Data receive acting interrupt enabled */
+#define SDIO_MASK_TXFIFOHEIE ((uint32_t)0x00004000) /*!<Tx FIFO Half Empty interrupt Enable */
+#define SDIO_MASK_RXFIFOHFIE ((uint32_t)0x00008000) /*!<Rx FIFO Half Full interrupt Enable */
+#define SDIO_MASK_TXFIFOFIE ((uint32_t)0x00010000) /*!<Tx FIFO Full interrupt Enable */
+#define SDIO_MASK_RXFIFOFIE ((uint32_t)0x00020000) /*!<Rx FIFO Full interrupt Enable */
+#define SDIO_MASK_TXFIFOEIE ((uint32_t)0x00040000) /*!<Tx FIFO Empty interrupt Enable */
+#define SDIO_MASK_RXFIFOEIE ((uint32_t)0x00080000) /*!<Rx FIFO Empty interrupt Enable */
+#define SDIO_MASK_TXDAVLIE ((uint32_t)0x00100000) /*!<Data available in Tx FIFO interrupt Enable */
+#define SDIO_MASK_RXDAVLIE ((uint32_t)0x00200000) /*!<Data available in Rx FIFO interrupt Enable */
+#define SDIO_MASK_SDIOITIE ((uint32_t)0x00400000) /*!<SDIO Mode Interrupt Received interrupt Enable */
+#define SDIO_MASK_CEATAENDIE ((uint32_t)0x00800000) /*!<CE-ATA command completion signal received Interrupt Enable */
+
+/***************** Bit definition for SDIO_FIFOCNT register *****************/
+#define SDIO_FIFOCNT_FIFOCOUNT ((uint32_t)0x00FFFFFF) /*!<Remaining number of words to be written to or read from the FIFO */
+
+/****************** Bit definition for SDIO_FIFO register *******************/
+#define SDIO_FIFO_FIFODATA ((uint32_t)0xFFFFFFFF) /*!<Receive and transmit FIFO data */
+
+/******************************************************************************/
+/* */
+/* USB Device FS */
+/* */
+/******************************************************************************/
+
+/*!<Endpoint-specific registers */
+/******************* Bit definition for USB_EP0R register *******************/
+#define USB_EP0R_EA ((uint16_t)0x000F) /*!<Endpoint Address */
+
+#define USB_EP0R_STAT_TX ((uint16_t)0x0030) /*!<STAT_TX[1:0] bits (Status bits, for transmission transfers) */
+#define USB_EP0R_STAT_TX_0 ((uint16_t)0x0010) /*!<Bit 0 */
+#define USB_EP0R_STAT_TX_1 ((uint16_t)0x0020) /*!<Bit 1 */
+
+#define USB_EP0R_DTOG_TX ((uint16_t)0x0040) /*!<Data Toggle, for transmission transfers */
+#define USB_EP0R_CTR_TX ((uint16_t)0x0080) /*!<Correct Transfer for transmission */
+#define USB_EP0R_EP_KIND ((uint16_t)0x0100) /*!<Endpoint Kind */
+
+#define USB_EP0R_EP_TYPE ((uint16_t)0x0600) /*!<EP_TYPE[1:0] bits (Endpoint type) */
+#define USB_EP0R_EP_TYPE_0 ((uint16_t)0x0200) /*!<Bit 0 */
+#define USB_EP0R_EP_TYPE_1 ((uint16_t)0x0400) /*!<Bit 1 */
+
+#define USB_EP0R_SETUP ((uint16_t)0x0800) /*!<Setup transaction completed */
+
+#define USB_EP0R_STAT_RX ((uint16_t)0x3000) /*!<STAT_RX[1:0] bits (Status bits, for reception transfers) */
+#define USB_EP0R_STAT_RX_0 ((uint16_t)0x1000) /*!<Bit 0 */
+#define USB_EP0R_STAT_RX_1 ((uint16_t)0x2000) /*!<Bit 1 */
+
+#define USB_EP0R_DTOG_RX ((uint16_t)0x4000) /*!<Data Toggle, for reception transfers */
+#define USB_EP0R_CTR_RX ((uint16_t)0x8000) /*!<Correct Transfer for reception */
+
+/******************* Bit definition for USB_EP1R register *******************/
+#define USB_EP1R_EA ((uint16_t)0x000F) /*!<Endpoint Address */
+
+#define USB_EP1R_STAT_TX ((uint16_t)0x0030) /*!<STAT_TX[1:0] bits (Status bits, for transmission transfers) */
+#define USB_EP1R_STAT_TX_0 ((uint16_t)0x0010) /*!<Bit 0 */
+#define USB_EP1R_STAT_TX_1 ((uint16_t)0x0020) /*!<Bit 1 */
+
+#define USB_EP1R_DTOG_TX ((uint16_t)0x0040) /*!<Data Toggle, for transmission transfers */
+#define USB_EP1R_CTR_TX ((uint16_t)0x0080) /*!<Correct Transfer for transmission */
+#define USB_EP1R_EP_KIND ((uint16_t)0x0100) /*!<Endpoint Kind */
+
+#define USB_EP1R_EP_TYPE ((uint16_t)0x0600) /*!<EP_TYPE[1:0] bits (Endpoint type) */
+#define USB_EP1R_EP_TYPE_0 ((uint16_t)0x0200) /*!<Bit 0 */
+#define USB_EP1R_EP_TYPE_1 ((uint16_t)0x0400) /*!<Bit 1 */
+
+#define USB_EP1R_SETUP ((uint16_t)0x0800) /*!<Setup transaction completed */
+
+#define USB_EP1R_STAT_RX ((uint16_t)0x3000) /*!<STAT_RX[1:0] bits (Status bits, for reception transfers) */
+#define USB_EP1R_STAT_RX_0 ((uint16_t)0x1000) /*!<Bit 0 */
+#define USB_EP1R_STAT_RX_1 ((uint16_t)0x2000) /*!<Bit 1 */
+
+#define USB_EP1R_DTOG_RX ((uint16_t)0x4000) /*!<Data Toggle, for reception transfers */
+#define USB_EP1R_CTR_RX ((uint16_t)0x8000) /*!<Correct Transfer for reception */
+
+/******************* Bit definition for USB_EP2R register *******************/
+#define USB_EP2R_EA ((uint16_t)0x000F) /*!<Endpoint Address */
+
+#define USB_EP2R_STAT_TX ((uint16_t)0x0030) /*!<STAT_TX[1:0] bits (Status bits, for transmission transfers) */
+#define USB_EP2R_STAT_TX_0 ((uint16_t)0x0010) /*!<Bit 0 */
+#define USB_EP2R_STAT_TX_1 ((uint16_t)0x0020) /*!<Bit 1 */
+
+#define USB_EP2R_DTOG_TX ((uint16_t)0x0040) /*!<Data Toggle, for transmission transfers */
+#define USB_EP2R_CTR_TX ((uint16_t)0x0080) /*!<Correct Transfer for transmission */
+#define USB_EP2R_EP_KIND ((uint16_t)0x0100) /*!<Endpoint Kind */
+
+#define USB_EP2R_EP_TYPE ((uint16_t)0x0600) /*!<EP_TYPE[1:0] bits (Endpoint type) */
+#define USB_EP2R_EP_TYPE_0 ((uint16_t)0x0200) /*!<Bit 0 */
+#define USB_EP2R_EP_TYPE_1 ((uint16_t)0x0400) /*!<Bit 1 */
+
+#define USB_EP2R_SETUP ((uint16_t)0x0800) /*!<Setup transaction completed */
+
+#define USB_EP2R_STAT_RX ((uint16_t)0x3000) /*!<STAT_RX[1:0] bits (Status bits, for reception transfers) */
+#define USB_EP2R_STAT_RX_0 ((uint16_t)0x1000) /*!<Bit 0 */
+#define USB_EP2R_STAT_RX_1 ((uint16_t)0x2000) /*!<Bit 1 */
+
+#define USB_EP2R_DTOG_RX ((uint16_t)0x4000) /*!<Data Toggle, for reception transfers */
+#define USB_EP2R_CTR_RX ((uint16_t)0x8000) /*!<Correct Transfer for reception */
+
+/******************* Bit definition for USB_EP3R register *******************/
+#define USB_EP3R_EA ((uint16_t)0x000F) /*!<Endpoint Address */
+
+#define USB_EP3R_STAT_TX ((uint16_t)0x0030) /*!<STAT_TX[1:0] bits (Status bits, for transmission transfers) */
+#define USB_EP3R_STAT_TX_0 ((uint16_t)0x0010) /*!<Bit 0 */
+#define USB_EP3R_STAT_TX_1 ((uint16_t)0x0020) /*!<Bit 1 */
+
+#define USB_EP3R_DTOG_TX ((uint16_t)0x0040) /*!<Data Toggle, for transmission transfers */
+#define USB_EP3R_CTR_TX ((uint16_t)0x0080) /*!<Correct Transfer for transmission */
+#define USB_EP3R_EP_KIND ((uint16_t)0x0100) /*!<Endpoint Kind */
+
+#define USB_EP3R_EP_TYPE ((uint16_t)0x0600) /*!<EP_TYPE[1:0] bits (Endpoint type) */
+#define USB_EP3R_EP_TYPE_0 ((uint16_t)0x0200) /*!<Bit 0 */
+#define USB_EP3R_EP_TYPE_1 ((uint16_t)0x0400) /*!<Bit 1 */
+
+#define USB_EP3R_SETUP ((uint16_t)0x0800) /*!<Setup transaction completed */
+
+#define USB_EP3R_STAT_RX ((uint16_t)0x3000) /*!<STAT_RX[1:0] bits (Status bits, for reception transfers) */
+#define USB_EP3R_STAT_RX_0 ((uint16_t)0x1000) /*!<Bit 0 */
+#define USB_EP3R_STAT_RX_1 ((uint16_t)0x2000) /*!<Bit 1 */
+
+#define USB_EP3R_DTOG_RX ((uint16_t)0x4000) /*!<Data Toggle, for reception transfers */
+#define USB_EP3R_CTR_RX ((uint16_t)0x8000) /*!<Correct Transfer for reception */
+
+/******************* Bit definition for USB_EP4R register *******************/
+#define USB_EP4R_EA ((uint16_t)0x000F) /*!<Endpoint Address */
+
+#define USB_EP4R_STAT_TX ((uint16_t)0x0030) /*!<STAT_TX[1:0] bits (Status bits, for transmission transfers) */
+#define USB_EP4R_STAT_TX_0 ((uint16_t)0x0010) /*!<Bit 0 */
+#define USB_EP4R_STAT_TX_1 ((uint16_t)0x0020) /*!<Bit 1 */
+
+#define USB_EP4R_DTOG_TX ((uint16_t)0x0040) /*!<Data Toggle, for transmission transfers */
+#define USB_EP4R_CTR_TX ((uint16_t)0x0080) /*!<Correct Transfer for transmission */
+#define USB_EP4R_EP_KIND ((uint16_t)0x0100) /*!<Endpoint Kind */
+
+#define USB_EP4R_EP_TYPE ((uint16_t)0x0600) /*!<EP_TYPE[1:0] bits (Endpoint type) */
+#define USB_EP4R_EP_TYPE_0 ((uint16_t)0x0200) /*!<Bit 0 */
+#define USB_EP4R_EP_TYPE_1 ((uint16_t)0x0400) /*!<Bit 1 */
+
+#define USB_EP4R_SETUP ((uint16_t)0x0800) /*!<Setup transaction completed */
+
+#define USB_EP4R_STAT_RX ((uint16_t)0x3000) /*!<STAT_RX[1:0] bits (Status bits, for reception transfers) */
+#define USB_EP4R_STAT_RX_0 ((uint16_t)0x1000) /*!<Bit 0 */
+#define USB_EP4R_STAT_RX_1 ((uint16_t)0x2000) /*!<Bit 1 */
+
+#define USB_EP4R_DTOG_RX ((uint16_t)0x4000) /*!<Data Toggle, for reception transfers */
+#define USB_EP4R_CTR_RX ((uint16_t)0x8000) /*!<Correct Transfer for reception */
+
+/******************* Bit definition for USB_EP5R register *******************/
+#define USB_EP5R_EA ((uint16_t)0x000F) /*!<Endpoint Address */
+
+#define USB_EP5R_STAT_TX ((uint16_t)0x0030) /*!<STAT_TX[1:0] bits (Status bits, for transmission transfers) */
+#define USB_EP5R_STAT_TX_0 ((uint16_t)0x0010) /*!<Bit 0 */
+#define USB_EP5R_STAT_TX_1 ((uint16_t)0x0020) /*!<Bit 1 */
+
+#define USB_EP5R_DTOG_TX ((uint16_t)0x0040) /*!<Data Toggle, for transmission transfers */
+#define USB_EP5R_CTR_TX ((uint16_t)0x0080) /*!<Correct Transfer for transmission */
+#define USB_EP5R_EP_KIND ((uint16_t)0x0100) /*!<Endpoint Kind */
+
+#define USB_EP5R_EP_TYPE ((uint16_t)0x0600) /*!<EP_TYPE[1:0] bits (Endpoint type) */
+#define USB_EP5R_EP_TYPE_0 ((uint16_t)0x0200) /*!<Bit 0 */
+#define USB_EP5R_EP_TYPE_1 ((uint16_t)0x0400) /*!<Bit 1 */
+
+#define USB_EP5R_SETUP ((uint16_t)0x0800) /*!<Setup transaction completed */
+
+#define USB_EP5R_STAT_RX ((uint16_t)0x3000) /*!<STAT_RX[1:0] bits (Status bits, for reception transfers) */
+#define USB_EP5R_STAT_RX_0 ((uint16_t)0x1000) /*!<Bit 0 */
+#define USB_EP5R_STAT_RX_1 ((uint16_t)0x2000) /*!<Bit 1 */
+
+#define USB_EP5R_DTOG_RX ((uint16_t)0x4000) /*!<Data Toggle, for reception transfers */
+#define USB_EP5R_CTR_RX ((uint16_t)0x8000) /*!<Correct Transfer for reception */
+
+/******************* Bit definition for USB_EP6R register *******************/
+#define USB_EP6R_EA ((uint16_t)0x000F) /*!<Endpoint Address */
+
+#define USB_EP6R_STAT_TX ((uint16_t)0x0030) /*!<STAT_TX[1:0] bits (Status bits, for transmission transfers) */
+#define USB_EP6R_STAT_TX_0 ((uint16_t)0x0010) /*!<Bit 0 */
+#define USB_EP6R_STAT_TX_1 ((uint16_t)0x0020) /*!<Bit 1 */
+
+#define USB_EP6R_DTOG_TX ((uint16_t)0x0040) /*!<Data Toggle, for transmission transfers */
+#define USB_EP6R_CTR_TX ((uint16_t)0x0080) /*!<Correct Transfer for transmission */
+#define USB_EP6R_EP_KIND ((uint16_t)0x0100) /*!<Endpoint Kind */
+
+#define USB_EP6R_EP_TYPE ((uint16_t)0x0600) /*!<EP_TYPE[1:0] bits (Endpoint type) */
+#define USB_EP6R_EP_TYPE_0 ((uint16_t)0x0200) /*!<Bit 0 */
+#define USB_EP6R_EP_TYPE_1 ((uint16_t)0x0400) /*!<Bit 1 */
+
+#define USB_EP6R_SETUP ((uint16_t)0x0800) /*!<Setup transaction completed */
+
+#define USB_EP6R_STAT_RX ((uint16_t)0x3000) /*!<STAT_RX[1:0] bits (Status bits, for reception transfers) */
+#define USB_EP6R_STAT_RX_0 ((uint16_t)0x1000) /*!<Bit 0 */
+#define USB_EP6R_STAT_RX_1 ((uint16_t)0x2000) /*!<Bit 1 */
+
+#define USB_EP6R_DTOG_RX ((uint16_t)0x4000) /*!<Data Toggle, for reception transfers */
+#define USB_EP6R_CTR_RX ((uint16_t)0x8000) /*!<Correct Transfer for reception */
+
+/******************* Bit definition for USB_EP7R register *******************/
+#define USB_EP7R_EA ((uint16_t)0x000F) /*!<Endpoint Address */
+
+#define USB_EP7R_STAT_TX ((uint16_t)0x0030) /*!<STAT_TX[1:0] bits (Status bits, for transmission transfers) */
+#define USB_EP7R_STAT_TX_0 ((uint16_t)0x0010) /*!<Bit 0 */
+#define USB_EP7R_STAT_TX_1 ((uint16_t)0x0020) /*!<Bit 1 */
+
+#define USB_EP7R_DTOG_TX ((uint16_t)0x0040) /*!<Data Toggle, for transmission transfers */
+#define USB_EP7R_CTR_TX ((uint16_t)0x0080) /*!<Correct Transfer for transmission */
+#define USB_EP7R_EP_KIND ((uint16_t)0x0100) /*!<Endpoint Kind */
+
+#define USB_EP7R_EP_TYPE ((uint16_t)0x0600) /*!<EP_TYPE[1:0] bits (Endpoint type) */
+#define USB_EP7R_EP_TYPE_0 ((uint16_t)0x0200) /*!<Bit 0 */
+#define USB_EP7R_EP_TYPE_1 ((uint16_t)0x0400) /*!<Bit 1 */
+
+#define USB_EP7R_SETUP ((uint16_t)0x0800) /*!<Setup transaction completed */
+
+#define USB_EP7R_STAT_RX ((uint16_t)0x3000) /*!<STAT_RX[1:0] bits (Status bits, for reception transfers) */
+#define USB_EP7R_STAT_RX_0 ((uint16_t)0x1000) /*!<Bit 0 */
+#define USB_EP7R_STAT_RX_1 ((uint16_t)0x2000) /*!<Bit 1 */
+
+#define USB_EP7R_DTOG_RX ((uint16_t)0x4000) /*!<Data Toggle, for reception transfers */
+#define USB_EP7R_CTR_RX ((uint16_t)0x8000) /*!<Correct Transfer for reception */
+
+/*!<Common registers */
+/******************* Bit definition for USB_CNTR register *******************/
+#define USB_CNTR_FRES ((uint16_t)0x0001) /*!<Force USB Reset */
+#define USB_CNTR_PDWN ((uint16_t)0x0002) /*!<Power down */
+#define USB_CNTR_LP_MODE ((uint16_t)0x0004) /*!<Low-power mode */
+#define USB_CNTR_FSUSP ((uint16_t)0x0008) /*!<Force suspend */
+#define USB_CNTR_RESUME ((uint16_t)0x0010) /*!<Resume request */
+#define USB_CNTR_ESOFM ((uint16_t)0x0100) /*!<Expected Start Of Frame Interrupt Mask */
+#define USB_CNTR_SOFM ((uint16_t)0x0200) /*!<Start Of Frame Interrupt Mask */
+#define USB_CNTR_RESETM ((uint16_t)0x0400) /*!<RESET Interrupt Mask */
+#define USB_CNTR_SUSPM ((uint16_t)0x0800) /*!<Suspend mode Interrupt Mask */
+#define USB_CNTR_WKUPM ((uint16_t)0x1000) /*!<Wakeup Interrupt Mask */
+#define USB_CNTR_ERRM ((uint16_t)0x2000) /*!<Error Interrupt Mask */
+#define USB_CNTR_PMAOVRM ((uint16_t)0x4000) /*!<Packet Memory Area Over / Underrun Interrupt Mask */
+#define USB_CNTR_CTRM ((uint16_t)0x8000) /*!<Correct Transfer Interrupt Mask */
+
+/******************* Bit definition for USB_ISTR register *******************/
+#define USB_ISTR_EP_ID ((uint16_t)0x000F) /*!<Endpoint Identifier */
+#define USB_ISTR_DIR ((uint16_t)0x0010) /*!<Direction of transaction */
+#define USB_ISTR_ESOF ((uint16_t)0x0100) /*!<Expected Start Of Frame */
+#define USB_ISTR_SOF ((uint16_t)0x0200) /*!<Start Of Frame */
+#define USB_ISTR_RESET ((uint16_t)0x0400) /*!<USB RESET request */
+#define USB_ISTR_SUSP ((uint16_t)0x0800) /*!<Suspend mode request */
+#define USB_ISTR_WKUP ((uint16_t)0x1000) /*!<Wake up */
+#define USB_ISTR_ERR ((uint16_t)0x2000) /*!<Error */
+#define USB_ISTR_PMAOVR ((uint16_t)0x4000) /*!<Packet Memory Area Over / Underrun */
+#define USB_ISTR_CTR ((uint16_t)0x8000) /*!<Correct Transfer */
+
+/******************* Bit definition for USB_FNR register ********************/
+#define USB_FNR_FN ((uint16_t)0x07FF) /*!<Frame Number */
+#define USB_FNR_LSOF ((uint16_t)0x1800) /*!<Lost SOF */
+#define USB_FNR_LCK ((uint16_t)0x2000) /*!<Locked */
+#define USB_FNR_RXDM ((uint16_t)0x4000) /*!<Receive Data - Line Status */
+#define USB_FNR_RXDP ((uint16_t)0x8000) /*!<Receive Data + Line Status */
+
+/****************** Bit definition for USB_DADDR register *******************/
+#define USB_DADDR_ADD ((uint8_t)0x7F) /*!<ADD[6:0] bits (Device Address) */
+#define USB_DADDR_ADD0 ((uint8_t)0x01) /*!<Bit 0 */
+#define USB_DADDR_ADD1 ((uint8_t)0x02) /*!<Bit 1 */
+#define USB_DADDR_ADD2 ((uint8_t)0x04) /*!<Bit 2 */
+#define USB_DADDR_ADD3 ((uint8_t)0x08) /*!<Bit 3 */
+#define USB_DADDR_ADD4 ((uint8_t)0x10) /*!<Bit 4 */
+#define USB_DADDR_ADD5 ((uint8_t)0x20) /*!<Bit 5 */
+#define USB_DADDR_ADD6 ((uint8_t)0x40) /*!<Bit 6 */
+
+#define USB_DADDR_EF ((uint8_t)0x80) /*!<Enable Function */
+
+/****************** Bit definition for USB_BTABLE register ******************/
+#define USB_BTABLE_BTABLE ((uint16_t)0xFFF8) /*!<Buffer Table */
+
+/*!<Buffer descriptor table */
+/***************** Bit definition for USB_ADDR0_TX register *****************/
+#define USB_ADDR0_TX_ADDR0_TX ((uint16_t)0xFFFE) /*!<Transmission Buffer Address 0 */
+
+/***************** Bit definition for USB_ADDR1_TX register *****************/
+#define USB_ADDR1_TX_ADDR1_TX ((uint16_t)0xFFFE) /*!<Transmission Buffer Address 1 */
+
+/***************** Bit definition for USB_ADDR2_TX register *****************/
+#define USB_ADDR2_TX_ADDR2_TX ((uint16_t)0xFFFE) /*!<Transmission Buffer Address 2 */
+
+/***************** Bit definition for USB_ADDR3_TX register *****************/
+#define USB_ADDR3_TX_ADDR3_TX ((uint16_t)0xFFFE) /*!<Transmission Buffer Address 3 */
+
+/***************** Bit definition for USB_ADDR4_TX register *****************/
+#define USB_ADDR4_TX_ADDR4_TX ((uint16_t)0xFFFE) /*!<Transmission Buffer Address 4 */
+
+/***************** Bit definition for USB_ADDR5_TX register *****************/
+#define USB_ADDR5_TX_ADDR5_TX ((uint16_t)0xFFFE) /*!<Transmission Buffer Address 5 */
+
+/***************** Bit definition for USB_ADDR6_TX register *****************/
+#define USB_ADDR6_TX_ADDR6_TX ((uint16_t)0xFFFE) /*!<Transmission Buffer Address 6 */
+
+/***************** Bit definition for USB_ADDR7_TX register *****************/
+#define USB_ADDR7_TX_ADDR7_TX ((uint16_t)0xFFFE) /*!<Transmission Buffer Address 7 */
+
+/*----------------------------------------------------------------------------*/
+
+/***************** Bit definition for USB_COUNT0_TX register ****************/
+#define USB_COUNT0_TX_COUNT0_TX ((uint16_t)0x03FF) /*!<Transmission Byte Count 0 */
+
+/***************** Bit definition for USB_COUNT1_TX register ****************/
+#define USB_COUNT1_TX_COUNT1_TX ((uint16_t)0x03FF) /*!<Transmission Byte Count 1 */
+
+/***************** Bit definition for USB_COUNT2_TX register ****************/
+#define USB_COUNT2_TX_COUNT2_TX ((uint16_t)0x03FF) /*!<Transmission Byte Count 2 */
+
+/***************** Bit definition for USB_COUNT3_TX register ****************/
+#define USB_COUNT3_TX_COUNT3_TX ((uint16_t)0x03FF) /*!<Transmission Byte Count 3 */
+
+/***************** Bit definition for USB_COUNT4_TX register ****************/
+#define USB_COUNT4_TX_COUNT4_TX ((uint16_t)0x03FF) /*!<Transmission Byte Count 4 */
+
+/***************** Bit definition for USB_COUNT5_TX register ****************/
+#define USB_COUNT5_TX_COUNT5_TX ((uint16_t)0x03FF) /*!<Transmission Byte Count 5 */
+
+/***************** Bit definition for USB_COUNT6_TX register ****************/
+#define USB_COUNT6_TX_COUNT6_TX ((uint16_t)0x03FF) /*!<Transmission Byte Count 6 */
+
+/***************** Bit definition for USB_COUNT7_TX register ****************/
+#define USB_COUNT7_TX_COUNT7_TX ((uint16_t)0x03FF) /*!<Transmission Byte Count 7 */
+
+/*----------------------------------------------------------------------------*/
+
+/**************** Bit definition for USB_COUNT0_TX_0 register ***************/
+#define USB_COUNT0_TX_0_COUNT0_TX_0 ((uint32_t)0x000003FF) /*!<Transmission Byte Count 0 (low) */
+
+/**************** Bit definition for USB_COUNT0_TX_1 register ***************/
+#define USB_COUNT0_TX_1_COUNT0_TX_1 ((uint32_t)0x03FF0000) /*!<Transmission Byte Count 0 (high) */
+
+/**************** Bit definition for USB_COUNT1_TX_0 register ***************/
+#define USB_COUNT1_TX_0_COUNT1_TX_0 ((uint32_t)0x000003FF) /*!<Transmission Byte Count 1 (low) */
+
+/**************** Bit definition for USB_COUNT1_TX_1 register ***************/
+#define USB_COUNT1_TX_1_COUNT1_TX_1 ((uint32_t)0x03FF0000) /*!<Transmission Byte Count 1 (high) */
+
+/**************** Bit definition for USB_COUNT2_TX_0 register ***************/
+#define USB_COUNT2_TX_0_COUNT2_TX_0 ((uint32_t)0x000003FF) /*!<Transmission Byte Count 2 (low) */
+
+/**************** Bit definition for USB_COUNT2_TX_1 register ***************/
+#define USB_COUNT2_TX_1_COUNT2_TX_1 ((uint32_t)0x03FF0000) /*!<Transmission Byte Count 2 (high) */
+
+/**************** Bit definition for USB_COUNT3_TX_0 register ***************/
+#define USB_COUNT3_TX_0_COUNT3_TX_0 ((uint16_t)0x000003FF) /*!<Transmission Byte Count 3 (low) */
+
+/**************** Bit definition for USB_COUNT3_TX_1 register ***************/
+#define USB_COUNT3_TX_1_COUNT3_TX_1 ((uint16_t)0x03FF0000) /*!<Transmission Byte Count 3 (high) */
+
+/**************** Bit definition for USB_COUNT4_TX_0 register ***************/
+#define USB_COUNT4_TX_0_COUNT4_TX_0 ((uint32_t)0x000003FF) /*!<Transmission Byte Count 4 (low) */
+
+/**************** Bit definition for USB_COUNT4_TX_1 register ***************/
+#define USB_COUNT4_TX_1_COUNT4_TX_1 ((uint32_t)0x03FF0000) /*!<Transmission Byte Count 4 (high) */
+
+/**************** Bit definition for USB_COUNT5_TX_0 register ***************/
+#define USB_COUNT5_TX_0_COUNT5_TX_0 ((uint32_t)0x000003FF) /*!<Transmission Byte Count 5 (low) */
+
+/**************** Bit definition for USB_COUNT5_TX_1 register ***************/
+#define USB_COUNT5_TX_1_COUNT5_TX_1 ((uint32_t)0x03FF0000) /*!<Transmission Byte Count 5 (high) */
+
+/**************** Bit definition for USB_COUNT6_TX_0 register ***************/
+#define USB_COUNT6_TX_0_COUNT6_TX_0 ((uint32_t)0x000003FF) /*!<Transmission Byte Count 6 (low) */
+
+/**************** Bit definition for USB_COUNT6_TX_1 register ***************/
+#define USB_COUNT6_TX_1_COUNT6_TX_1 ((uint32_t)0x03FF0000) /*!<Transmission Byte Count 6 (high) */
+
+/**************** Bit definition for USB_COUNT7_TX_0 register ***************/
+#define USB_COUNT7_TX_0_COUNT7_TX_0 ((uint32_t)0x000003FF) /*!<Transmission Byte Count 7 (low) */
+
+/**************** Bit definition for USB_COUNT7_TX_1 register ***************/
+#define USB_COUNT7_TX_1_COUNT7_TX_1 ((uint32_t)0x03FF0000) /*!<Transmission Byte Count 7 (high) */
+
+/*----------------------------------------------------------------------------*/
+
+/***************** Bit definition for USB_ADDR0_RX register *****************/
+#define USB_ADDR0_RX_ADDR0_RX ((uint16_t)0xFFFE) /*!<Reception Buffer Address 0 */
+
+/***************** Bit definition for USB_ADDR1_RX register *****************/
+#define USB_ADDR1_RX_ADDR1_RX ((uint16_t)0xFFFE) /*!<Reception Buffer Address 1 */
+
+/***************** Bit definition for USB_ADDR2_RX register *****************/
+#define USB_ADDR2_RX_ADDR2_RX ((uint16_t)0xFFFE) /*!<Reception Buffer Address 2 */
+
+/***************** Bit definition for USB_ADDR3_RX register *****************/
+#define USB_ADDR3_RX_ADDR3_RX ((uint16_t)0xFFFE) /*!<Reception Buffer Address 3 */
+
+/***************** Bit definition for USB_ADDR4_RX register *****************/
+#define USB_ADDR4_RX_ADDR4_RX ((uint16_t)0xFFFE) /*!<Reception Buffer Address 4 */
+
+/***************** Bit definition for USB_ADDR5_RX register *****************/
+#define USB_ADDR5_RX_ADDR5_RX ((uint16_t)0xFFFE) /*!<Reception Buffer Address 5 */
+
+/***************** Bit definition for USB_ADDR6_RX register *****************/
+#define USB_ADDR6_RX_ADDR6_RX ((uint16_t)0xFFFE) /*!<Reception Buffer Address 6 */
+
+/***************** Bit definition for USB_ADDR7_RX register *****************/
+#define USB_ADDR7_RX_ADDR7_RX ((uint16_t)0xFFFE) /*!<Reception Buffer Address 7 */
+
+/*----------------------------------------------------------------------------*/
+
+/***************** Bit definition for USB_COUNT0_RX register ****************/
+#define USB_COUNT0_RX_COUNT0_RX ((uint16_t)0x03FF) /*!<Reception Byte Count */
+
+#define USB_COUNT0_RX_NUM_BLOCK ((uint16_t)0x7C00) /*!<NUM_BLOCK[4:0] bits (Number of blocks) */
+#define USB_COUNT0_RX_NUM_BLOCK_0 ((uint16_t)0x0400) /*!<Bit 0 */
+#define USB_COUNT0_RX_NUM_BLOCK_1 ((uint16_t)0x0800) /*!<Bit 1 */
+#define USB_COUNT0_RX_NUM_BLOCK_2 ((uint16_t)0x1000) /*!<Bit 2 */
+#define USB_COUNT0_RX_NUM_BLOCK_3 ((uint16_t)0x2000) /*!<Bit 3 */
+#define USB_COUNT0_RX_NUM_BLOCK_4 ((uint16_t)0x4000) /*!<Bit 4 */
+
+#define USB_COUNT0_RX_BLSIZE ((uint16_t)0x8000) /*!<BLock SIZE */
+
+/***************** Bit definition for USB_COUNT1_RX register ****************/
+#define USB_COUNT1_RX_COUNT1_RX ((uint16_t)0x03FF) /*!<Reception Byte Count */
+
+#define USB_COUNT1_RX_NUM_BLOCK ((uint16_t)0x7C00) /*!<NUM_BLOCK[4:0] bits (Number of blocks) */
+#define USB_COUNT1_RX_NUM_BLOCK_0 ((uint16_t)0x0400) /*!<Bit 0 */
+#define USB_COUNT1_RX_NUM_BLOCK_1 ((uint16_t)0x0800) /*!<Bit 1 */
+#define USB_COUNT1_RX_NUM_BLOCK_2 ((uint16_t)0x1000) /*!<Bit 2 */
+#define USB_COUNT1_RX_NUM_BLOCK_3 ((uint16_t)0x2000) /*!<Bit 3 */
+#define USB_COUNT1_RX_NUM_BLOCK_4 ((uint16_t)0x4000) /*!<Bit 4 */
+
+#define USB_COUNT1_RX_BLSIZE ((uint16_t)0x8000) /*!<BLock SIZE */
+
+/***************** Bit definition for USB_COUNT2_RX register ****************/
+#define USB_COUNT2_RX_COUNT2_RX ((uint16_t)0x03FF) /*!<Reception Byte Count */
+
+#define USB_COUNT2_RX_NUM_BLOCK ((uint16_t)0x7C00) /*!<NUM_BLOCK[4:0] bits (Number of blocks) */
+#define USB_COUNT2_RX_NUM_BLOCK_0 ((uint16_t)0x0400) /*!<Bit 0 */
+#define USB_COUNT2_RX_NUM_BLOCK_1 ((uint16_t)0x0800) /*!<Bit 1 */
+#define USB_COUNT2_RX_NUM_BLOCK_2 ((uint16_t)0x1000) /*!<Bit 2 */
+#define USB_COUNT2_RX_NUM_BLOCK_3 ((uint16_t)0x2000) /*!<Bit 3 */
+#define USB_COUNT2_RX_NUM_BLOCK_4 ((uint16_t)0x4000) /*!<Bit 4 */
+
+#define USB_COUNT2_RX_BLSIZE ((uint16_t)0x8000) /*!<BLock SIZE */
+
+/***************** Bit definition for USB_COUNT3_RX register ****************/
+#define USB_COUNT3_RX_COUNT3_RX ((uint16_t)0x03FF) /*!<Reception Byte Count */
+
+#define USB_COUNT3_RX_NUM_BLOCK ((uint16_t)0x7C00) /*!<NUM_BLOCK[4:0] bits (Number of blocks) */
+#define USB_COUNT3_RX_NUM_BLOCK_0 ((uint16_t)0x0400) /*!<Bit 0 */
+#define USB_COUNT3_RX_NUM_BLOCK_1 ((uint16_t)0x0800) /*!<Bit 1 */
+#define USB_COUNT3_RX_NUM_BLOCK_2 ((uint16_t)0x1000) /*!<Bit 2 */
+#define USB_COUNT3_RX_NUM_BLOCK_3 ((uint16_t)0x2000) /*!<Bit 3 */
+#define USB_COUNT3_RX_NUM_BLOCK_4 ((uint16_t)0x4000) /*!<Bit 4 */
+
+#define USB_COUNT3_RX_BLSIZE ((uint16_t)0x8000) /*!<BLock SIZE */
+
+/***************** Bit definition for USB_COUNT4_RX register ****************/
+#define USB_COUNT4_RX_COUNT4_RX ((uint16_t)0x03FF) /*!<Reception Byte Count */
+
+#define USB_COUNT4_RX_NUM_BLOCK ((uint16_t)0x7C00) /*!<NUM_BLOCK[4:0] bits (Number of blocks) */
+#define USB_COUNT4_RX_NUM_BLOCK_0 ((uint16_t)0x0400) /*!<Bit 0 */
+#define USB_COUNT4_RX_NUM_BLOCK_1 ((uint16_t)0x0800) /*!<Bit 1 */
+#define USB_COUNT4_RX_NUM_BLOCK_2 ((uint16_t)0x1000) /*!<Bit 2 */
+#define USB_COUNT4_RX_NUM_BLOCK_3 ((uint16_t)0x2000) /*!<Bit 3 */
+#define USB_COUNT4_RX_NUM_BLOCK_4 ((uint16_t)0x4000) /*!<Bit 4 */
+
+#define USB_COUNT4_RX_BLSIZE ((uint16_t)0x8000) /*!<BLock SIZE */
+
+/***************** Bit definition for USB_COUNT5_RX register ****************/
+#define USB_COUNT5_RX_COUNT5_RX ((uint16_t)0x03FF) /*!<Reception Byte Count */
+
+#define USB_COUNT5_RX_NUM_BLOCK ((uint16_t)0x7C00) /*!<NUM_BLOCK[4:0] bits (Number of blocks) */
+#define USB_COUNT5_RX_NUM_BLOCK_0 ((uint16_t)0x0400) /*!<Bit 0 */
+#define USB_COUNT5_RX_NUM_BLOCK_1 ((uint16_t)0x0800) /*!<Bit 1 */
+#define USB_COUNT5_RX_NUM_BLOCK_2 ((uint16_t)0x1000) /*!<Bit 2 */
+#define USB_COUNT5_RX_NUM_BLOCK_3 ((uint16_t)0x2000) /*!<Bit 3 */
+#define USB_COUNT5_RX_NUM_BLOCK_4 ((uint16_t)0x4000) /*!<Bit 4 */
+
+#define USB_COUNT5_RX_BLSIZE ((uint16_t)0x8000) /*!<BLock SIZE */
+
+/***************** Bit definition for USB_COUNT6_RX register ****************/
+#define USB_COUNT6_RX_COUNT6_RX ((uint16_t)0x03FF) /*!<Reception Byte Count */
+
+#define USB_COUNT6_RX_NUM_BLOCK ((uint16_t)0x7C00) /*!<NUM_BLOCK[4:0] bits (Number of blocks) */
+#define USB_COUNT6_RX_NUM_BLOCK_0 ((uint16_t)0x0400) /*!<Bit 0 */
+#define USB_COUNT6_RX_NUM_BLOCK_1 ((uint16_t)0x0800) /*!<Bit 1 */
+#define USB_COUNT6_RX_NUM_BLOCK_2 ((uint16_t)0x1000) /*!<Bit 2 */
+#define USB_COUNT6_RX_NUM_BLOCK_3 ((uint16_t)0x2000) /*!<Bit 3 */
+#define USB_COUNT6_RX_NUM_BLOCK_4 ((uint16_t)0x4000) /*!<Bit 4 */
+
+#define USB_COUNT6_RX_BLSIZE ((uint16_t)0x8000) /*!<BLock SIZE */
+
+/***************** Bit definition for USB_COUNT7_RX register ****************/
+#define USB_COUNT7_RX_COUNT7_RX ((uint16_t)0x03FF) /*!<Reception Byte Count */
+
+#define USB_COUNT7_RX_NUM_BLOCK ((uint16_t)0x7C00) /*!<NUM_BLOCK[4:0] bits (Number of blocks) */
+#define USB_COUNT7_RX_NUM_BLOCK_0 ((uint16_t)0x0400) /*!<Bit 0 */
+#define USB_COUNT7_RX_NUM_BLOCK_1 ((uint16_t)0x0800) /*!<Bit 1 */
+#define USB_COUNT7_RX_NUM_BLOCK_2 ((uint16_t)0x1000) /*!<Bit 2 */
+#define USB_COUNT7_RX_NUM_BLOCK_3 ((uint16_t)0x2000) /*!<Bit 3 */
+#define USB_COUNT7_RX_NUM_BLOCK_4 ((uint16_t)0x4000) /*!<Bit 4 */
+
+#define USB_COUNT7_RX_BLSIZE ((uint16_t)0x8000) /*!<BLock SIZE */
+
+/*----------------------------------------------------------------------------*/
+
+/**************** Bit definition for USB_COUNT0_RX_0 register ***************/
+#define USB_COUNT0_RX_0_COUNT0_RX_0 ((uint32_t)0x000003FF) /*!<Reception Byte Count (low) */
+
+#define USB_COUNT0_RX_0_NUM_BLOCK_0 ((uint32_t)0x00007C00) /*!<NUM_BLOCK_0[4:0] bits (Number of blocks) (low) */
+#define USB_COUNT0_RX_0_NUM_BLOCK_0_0 ((uint32_t)0x00000400) /*!<Bit 0 */
+#define USB_COUNT0_RX_0_NUM_BLOCK_0_1 ((uint32_t)0x00000800) /*!<Bit 1 */
+#define USB_COUNT0_RX_0_NUM_BLOCK_0_2 ((uint32_t)0x00001000) /*!<Bit 2 */
+#define USB_COUNT0_RX_0_NUM_BLOCK_0_3 ((uint32_t)0x00002000) /*!<Bit 3 */
+#define USB_COUNT0_RX_0_NUM_BLOCK_0_4 ((uint32_t)0x00004000) /*!<Bit 4 */
+
+#define USB_COUNT0_RX_0_BLSIZE_0 ((uint32_t)0x00008000) /*!<BLock SIZE (low) */
+
+/**************** Bit definition for USB_COUNT0_RX_1 register ***************/
+#define USB_COUNT0_RX_1_COUNT0_RX_1 ((uint32_t)0x03FF0000) /*!<Reception Byte Count (high) */
+
+#define USB_COUNT0_RX_1_NUM_BLOCK_1 ((uint32_t)0x7C000000) /*!<NUM_BLOCK_1[4:0] bits (Number of blocks) (high) */
+#define USB_COUNT0_RX_1_NUM_BLOCK_1_0 ((uint32_t)0x04000000) /*!<Bit 1 */
+#define USB_COUNT0_RX_1_NUM_BLOCK_1_1 ((uint32_t)0x08000000) /*!<Bit 1 */
+#define USB_COUNT0_RX_1_NUM_BLOCK_1_2 ((uint32_t)0x10000000) /*!<Bit 2 */
+#define USB_COUNT0_RX_1_NUM_BLOCK_1_3 ((uint32_t)0x20000000) /*!<Bit 3 */
+#define USB_COUNT0_RX_1_NUM_BLOCK_1_4 ((uint32_t)0x40000000) /*!<Bit 4 */
+
+#define USB_COUNT0_RX_1_BLSIZE_1 ((uint32_t)0x80000000) /*!<BLock SIZE (high) */
+
+/**************** Bit definition for USB_COUNT1_RX_0 register ***************/
+#define USB_COUNT1_RX_0_COUNT1_RX_0 ((uint32_t)0x000003FF) /*!<Reception Byte Count (low) */
+
+#define USB_COUNT1_RX_0_NUM_BLOCK_0 ((uint32_t)0x00007C00) /*!<NUM_BLOCK_0[4:0] bits (Number of blocks) (low) */
+#define USB_COUNT1_RX_0_NUM_BLOCK_0_0 ((uint32_t)0x00000400) /*!<Bit 0 */
+#define USB_COUNT1_RX_0_NUM_BLOCK_0_1 ((uint32_t)0x00000800) /*!<Bit 1 */
+#define USB_COUNT1_RX_0_NUM_BLOCK_0_2 ((uint32_t)0x00001000) /*!<Bit 2 */
+#define USB_COUNT1_RX_0_NUM_BLOCK_0_3 ((uint32_t)0x00002000) /*!<Bit 3 */
+#define USB_COUNT1_RX_0_NUM_BLOCK_0_4 ((uint32_t)0x00004000) /*!<Bit 4 */
+
+#define USB_COUNT1_RX_0_BLSIZE_0 ((uint32_t)0x00008000) /*!<BLock SIZE (low) */
+
+/**************** Bit definition for USB_COUNT1_RX_1 register ***************/
+#define USB_COUNT1_RX_1_COUNT1_RX_1 ((uint32_t)0x03FF0000) /*!<Reception Byte Count (high) */
+
+#define USB_COUNT1_RX_1_NUM_BLOCK_1 ((uint32_t)0x7C000000) /*!<NUM_BLOCK_1[4:0] bits (Number of blocks) (high) */
+#define USB_COUNT1_RX_1_NUM_BLOCK_1_0 ((uint32_t)0x04000000) /*!<Bit 0 */
+#define USB_COUNT1_RX_1_NUM_BLOCK_1_1 ((uint32_t)0x08000000) /*!<Bit 1 */
+#define USB_COUNT1_RX_1_NUM_BLOCK_1_2 ((uint32_t)0x10000000) /*!<Bit 2 */
+#define USB_COUNT1_RX_1_NUM_BLOCK_1_3 ((uint32_t)0x20000000) /*!<Bit 3 */
+#define USB_COUNT1_RX_1_NUM_BLOCK_1_4 ((uint32_t)0x40000000) /*!<Bit 4 */
+
+#define USB_COUNT1_RX_1_BLSIZE_1 ((uint32_t)0x80000000) /*!<BLock SIZE (high) */
+
+/**************** Bit definition for USB_COUNT2_RX_0 register ***************/
+#define USB_COUNT2_RX_0_COUNT2_RX_0 ((uint32_t)0x000003FF) /*!<Reception Byte Count (low) */
+
+#define USB_COUNT2_RX_0_NUM_BLOCK_0 ((uint32_t)0x00007C00) /*!<NUM_BLOCK_0[4:0] bits (Number of blocks) (low) */
+#define USB_COUNT2_RX_0_NUM_BLOCK_0_0 ((uint32_t)0x00000400) /*!<Bit 0 */
+#define USB_COUNT2_RX_0_NUM_BLOCK_0_1 ((uint32_t)0x00000800) /*!<Bit 1 */
+#define USB_COUNT2_RX_0_NUM_BLOCK_0_2 ((uint32_t)0x00001000) /*!<Bit 2 */
+#define USB_COUNT2_RX_0_NUM_BLOCK_0_3 ((uint32_t)0x00002000) /*!<Bit 3 */
+#define USB_COUNT2_RX_0_NUM_BLOCK_0_4 ((uint32_t)0x00004000) /*!<Bit 4 */
+
+#define USB_COUNT2_RX_0_BLSIZE_0 ((uint32_t)0x00008000) /*!<BLock SIZE (low) */
+
+/**************** Bit definition for USB_COUNT2_RX_1 register ***************/
+#define USB_COUNT2_RX_1_COUNT2_RX_1 ((uint32_t)0x03FF0000) /*!<Reception Byte Count (high) */
+
+#define USB_COUNT2_RX_1_NUM_BLOCK_1 ((uint32_t)0x7C000000) /*!<NUM_BLOCK_1[4:0] bits (Number of blocks) (high) */
+#define USB_COUNT2_RX_1_NUM_BLOCK_1_0 ((uint32_t)0x04000000) /*!<Bit 0 */
+#define USB_COUNT2_RX_1_NUM_BLOCK_1_1 ((uint32_t)0x08000000) /*!<Bit 1 */
+#define USB_COUNT2_RX_1_NUM_BLOCK_1_2 ((uint32_t)0x10000000) /*!<Bit 2 */
+#define USB_COUNT2_RX_1_NUM_BLOCK_1_3 ((uint32_t)0x20000000) /*!<Bit 3 */
+#define USB_COUNT2_RX_1_NUM_BLOCK_1_4 ((uint32_t)0x40000000) /*!<Bit 4 */
+
+#define USB_COUNT2_RX_1_BLSIZE_1 ((uint32_t)0x80000000) /*!<BLock SIZE (high) */
+
+/**************** Bit definition for USB_COUNT3_RX_0 register ***************/
+#define USB_COUNT3_RX_0_COUNT3_RX_0 ((uint32_t)0x000003FF) /*!<Reception Byte Count (low) */
+
+#define USB_COUNT3_RX_0_NUM_BLOCK_0 ((uint32_t)0x00007C00) /*!<NUM_BLOCK_0[4:0] bits (Number of blocks) (low) */
+#define USB_COUNT3_RX_0_NUM_BLOCK_0_0 ((uint32_t)0x00000400) /*!<Bit 0 */
+#define USB_COUNT3_RX_0_NUM_BLOCK_0_1 ((uint32_t)0x00000800) /*!<Bit 1 */
+#define USB_COUNT3_RX_0_NUM_BLOCK_0_2 ((uint32_t)0x00001000) /*!<Bit 2 */
+#define USB_COUNT3_RX_0_NUM_BLOCK_0_3 ((uint32_t)0x00002000) /*!<Bit 3 */
+#define USB_COUNT3_RX_0_NUM_BLOCK_0_4 ((uint32_t)0x00004000) /*!<Bit 4 */
+
+#define USB_COUNT3_RX_0_BLSIZE_0 ((uint32_t)0x00008000) /*!<BLock SIZE (low) */
+
+/**************** Bit definition for USB_COUNT3_RX_1 register ***************/
+#define USB_COUNT3_RX_1_COUNT3_RX_1 ((uint32_t)0x03FF0000) /*!<Reception Byte Count (high) */
+
+#define USB_COUNT3_RX_1_NUM_BLOCK_1 ((uint32_t)0x7C000000) /*!<NUM_BLOCK_1[4:0] bits (Number of blocks) (high) */
+#define USB_COUNT3_RX_1_NUM_BLOCK_1_0 ((uint32_t)0x04000000) /*!<Bit 0 */
+#define USB_COUNT3_RX_1_NUM_BLOCK_1_1 ((uint32_t)0x08000000) /*!<Bit 1 */
+#define USB_COUNT3_RX_1_NUM_BLOCK_1_2 ((uint32_t)0x10000000) /*!<Bit 2 */
+#define USB_COUNT3_RX_1_NUM_BLOCK_1_3 ((uint32_t)0x20000000) /*!<Bit 3 */
+#define USB_COUNT3_RX_1_NUM_BLOCK_1_4 ((uint32_t)0x40000000) /*!<Bit 4 */
+
+#define USB_COUNT3_RX_1_BLSIZE_1 ((uint32_t)0x80000000) /*!<BLock SIZE (high) */
+
+/**************** Bit definition for USB_COUNT4_RX_0 register ***************/
+#define USB_COUNT4_RX_0_COUNT4_RX_0 ((uint32_t)0x000003FF) /*!<Reception Byte Count (low) */
+
+#define USB_COUNT4_RX_0_NUM_BLOCK_0 ((uint32_t)0x00007C00) /*!<NUM_BLOCK_0[4:0] bits (Number of blocks) (low) */
+#define USB_COUNT4_RX_0_NUM_BLOCK_0_0 ((uint32_t)0x00000400) /*!<Bit 0 */
+#define USB_COUNT4_RX_0_NUM_BLOCK_0_1 ((uint32_t)0x00000800) /*!<Bit 1 */
+#define USB_COUNT4_RX_0_NUM_BLOCK_0_2 ((uint32_t)0x00001000) /*!<Bit 2 */
+#define USB_COUNT4_RX_0_NUM_BLOCK_0_3 ((uint32_t)0x00002000) /*!<Bit 3 */
+#define USB_COUNT4_RX_0_NUM_BLOCK_0_4 ((uint32_t)0x00004000) /*!<Bit 4 */
+
+#define USB_COUNT4_RX_0_BLSIZE_0 ((uint32_t)0x00008000) /*!<BLock SIZE (low) */
+
+/**************** Bit definition for USB_COUNT4_RX_1 register ***************/
+#define USB_COUNT4_RX_1_COUNT4_RX_1 ((uint32_t)0x03FF0000) /*!<Reception Byte Count (high) */
+
+#define USB_COUNT4_RX_1_NUM_BLOCK_1 ((uint32_t)0x7C000000) /*!<NUM_BLOCK_1[4:0] bits (Number of blocks) (high) */
+#define USB_COUNT4_RX_1_NUM_BLOCK_1_0 ((uint32_t)0x04000000) /*!<Bit 0 */
+#define USB_COUNT4_RX_1_NUM_BLOCK_1_1 ((uint32_t)0x08000000) /*!<Bit 1 */
+#define USB_COUNT4_RX_1_NUM_BLOCK_1_2 ((uint32_t)0x10000000) /*!<Bit 2 */
+#define USB_COUNT4_RX_1_NUM_BLOCK_1_3 ((uint32_t)0x20000000) /*!<Bit 3 */
+#define USB_COUNT4_RX_1_NUM_BLOCK_1_4 ((uint32_t)0x40000000) /*!<Bit 4 */
+
+#define USB_COUNT4_RX_1_BLSIZE_1 ((uint32_t)0x80000000) /*!<BLock SIZE (high) */
+
+/**************** Bit definition for USB_COUNT5_RX_0 register ***************/
+#define USB_COUNT5_RX_0_COUNT5_RX_0 ((uint32_t)0x000003FF) /*!<Reception Byte Count (low) */
+
+#define USB_COUNT5_RX_0_NUM_BLOCK_0 ((uint32_t)0x00007C00) /*!<NUM_BLOCK_0[4:0] bits (Number of blocks) (low) */
+#define USB_COUNT5_RX_0_NUM_BLOCK_0_0 ((uint32_t)0x00000400) /*!<Bit 0 */
+#define USB_COUNT5_RX_0_NUM_BLOCK_0_1 ((uint32_t)0x00000800) /*!<Bit 1 */
+#define USB_COUNT5_RX_0_NUM_BLOCK_0_2 ((uint32_t)0x00001000) /*!<Bit 2 */
+#define USB_COUNT5_RX_0_NUM_BLOCK_0_3 ((uint32_t)0x00002000) /*!<Bit 3 */
+#define USB_COUNT5_RX_0_NUM_BLOCK_0_4 ((uint32_t)0x00004000) /*!<Bit 4 */
+
+#define USB_COUNT5_RX_0_BLSIZE_0 ((uint32_t)0x00008000) /*!<BLock SIZE (low) */
+
+/**************** Bit definition for USB_COUNT5_RX_1 register ***************/
+#define USB_COUNT5_RX_1_COUNT5_RX_1 ((uint32_t)0x03FF0000) /*!<Reception Byte Count (high) */
+
+#define USB_COUNT5_RX_1_NUM_BLOCK_1 ((uint32_t)0x7C000000) /*!<NUM_BLOCK_1[4:0] bits (Number of blocks) (high) */
+#define USB_COUNT5_RX_1_NUM_BLOCK_1_0 ((uint32_t)0x04000000) /*!<Bit 0 */
+#define USB_COUNT5_RX_1_NUM_BLOCK_1_1 ((uint32_t)0x08000000) /*!<Bit 1 */
+#define USB_COUNT5_RX_1_NUM_BLOCK_1_2 ((uint32_t)0x10000000) /*!<Bit 2 */
+#define USB_COUNT5_RX_1_NUM_BLOCK_1_3 ((uint32_t)0x20000000) /*!<Bit 3 */
+#define USB_COUNT5_RX_1_NUM_BLOCK_1_4 ((uint32_t)0x40000000) /*!<Bit 4 */
+
+#define USB_COUNT5_RX_1_BLSIZE_1 ((uint32_t)0x80000000) /*!<BLock SIZE (high) */
+
+/*************** Bit definition for USB_COUNT6_RX_0 register ***************/
+#define USB_COUNT6_RX_0_COUNT6_RX_0 ((uint32_t)0x000003FF) /*!<Reception Byte Count (low) */
+
+#define USB_COUNT6_RX_0_NUM_BLOCK_0 ((uint32_t)0x00007C00) /*!<NUM_BLOCK_0[4:0] bits (Number of blocks) (low) */
+#define USB_COUNT6_RX_0_NUM_BLOCK_0_0 ((uint32_t)0x00000400) /*!<Bit 0 */
+#define USB_COUNT6_RX_0_NUM_BLOCK_0_1 ((uint32_t)0x00000800) /*!<Bit 1 */
+#define USB_COUNT6_RX_0_NUM_BLOCK_0_2 ((uint32_t)0x00001000) /*!<Bit 2 */
+#define USB_COUNT6_RX_0_NUM_BLOCK_0_3 ((uint32_t)0x00002000) /*!<Bit 3 */
+#define USB_COUNT6_RX_0_NUM_BLOCK_0_4 ((uint32_t)0x00004000) /*!<Bit 4 */
+
+#define USB_COUNT6_RX_0_BLSIZE_0 ((uint32_t)0x00008000) /*!<BLock SIZE (low) */
+
+/**************** Bit definition for USB_COUNT6_RX_1 register ***************/
+#define USB_COUNT6_RX_1_COUNT6_RX_1 ((uint32_t)0x03FF0000) /*!<Reception Byte Count (high) */
+
+#define USB_COUNT6_RX_1_NUM_BLOCK_1 ((uint32_t)0x7C000000) /*!<NUM_BLOCK_1[4:0] bits (Number of blocks) (high) */
+#define USB_COUNT6_RX_1_NUM_BLOCK_1_0 ((uint32_t)0x04000000) /*!<Bit 0 */
+#define USB_COUNT6_RX_1_NUM_BLOCK_1_1 ((uint32_t)0x08000000) /*!<Bit 1 */
+#define USB_COUNT6_RX_1_NUM_BLOCK_1_2 ((uint32_t)0x10000000) /*!<Bit 2 */
+#define USB_COUNT6_RX_1_NUM_BLOCK_1_3 ((uint32_t)0x20000000) /*!<Bit 3 */
+#define USB_COUNT6_RX_1_NUM_BLOCK_1_4 ((uint32_t)0x40000000) /*!<Bit 4 */
+
+#define USB_COUNT6_RX_1_BLSIZE_1 ((uint32_t)0x80000000) /*!<BLock SIZE (high) */
+
+/*************** Bit definition for USB_COUNT7_RX_0 register ****************/
+#define USB_COUNT7_RX_0_COUNT7_RX_0 ((uint32_t)0x000003FF) /*!<Reception Byte Count (low) */
+
+#define USB_COUNT7_RX_0_NUM_BLOCK_0 ((uint32_t)0x00007C00) /*!<NUM_BLOCK_0[4:0] bits (Number of blocks) (low) */
+#define USB_COUNT7_RX_0_NUM_BLOCK_0_0 ((uint32_t)0x00000400) /*!<Bit 0 */
+#define USB_COUNT7_RX_0_NUM_BLOCK_0_1 ((uint32_t)0x00000800) /*!<Bit 1 */
+#define USB_COUNT7_RX_0_NUM_BLOCK_0_2 ((uint32_t)0x00001000) /*!<Bit 2 */
+#define USB_COUNT7_RX_0_NUM_BLOCK_0_3 ((uint32_t)0x00002000) /*!<Bit 3 */
+#define USB_COUNT7_RX_0_NUM_BLOCK_0_4 ((uint32_t)0x00004000) /*!<Bit 4 */
+
+#define USB_COUNT7_RX_0_BLSIZE_0 ((uint32_t)0x00008000) /*!<BLock SIZE (low) */
+
+/*************** Bit definition for USB_COUNT7_RX_1 register ****************/
+#define USB_COUNT7_RX_1_COUNT7_RX_1 ((uint32_t)0x03FF0000) /*!<Reception Byte Count (high) */
+
+#define USB_COUNT7_RX_1_NUM_BLOCK_1 ((uint32_t)0x7C000000) /*!<NUM_BLOCK_1[4:0] bits (Number of blocks) (high) */
+#define USB_COUNT7_RX_1_NUM_BLOCK_1_0 ((uint32_t)0x04000000) /*!<Bit 0 */
+#define USB_COUNT7_RX_1_NUM_BLOCK_1_1 ((uint32_t)0x08000000) /*!<Bit 1 */
+#define USB_COUNT7_RX_1_NUM_BLOCK_1_2 ((uint32_t)0x10000000) /*!<Bit 2 */
+#define USB_COUNT7_RX_1_NUM_BLOCK_1_3 ((uint32_t)0x20000000) /*!<Bit 3 */
+#define USB_COUNT7_RX_1_NUM_BLOCK_1_4 ((uint32_t)0x40000000) /*!<Bit 4 */
+
+#define USB_COUNT7_RX_1_BLSIZE_1 ((uint32_t)0x80000000) /*!<BLock SIZE (high) */
+
+/******************************************************************************/
+/* */
+/* Controller Area Network */
+/* */
+/******************************************************************************/
+
+/*!<CAN control and status registers */
+/******************* Bit definition for CAN_MCR register ********************/
+#define CAN_MCR_INRQ ((uint16_t)0x0001) /*!<Initialization Request */
+#define CAN_MCR_SLEEP ((uint16_t)0x0002) /*!<Sleep Mode Request */
+#define CAN_MCR_TXFP ((uint16_t)0x0004) /*!<Transmit FIFO Priority */
+#define CAN_MCR_RFLM ((uint16_t)0x0008) /*!<Receive FIFO Locked Mode */
+#define CAN_MCR_NART ((uint16_t)0x0010) /*!<No Automatic Retransmission */
+#define CAN_MCR_AWUM ((uint16_t)0x0020) /*!<Automatic Wakeup Mode */
+#define CAN_MCR_ABOM ((uint16_t)0x0040) /*!<Automatic Bus-Off Management */
+#define CAN_MCR_TTCM ((uint16_t)0x0080) /*!<Time Triggered Communication Mode */
+#define CAN_MCR_RESET ((uint16_t)0x8000) /*!<bxCAN software master reset */
+
+/******************* Bit definition for CAN_MSR register ********************/
+#define CAN_MSR_INAK ((uint16_t)0x0001) /*!<Initialization Acknowledge */
+#define CAN_MSR_SLAK ((uint16_t)0x0002) /*!<Sleep Acknowledge */
+#define CAN_MSR_ERRI ((uint16_t)0x0004) /*!<Error Interrupt */
+#define CAN_MSR_WKUI ((uint16_t)0x0008) /*!<Wakeup Interrupt */
+#define CAN_MSR_SLAKI ((uint16_t)0x0010) /*!<Sleep Acknowledge Interrupt */
+#define CAN_MSR_TXM ((uint16_t)0x0100) /*!<Transmit Mode */
+#define CAN_MSR_RXM ((uint16_t)0x0200) /*!<Receive Mode */
+#define CAN_MSR_SAMP ((uint16_t)0x0400) /*!<Last Sample Point */
+#define CAN_MSR_RX ((uint16_t)0x0800) /*!<CAN Rx Signal */
+
+/******************* Bit definition for CAN_TSR register ********************/
+#define CAN_TSR_RQCP0 ((uint32_t)0x00000001) /*!<Request Completed Mailbox0 */
+#define CAN_TSR_TXOK0 ((uint32_t)0x00000002) /*!<Transmission OK of Mailbox0 */
+#define CAN_TSR_ALST0 ((uint32_t)0x00000004) /*!<Arbitration Lost for Mailbox0 */
+#define CAN_TSR_TERR0 ((uint32_t)0x00000008) /*!<Transmission Error of Mailbox0 */
+#define CAN_TSR_ABRQ0 ((uint32_t)0x00000080) /*!<Abort Request for Mailbox0 */
+#define CAN_TSR_RQCP1 ((uint32_t)0x00000100) /*!<Request Completed Mailbox1 */
+#define CAN_TSR_TXOK1 ((uint32_t)0x00000200) /*!<Transmission OK of Mailbox1 */
+#define CAN_TSR_ALST1 ((uint32_t)0x00000400) /*!<Arbitration Lost for Mailbox1 */
+#define CAN_TSR_TERR1 ((uint32_t)0x00000800) /*!<Transmission Error of Mailbox1 */
+#define CAN_TSR_ABRQ1 ((uint32_t)0x00008000) /*!<Abort Request for Mailbox 1 */
+#define CAN_TSR_RQCP2 ((uint32_t)0x00010000) /*!<Request Completed Mailbox2 */
+#define CAN_TSR_TXOK2 ((uint32_t)0x00020000) /*!<Transmission OK of Mailbox 2 */
+#define CAN_TSR_ALST2 ((uint32_t)0x00040000) /*!<Arbitration Lost for mailbox 2 */
+#define CAN_TSR_TERR2 ((uint32_t)0x00080000) /*!<Transmission Error of Mailbox 2 */
+#define CAN_TSR_ABRQ2 ((uint32_t)0x00800000) /*!<Abort Request for Mailbox 2 */
+#define CAN_TSR_CODE ((uint32_t)0x03000000) /*!<Mailbox Code */
+
+#define CAN_TSR_TME ((uint32_t)0x1C000000) /*!<TME[2:0] bits */
+#define CAN_TSR_TME0 ((uint32_t)0x04000000) /*!<Transmit Mailbox 0 Empty */
+#define CAN_TSR_TME1 ((uint32_t)0x08000000) /*!<Transmit Mailbox 1 Empty */
+#define CAN_TSR_TME2 ((uint32_t)0x10000000) /*!<Transmit Mailbox 2 Empty */
+
+#define CAN_TSR_LOW ((uint32_t)0xE0000000) /*!<LOW[2:0] bits */
+#define CAN_TSR_LOW0 ((uint32_t)0x20000000) /*!<Lowest Priority Flag for Mailbox 0 */
+#define CAN_TSR_LOW1 ((uint32_t)0x40000000) /*!<Lowest Priority Flag for Mailbox 1 */
+#define CAN_TSR_LOW2 ((uint32_t)0x80000000) /*!<Lowest Priority Flag for Mailbox 2 */
+
+/******************* Bit definition for CAN_RF0R register *******************/
+#define CAN_RF0R_FMP0 ((uint8_t)0x03) /*!<FIFO 0 Message Pending */
+#define CAN_RF0R_FULL0 ((uint8_t)0x08) /*!<FIFO 0 Full */
+#define CAN_RF0R_FOVR0 ((uint8_t)0x10) /*!<FIFO 0 Overrun */
+#define CAN_RF0R_RFOM0 ((uint8_t)0x20) /*!<Release FIFO 0 Output Mailbox */
+
+/******************* Bit definition for CAN_RF1R register *******************/
+#define CAN_RF1R_FMP1 ((uint8_t)0x03) /*!<FIFO 1 Message Pending */
+#define CAN_RF1R_FULL1 ((uint8_t)0x08) /*!<FIFO 1 Full */
+#define CAN_RF1R_FOVR1 ((uint8_t)0x10) /*!<FIFO 1 Overrun */
+#define CAN_RF1R_RFOM1 ((uint8_t)0x20) /*!<Release FIFO 1 Output Mailbox */
+
+/******************** Bit definition for CAN_IER register *******************/
+#define CAN_IER_TMEIE ((uint32_t)0x00000001) /*!<Transmit Mailbox Empty Interrupt Enable */
+#define CAN_IER_FMPIE0 ((uint32_t)0x00000002) /*!<FIFO Message Pending Interrupt Enable */
+#define CAN_IER_FFIE0 ((uint32_t)0x00000004) /*!<FIFO Full Interrupt Enable */
+#define CAN_IER_FOVIE0 ((uint32_t)0x00000008) /*!<FIFO Overrun Interrupt Enable */
+#define CAN_IER_FMPIE1 ((uint32_t)0x00000010) /*!<FIFO Message Pending Interrupt Enable */
+#define CAN_IER_FFIE1 ((uint32_t)0x00000020) /*!<FIFO Full Interrupt Enable */
+#define CAN_IER_FOVIE1 ((uint32_t)0x00000040) /*!<FIFO Overrun Interrupt Enable */
+#define CAN_IER_EWGIE ((uint32_t)0x00000100) /*!<Error Warning Interrupt Enable */
+#define CAN_IER_EPVIE ((uint32_t)0x00000200) /*!<Error Passive Interrupt Enable */
+#define CAN_IER_BOFIE ((uint32_t)0x00000400) /*!<Bus-Off Interrupt Enable */
+#define CAN_IER_LECIE ((uint32_t)0x00000800) /*!<Last Error Code Interrupt Enable */
+#define CAN_IER_ERRIE ((uint32_t)0x00008000) /*!<Error Interrupt Enable */
+#define CAN_IER_WKUIE ((uint32_t)0x00010000) /*!<Wakeup Interrupt Enable */
+#define CAN_IER_SLKIE ((uint32_t)0x00020000) /*!<Sleep Interrupt Enable */
+
+/******************** Bit definition for CAN_ESR register *******************/
+#define CAN_ESR_EWGF ((uint32_t)0x00000001) /*!<Error Warning Flag */
+#define CAN_ESR_EPVF ((uint32_t)0x00000002) /*!<Error Passive Flag */
+#define CAN_ESR_BOFF ((uint32_t)0x00000004) /*!<Bus-Off Flag */
+
+#define CAN_ESR_LEC ((uint32_t)0x00000070) /*!<LEC[2:0] bits (Last Error Code) */
+#define CAN_ESR_LEC_0 ((uint32_t)0x00000010) /*!<Bit 0 */
+#define CAN_ESR_LEC_1 ((uint32_t)0x00000020) /*!<Bit 1 */
+#define CAN_ESR_LEC_2 ((uint32_t)0x00000040) /*!<Bit 2 */
+
+#define CAN_ESR_TEC ((uint32_t)0x00FF0000) /*!<Least significant byte of the 9-bit Transmit Error Counter */
+#define CAN_ESR_REC ((uint32_t)0xFF000000) /*!<Receive Error Counter */
+
+/******************* Bit definition for CAN_BTR register ********************/
+#define CAN_BTR_BRP ((uint32_t)0x000003FF) /*!<Baud Rate Prescaler */
+#define CAN_BTR_TS1 ((uint32_t)0x000F0000) /*!<Time Segment 1 */
+#define CAN_BTR_TS2 ((uint32_t)0x00700000) /*!<Time Segment 2 */
+#define CAN_BTR_SJW ((uint32_t)0x03000000) /*!<Resynchronization Jump Width */
+#define CAN_BTR_LBKM ((uint32_t)0x40000000) /*!<Loop Back Mode (Debug) */
+#define CAN_BTR_SILM ((uint32_t)0x80000000) /*!<Silent Mode */
+
+/*!<Mailbox registers */
+/****************** Bit definition for CAN_TI0R register ********************/
+#define CAN_TI0R_TXRQ ((uint32_t)0x00000001) /*!<Transmit Mailbox Request */
+#define CAN_TI0R_RTR ((uint32_t)0x00000002) /*!<Remote Transmission Request */
+#define CAN_TI0R_IDE ((uint32_t)0x00000004) /*!<Identifier Extension */
+#define CAN_TI0R_EXID ((uint32_t)0x001FFFF8) /*!<Extended Identifier */
+#define CAN_TI0R_STID ((uint32_t)0xFFE00000) /*!<Standard Identifier or Extended Identifier */
+
+/****************** Bit definition for CAN_TDT0R register *******************/
+#define CAN_TDT0R_DLC ((uint32_t)0x0000000F) /*!<Data Length Code */
+#define CAN_TDT0R_TGT ((uint32_t)0x00000100) /*!<Transmit Global Time */
+#define CAN_TDT0R_TIME ((uint32_t)0xFFFF0000) /*!<Message Time Stamp */
+
+/****************** Bit definition for CAN_TDL0R register *******************/
+#define CAN_TDL0R_DATA0 ((uint32_t)0x000000FF) /*!<Data byte 0 */
+#define CAN_TDL0R_DATA1 ((uint32_t)0x0000FF00) /*!<Data byte 1 */
+#define CAN_TDL0R_DATA2 ((uint32_t)0x00FF0000) /*!<Data byte 2 */
+#define CAN_TDL0R_DATA3 ((uint32_t)0xFF000000) /*!<Data byte 3 */
+
+/****************** Bit definition for CAN_TDH0R register *******************/
+#define CAN_TDH0R_DATA4 ((uint32_t)0x000000FF) /*!<Data byte 4 */
+#define CAN_TDH0R_DATA5 ((uint32_t)0x0000FF00) /*!<Data byte 5 */
+#define CAN_TDH0R_DATA6 ((uint32_t)0x00FF0000) /*!<Data byte 6 */
+#define CAN_TDH0R_DATA7 ((uint32_t)0xFF000000) /*!<Data byte 7 */
+
+/******************* Bit definition for CAN_TI1R register *******************/
+#define CAN_TI1R_TXRQ ((uint32_t)0x00000001) /*!<Transmit Mailbox Request */
+#define CAN_TI1R_RTR ((uint32_t)0x00000002) /*!<Remote Transmission Request */
+#define CAN_TI1R_IDE ((uint32_t)0x00000004) /*!<Identifier Extension */
+#define CAN_TI1R_EXID ((uint32_t)0x001FFFF8) /*!<Extended Identifier */
+#define CAN_TI1R_STID ((uint32_t)0xFFE00000) /*!<Standard Identifier or Extended Identifier */
+
+/******************* Bit definition for CAN_TDT1R register ******************/
+#define CAN_TDT1R_DLC ((uint32_t)0x0000000F) /*!<Data Length Code */
+#define CAN_TDT1R_TGT ((uint32_t)0x00000100) /*!<Transmit Global Time */
+#define CAN_TDT1R_TIME ((uint32_t)0xFFFF0000) /*!<Message Time Stamp */
+
+/******************* Bit definition for CAN_TDL1R register ******************/
+#define CAN_TDL1R_DATA0 ((uint32_t)0x000000FF) /*!<Data byte 0 */
+#define CAN_TDL1R_DATA1 ((uint32_t)0x0000FF00) /*!<Data byte 1 */
+#define CAN_TDL1R_DATA2 ((uint32_t)0x00FF0000) /*!<Data byte 2 */
+#define CAN_TDL1R_DATA3 ((uint32_t)0xFF000000) /*!<Data byte 3 */
+
+/******************* Bit definition for CAN_TDH1R register ******************/
+#define CAN_TDH1R_DATA4 ((uint32_t)0x000000FF) /*!<Data byte 4 */
+#define CAN_TDH1R_DATA5 ((uint32_t)0x0000FF00) /*!<Data byte 5 */
+#define CAN_TDH1R_DATA6 ((uint32_t)0x00FF0000) /*!<Data byte 6 */
+#define CAN_TDH1R_DATA7 ((uint32_t)0xFF000000) /*!<Data byte 7 */
+
+/******************* Bit definition for CAN_TI2R register *******************/
+#define CAN_TI2R_TXRQ ((uint32_t)0x00000001) /*!<Transmit Mailbox Request */
+#define CAN_TI2R_RTR ((uint32_t)0x00000002) /*!<Remote Transmission Request */
+#define CAN_TI2R_IDE ((uint32_t)0x00000004) /*!<Identifier Extension */
+#define CAN_TI2R_EXID ((uint32_t)0x001FFFF8) /*!<Extended identifier */
+#define CAN_TI2R_STID ((uint32_t)0xFFE00000) /*!<Standard Identifier or Extended Identifier */
+
+/******************* Bit definition for CAN_TDT2R register ******************/
+#define CAN_TDT2R_DLC ((uint32_t)0x0000000F) /*!<Data Length Code */
+#define CAN_TDT2R_TGT ((uint32_t)0x00000100) /*!<Transmit Global Time */
+#define CAN_TDT2R_TIME ((uint32_t)0xFFFF0000) /*!<Message Time Stamp */
+
+/******************* Bit definition for CAN_TDL2R register ******************/
+#define CAN_TDL2R_DATA0 ((uint32_t)0x000000FF) /*!<Data byte 0 */
+#define CAN_TDL2R_DATA1 ((uint32_t)0x0000FF00) /*!<Data byte 1 */
+#define CAN_TDL2R_DATA2 ((uint32_t)0x00FF0000) /*!<Data byte 2 */
+#define CAN_TDL2R_DATA3 ((uint32_t)0xFF000000) /*!<Data byte 3 */
+
+/******************* Bit definition for CAN_TDH2R register ******************/
+#define CAN_TDH2R_DATA4 ((uint32_t)0x000000FF) /*!<Data byte 4 */
+#define CAN_TDH2R_DATA5 ((uint32_t)0x0000FF00) /*!<Data byte 5 */
+#define CAN_TDH2R_DATA6 ((uint32_t)0x00FF0000) /*!<Data byte 6 */
+#define CAN_TDH2R_DATA7 ((uint32_t)0xFF000000) /*!<Data byte 7 */
+
+/******************* Bit definition for CAN_RI0R register *******************/
+#define CAN_RI0R_RTR ((uint32_t)0x00000002) /*!<Remote Transmission Request */
+#define CAN_RI0R_IDE ((uint32_t)0x00000004) /*!<Identifier Extension */
+#define CAN_RI0R_EXID ((uint32_t)0x001FFFF8) /*!<Extended Identifier */
+#define CAN_RI0R_STID ((uint32_t)0xFFE00000) /*!<Standard Identifier or Extended Identifier */
+
+/******************* Bit definition for CAN_RDT0R register ******************/
+#define CAN_RDT0R_DLC ((uint32_t)0x0000000F) /*!<Data Length Code */
+#define CAN_RDT0R_FMI ((uint32_t)0x0000FF00) /*!<Filter Match Index */
+#define CAN_RDT0R_TIME ((uint32_t)0xFFFF0000) /*!<Message Time Stamp */
+
+/******************* Bit definition for CAN_RDL0R register ******************/
+#define CAN_RDL0R_DATA0 ((uint32_t)0x000000FF) /*!<Data byte 0 */
+#define CAN_RDL0R_DATA1 ((uint32_t)0x0000FF00) /*!<Data byte 1 */
+#define CAN_RDL0R_DATA2 ((uint32_t)0x00FF0000) /*!<Data byte 2 */
+#define CAN_RDL0R_DATA3 ((uint32_t)0xFF000000) /*!<Data byte 3 */
+
+/******************* Bit definition for CAN_RDH0R register ******************/
+#define CAN_RDH0R_DATA4 ((uint32_t)0x000000FF) /*!<Data byte 4 */
+#define CAN_RDH0R_DATA5 ((uint32_t)0x0000FF00) /*!<Data byte 5 */
+#define CAN_RDH0R_DATA6 ((uint32_t)0x00FF0000) /*!<Data byte 6 */
+#define CAN_RDH0R_DATA7 ((uint32_t)0xFF000000) /*!<Data byte 7 */
+
+/******************* Bit definition for CAN_RI1R register *******************/
+#define CAN_RI1R_RTR ((uint32_t)0x00000002) /*!<Remote Transmission Request */
+#define CAN_RI1R_IDE ((uint32_t)0x00000004) /*!<Identifier Extension */
+#define CAN_RI1R_EXID ((uint32_t)0x001FFFF8) /*!<Extended identifier */
+#define CAN_RI1R_STID ((uint32_t)0xFFE00000) /*!<Standard Identifier or Extended Identifier */
+
+/******************* Bit definition for CAN_RDT1R register ******************/
+#define CAN_RDT1R_DLC ((uint32_t)0x0000000F) /*!<Data Length Code */
+#define CAN_RDT1R_FMI ((uint32_t)0x0000FF00) /*!<Filter Match Index */
+#define CAN_RDT1R_TIME ((uint32_t)0xFFFF0000) /*!<Message Time Stamp */
+
+/******************* Bit definition for CAN_RDL1R register ******************/
+#define CAN_RDL1R_DATA0 ((uint32_t)0x000000FF) /*!<Data byte 0 */
+#define CAN_RDL1R_DATA1 ((uint32_t)0x0000FF00) /*!<Data byte 1 */
+#define CAN_RDL1R_DATA2 ((uint32_t)0x00FF0000) /*!<Data byte 2 */
+#define CAN_RDL1R_DATA3 ((uint32_t)0xFF000000) /*!<Data byte 3 */
+
+/******************* Bit definition for CAN_RDH1R register ******************/
+#define CAN_RDH1R_DATA4 ((uint32_t)0x000000FF) /*!<Data byte 4 */
+#define CAN_RDH1R_DATA5 ((uint32_t)0x0000FF00) /*!<Data byte 5 */
+#define CAN_RDH1R_DATA6 ((uint32_t)0x00FF0000) /*!<Data byte 6 */
+#define CAN_RDH1R_DATA7 ((uint32_t)0xFF000000) /*!<Data byte 7 */
+
+/*!<CAN filter registers */
+/******************* Bit definition for CAN_FMR register ********************/
+#define CAN_FMR_FINIT ((uint8_t)0x01) /*!<Filter Init Mode */
+
+/******************* Bit definition for CAN_FM1R register *******************/
+#define CAN_FM1R_FBM ((uint16_t)0x3FFF) /*!<Filter Mode */
+#define CAN_FM1R_FBM0 ((uint16_t)0x0001) /*!<Filter Init Mode bit 0 */
+#define CAN_FM1R_FBM1 ((uint16_t)0x0002) /*!<Filter Init Mode bit 1 */
+#define CAN_FM1R_FBM2 ((uint16_t)0x0004) /*!<Filter Init Mode bit 2 */
+#define CAN_FM1R_FBM3 ((uint16_t)0x0008) /*!<Filter Init Mode bit 3 */
+#define CAN_FM1R_FBM4 ((uint16_t)0x0010) /*!<Filter Init Mode bit 4 */
+#define CAN_FM1R_FBM5 ((uint16_t)0x0020) /*!<Filter Init Mode bit 5 */
+#define CAN_FM1R_FBM6 ((uint16_t)0x0040) /*!<Filter Init Mode bit 6 */
+#define CAN_FM1R_FBM7 ((uint16_t)0x0080) /*!<Filter Init Mode bit 7 */
+#define CAN_FM1R_FBM8 ((uint16_t)0x0100) /*!<Filter Init Mode bit 8 */
+#define CAN_FM1R_FBM9 ((uint16_t)0x0200) /*!<Filter Init Mode bit 9 */
+#define CAN_FM1R_FBM10 ((uint16_t)0x0400) /*!<Filter Init Mode bit 10 */
+#define CAN_FM1R_FBM11 ((uint16_t)0x0800) /*!<Filter Init Mode bit 11 */
+#define CAN_FM1R_FBM12 ((uint16_t)0x1000) /*!<Filter Init Mode bit 12 */
+#define CAN_FM1R_FBM13 ((uint16_t)0x2000) /*!<Filter Init Mode bit 13 */
+
+/******************* Bit definition for CAN_FS1R register *******************/
+#define CAN_FS1R_FSC ((uint16_t)0x3FFF) /*!<Filter Scale Configuration */
+#define CAN_FS1R_FSC0 ((uint16_t)0x0001) /*!<Filter Scale Configuration bit 0 */
+#define CAN_FS1R_FSC1 ((uint16_t)0x0002) /*!<Filter Scale Configuration bit 1 */
+#define CAN_FS1R_FSC2 ((uint16_t)0x0004) /*!<Filter Scale Configuration bit 2 */
+#define CAN_FS1R_FSC3 ((uint16_t)0x0008) /*!<Filter Scale Configuration bit 3 */
+#define CAN_FS1R_FSC4 ((uint16_t)0x0010) /*!<Filter Scale Configuration bit 4 */
+#define CAN_FS1R_FSC5 ((uint16_t)0x0020) /*!<Filter Scale Configuration bit 5 */
+#define CAN_FS1R_FSC6 ((uint16_t)0x0040) /*!<Filter Scale Configuration bit 6 */
+#define CAN_FS1R_FSC7 ((uint16_t)0x0080) /*!<Filter Scale Configuration bit 7 */
+#define CAN_FS1R_FSC8 ((uint16_t)0x0100) /*!<Filter Scale Configuration bit 8 */
+#define CAN_FS1R_FSC9 ((uint16_t)0x0200) /*!<Filter Scale Configuration bit 9 */
+#define CAN_FS1R_FSC10 ((uint16_t)0x0400) /*!<Filter Scale Configuration bit 10 */
+#define CAN_FS1R_FSC11 ((uint16_t)0x0800) /*!<Filter Scale Configuration bit 11 */
+#define CAN_FS1R_FSC12 ((uint16_t)0x1000) /*!<Filter Scale Configuration bit 12 */
+#define CAN_FS1R_FSC13 ((uint16_t)0x2000) /*!<Filter Scale Configuration bit 13 */
+
+/****************** Bit definition for CAN_FFA1R register *******************/
+#define CAN_FFA1R_FFA ((uint16_t)0x3FFF) /*!<Filter FIFO Assignment */
+#define CAN_FFA1R_FFA0 ((uint16_t)0x0001) /*!<Filter FIFO Assignment for Filter 0 */
+#define CAN_FFA1R_FFA1 ((uint16_t)0x0002) /*!<Filter FIFO Assignment for Filter 1 */
+#define CAN_FFA1R_FFA2 ((uint16_t)0x0004) /*!<Filter FIFO Assignment for Filter 2 */
+#define CAN_FFA1R_FFA3 ((uint16_t)0x0008) /*!<Filter FIFO Assignment for Filter 3 */
+#define CAN_FFA1R_FFA4 ((uint16_t)0x0010) /*!<Filter FIFO Assignment for Filter 4 */
+#define CAN_FFA1R_FFA5 ((uint16_t)0x0020) /*!<Filter FIFO Assignment for Filter 5 */
+#define CAN_FFA1R_FFA6 ((uint16_t)0x0040) /*!<Filter FIFO Assignment for Filter 6 */
+#define CAN_FFA1R_FFA7 ((uint16_t)0x0080) /*!<Filter FIFO Assignment for Filter 7 */
+#define CAN_FFA1R_FFA8 ((uint16_t)0x0100) /*!<Filter FIFO Assignment for Filter 8 */
+#define CAN_FFA1R_FFA9 ((uint16_t)0x0200) /*!<Filter FIFO Assignment for Filter 9 */
+#define CAN_FFA1R_FFA10 ((uint16_t)0x0400) /*!<Filter FIFO Assignment for Filter 10 */
+#define CAN_FFA1R_FFA11 ((uint16_t)0x0800) /*!<Filter FIFO Assignment for Filter 11 */
+#define CAN_FFA1R_FFA12 ((uint16_t)0x1000) /*!<Filter FIFO Assignment for Filter 12 */
+#define CAN_FFA1R_FFA13 ((uint16_t)0x2000) /*!<Filter FIFO Assignment for Filter 13 */
+
+/******************* Bit definition for CAN_FA1R register *******************/
+#define CAN_FA1R_FACT ((uint16_t)0x3FFF) /*!<Filter Active */
+#define CAN_FA1R_FACT0 ((uint16_t)0x0001) /*!<Filter 0 Active */
+#define CAN_FA1R_FACT1 ((uint16_t)0x0002) /*!<Filter 1 Active */
+#define CAN_FA1R_FACT2 ((uint16_t)0x0004) /*!<Filter 2 Active */
+#define CAN_FA1R_FACT3 ((uint16_t)0x0008) /*!<Filter 3 Active */
+#define CAN_FA1R_FACT4 ((uint16_t)0x0010) /*!<Filter 4 Active */
+#define CAN_FA1R_FACT5 ((uint16_t)0x0020) /*!<Filter 5 Active */
+#define CAN_FA1R_FACT6 ((uint16_t)0x0040) /*!<Filter 6 Active */
+#define CAN_FA1R_FACT7 ((uint16_t)0x0080) /*!<Filter 7 Active */
+#define CAN_FA1R_FACT8 ((uint16_t)0x0100) /*!<Filter 8 Active */
+#define CAN_FA1R_FACT9 ((uint16_t)0x0200) /*!<Filter 9 Active */
+#define CAN_FA1R_FACT10 ((uint16_t)0x0400) /*!<Filter 10 Active */
+#define CAN_FA1R_FACT11 ((uint16_t)0x0800) /*!<Filter 11 Active */
+#define CAN_FA1R_FACT12 ((uint16_t)0x1000) /*!<Filter 12 Active */
+#define CAN_FA1R_FACT13 ((uint16_t)0x2000) /*!<Filter 13 Active */
+
+/******************* Bit definition for CAN_F0R1 register *******************/
+#define CAN_F0R1_FB0 ((uint32_t)0x00000001) /*!<Filter bit 0 */
+#define CAN_F0R1_FB1 ((uint32_t)0x00000002) /*!<Filter bit 1 */
+#define CAN_F0R1_FB2 ((uint32_t)0x00000004) /*!<Filter bit 2 */
+#define CAN_F0R1_FB3 ((uint32_t)0x00000008) /*!<Filter bit 3 */
+#define CAN_F0R1_FB4 ((uint32_t)0x00000010) /*!<Filter bit 4 */
+#define CAN_F0R1_FB5 ((uint32_t)0x00000020) /*!<Filter bit 5 */
+#define CAN_F0R1_FB6 ((uint32_t)0x00000040) /*!<Filter bit 6 */
+#define CAN_F0R1_FB7 ((uint32_t)0x00000080) /*!<Filter bit 7 */
+#define CAN_F0R1_FB8 ((uint32_t)0x00000100) /*!<Filter bit 8 */
+#define CAN_F0R1_FB9 ((uint32_t)0x00000200) /*!<Filter bit 9 */
+#define CAN_F0R1_FB10 ((uint32_t)0x00000400) /*!<Filter bit 10 */
+#define CAN_F0R1_FB11 ((uint32_t)0x00000800) /*!<Filter bit 11 */
+#define CAN_F0R1_FB12 ((uint32_t)0x00001000) /*!<Filter bit 12 */
+#define CAN_F0R1_FB13 ((uint32_t)0x00002000) /*!<Filter bit 13 */
+#define CAN_F0R1_FB14 ((uint32_t)0x00004000) /*!<Filter bit 14 */
+#define CAN_F0R1_FB15 ((uint32_t)0x00008000) /*!<Filter bit 15 */
+#define CAN_F0R1_FB16 ((uint32_t)0x00010000) /*!<Filter bit 16 */
+#define CAN_F0R1_FB17 ((uint32_t)0x00020000) /*!<Filter bit 17 */
+#define CAN_F0R1_FB18 ((uint32_t)0x00040000) /*!<Filter bit 18 */
+#define CAN_F0R1_FB19 ((uint32_t)0x00080000) /*!<Filter bit 19 */
+#define CAN_F0R1_FB20 ((uint32_t)0x00100000) /*!<Filter bit 20 */
+#define CAN_F0R1_FB21 ((uint32_t)0x00200000) /*!<Filter bit 21 */
+#define CAN_F0R1_FB22 ((uint32_t)0x00400000) /*!<Filter bit 22 */
+#define CAN_F0R1_FB23 ((uint32_t)0x00800000) /*!<Filter bit 23 */
+#define CAN_F0R1_FB24 ((uint32_t)0x01000000) /*!<Filter bit 24 */
+#define CAN_F0R1_FB25 ((uint32_t)0x02000000) /*!<Filter bit 25 */
+#define CAN_F0R1_FB26 ((uint32_t)0x04000000) /*!<Filter bit 26 */
+#define CAN_F0R1_FB27 ((uint32_t)0x08000000) /*!<Filter bit 27 */
+#define CAN_F0R1_FB28 ((uint32_t)0x10000000) /*!<Filter bit 28 */
+#define CAN_F0R1_FB29 ((uint32_t)0x20000000) /*!<Filter bit 29 */
+#define CAN_F0R1_FB30 ((uint32_t)0x40000000) /*!<Filter bit 30 */
+#define CAN_F0R1_FB31 ((uint32_t)0x80000000) /*!<Filter bit 31 */
+
+/******************* Bit definition for CAN_F1R1 register *******************/
+#define CAN_F1R1_FB0 ((uint32_t)0x00000001) /*!<Filter bit 0 */
+#define CAN_F1R1_FB1 ((uint32_t)0x00000002) /*!<Filter bit 1 */
+#define CAN_F1R1_FB2 ((uint32_t)0x00000004) /*!<Filter bit 2 */
+#define CAN_F1R1_FB3 ((uint32_t)0x00000008) /*!<Filter bit 3 */
+#define CAN_F1R1_FB4 ((uint32_t)0x00000010) /*!<Filter bit 4 */
+#define CAN_F1R1_FB5 ((uint32_t)0x00000020) /*!<Filter bit 5 */
+#define CAN_F1R1_FB6 ((uint32_t)0x00000040) /*!<Filter bit 6 */
+#define CAN_F1R1_FB7 ((uint32_t)0x00000080) /*!<Filter bit 7 */
+#define CAN_F1R1_FB8 ((uint32_t)0x00000100) /*!<Filter bit 8 */
+#define CAN_F1R1_FB9 ((uint32_t)0x00000200) /*!<Filter bit 9 */
+#define CAN_F1R1_FB10 ((uint32_t)0x00000400) /*!<Filter bit 10 */
+#define CAN_F1R1_FB11 ((uint32_t)0x00000800) /*!<Filter bit 11 */
+#define CAN_F1R1_FB12 ((uint32_t)0x00001000) /*!<Filter bit 12 */
+#define CAN_F1R1_FB13 ((uint32_t)0x00002000) /*!<Filter bit 13 */
+#define CAN_F1R1_FB14 ((uint32_t)0x00004000) /*!<Filter bit 14 */
+#define CAN_F1R1_FB15 ((uint32_t)0x00008000) /*!<Filter bit 15 */
+#define CAN_F1R1_FB16 ((uint32_t)0x00010000) /*!<Filter bit 16 */
+#define CAN_F1R1_FB17 ((uint32_t)0x00020000) /*!<Filter bit 17 */
+#define CAN_F1R1_FB18 ((uint32_t)0x00040000) /*!<Filter bit 18 */
+#define CAN_F1R1_FB19 ((uint32_t)0x00080000) /*!<Filter bit 19 */
+#define CAN_F1R1_FB20 ((uint32_t)0x00100000) /*!<Filter bit 20 */
+#define CAN_F1R1_FB21 ((uint32_t)0x00200000) /*!<Filter bit 21 */
+#define CAN_F1R1_FB22 ((uint32_t)0x00400000) /*!<Filter bit 22 */
+#define CAN_F1R1_FB23 ((uint32_t)0x00800000) /*!<Filter bit 23 */
+#define CAN_F1R1_FB24 ((uint32_t)0x01000000) /*!<Filter bit 24 */
+#define CAN_F1R1_FB25 ((uint32_t)0x02000000) /*!<Filter bit 25 */
+#define CAN_F1R1_FB26 ((uint32_t)0x04000000) /*!<Filter bit 26 */
+#define CAN_F1R1_FB27 ((uint32_t)0x08000000) /*!<Filter bit 27 */
+#define CAN_F1R1_FB28 ((uint32_t)0x10000000) /*!<Filter bit 28 */
+#define CAN_F1R1_FB29 ((uint32_t)0x20000000) /*!<Filter bit 29 */
+#define CAN_F1R1_FB30 ((uint32_t)0x40000000) /*!<Filter bit 30 */
+#define CAN_F1R1_FB31 ((uint32_t)0x80000000) /*!<Filter bit 31 */
+
+/******************* Bit definition for CAN_F2R1 register *******************/
+#define CAN_F2R1_FB0 ((uint32_t)0x00000001) /*!<Filter bit 0 */
+#define CAN_F2R1_FB1 ((uint32_t)0x00000002) /*!<Filter bit 1 */
+#define CAN_F2R1_FB2 ((uint32_t)0x00000004) /*!<Filter bit 2 */
+#define CAN_F2R1_FB3 ((uint32_t)0x00000008) /*!<Filter bit 3 */
+#define CAN_F2R1_FB4 ((uint32_t)0x00000010) /*!<Filter bit 4 */
+#define CAN_F2R1_FB5 ((uint32_t)0x00000020) /*!<Filter bit 5 */
+#define CAN_F2R1_FB6 ((uint32_t)0x00000040) /*!<Filter bit 6 */
+#define CAN_F2R1_FB7 ((uint32_t)0x00000080) /*!<Filter bit 7 */
+#define CAN_F2R1_FB8 ((uint32_t)0x00000100) /*!<Filter bit 8 */
+#define CAN_F2R1_FB9 ((uint32_t)0x00000200) /*!<Filter bit 9 */
+#define CAN_F2R1_FB10 ((uint32_t)0x00000400) /*!<Filter bit 10 */
+#define CAN_F2R1_FB11 ((uint32_t)0x00000800) /*!<Filter bit 11 */
+#define CAN_F2R1_FB12 ((uint32_t)0x00001000) /*!<Filter bit 12 */
+#define CAN_F2R1_FB13 ((uint32_t)0x00002000) /*!<Filter bit 13 */
+#define CAN_F2R1_FB14 ((uint32_t)0x00004000) /*!<Filter bit 14 */
+#define CAN_F2R1_FB15 ((uint32_t)0x00008000) /*!<Filter bit 15 */
+#define CAN_F2R1_FB16 ((uint32_t)0x00010000) /*!<Filter bit 16 */
+#define CAN_F2R1_FB17 ((uint32_t)0x00020000) /*!<Filter bit 17 */
+#define CAN_F2R1_FB18 ((uint32_t)0x00040000) /*!<Filter bit 18 */
+#define CAN_F2R1_FB19 ((uint32_t)0x00080000) /*!<Filter bit 19 */
+#define CAN_F2R1_FB20 ((uint32_t)0x00100000) /*!<Filter bit 20 */
+#define CAN_F2R1_FB21 ((uint32_t)0x00200000) /*!<Filter bit 21 */
+#define CAN_F2R1_FB22 ((uint32_t)0x00400000) /*!<Filter bit 22 */
+#define CAN_F2R1_FB23 ((uint32_t)0x00800000) /*!<Filter bit 23 */
+#define CAN_F2R1_FB24 ((uint32_t)0x01000000) /*!<Filter bit 24 */
+#define CAN_F2R1_FB25 ((uint32_t)0x02000000) /*!<Filter bit 25 */
+#define CAN_F2R1_FB26 ((uint32_t)0x04000000) /*!<Filter bit 26 */
+#define CAN_F2R1_FB27 ((uint32_t)0x08000000) /*!<Filter bit 27 */
+#define CAN_F2R1_FB28 ((uint32_t)0x10000000) /*!<Filter bit 28 */
+#define CAN_F2R1_FB29 ((uint32_t)0x20000000) /*!<Filter bit 29 */
+#define CAN_F2R1_FB30 ((uint32_t)0x40000000) /*!<Filter bit 30 */
+#define CAN_F2R1_FB31 ((uint32_t)0x80000000) /*!<Filter bit 31 */
+
+/******************* Bit definition for CAN_F3R1 register *******************/
+#define CAN_F3R1_FB0 ((uint32_t)0x00000001) /*!<Filter bit 0 */
+#define CAN_F3R1_FB1 ((uint32_t)0x00000002) /*!<Filter bit 1 */
+#define CAN_F3R1_FB2 ((uint32_t)0x00000004) /*!<Filter bit 2 */
+#define CAN_F3R1_FB3 ((uint32_t)0x00000008) /*!<Filter bit 3 */
+#define CAN_F3R1_FB4 ((uint32_t)0x00000010) /*!<Filter bit 4 */
+#define CAN_F3R1_FB5 ((uint32_t)0x00000020) /*!<Filter bit 5 */
+#define CAN_F3R1_FB6 ((uint32_t)0x00000040) /*!<Filter bit 6 */
+#define CAN_F3R1_FB7 ((uint32_t)0x00000080) /*!<Filter bit 7 */
+#define CAN_F3R1_FB8 ((uint32_t)0x00000100) /*!<Filter bit 8 */
+#define CAN_F3R1_FB9 ((uint32_t)0x00000200) /*!<Filter bit 9 */
+#define CAN_F3R1_FB10 ((uint32_t)0x00000400) /*!<Filter bit 10 */
+#define CAN_F3R1_FB11 ((uint32_t)0x00000800) /*!<Filter bit 11 */
+#define CAN_F3R1_FB12 ((uint32_t)0x00001000) /*!<Filter bit 12 */
+#define CAN_F3R1_FB13 ((uint32_t)0x00002000) /*!<Filter bit 13 */
+#define CAN_F3R1_FB14 ((uint32_t)0x00004000) /*!<Filter bit 14 */
+#define CAN_F3R1_FB15 ((uint32_t)0x00008000) /*!<Filter bit 15 */
+#define CAN_F3R1_FB16 ((uint32_t)0x00010000) /*!<Filter bit 16 */
+#define CAN_F3R1_FB17 ((uint32_t)0x00020000) /*!<Filter bit 17 */
+#define CAN_F3R1_FB18 ((uint32_t)0x00040000) /*!<Filter bit 18 */
+#define CAN_F3R1_FB19 ((uint32_t)0x00080000) /*!<Filter bit 19 */
+#define CAN_F3R1_FB20 ((uint32_t)0x00100000) /*!<Filter bit 20 */
+#define CAN_F3R1_FB21 ((uint32_t)0x00200000) /*!<Filter bit 21 */
+#define CAN_F3R1_FB22 ((uint32_t)0x00400000) /*!<Filter bit 22 */
+#define CAN_F3R1_FB23 ((uint32_t)0x00800000) /*!<Filter bit 23 */
+#define CAN_F3R1_FB24 ((uint32_t)0x01000000) /*!<Filter bit 24 */
+#define CAN_F3R1_FB25 ((uint32_t)0x02000000) /*!<Filter bit 25 */
+#define CAN_F3R1_FB26 ((uint32_t)0x04000000) /*!<Filter bit 26 */
+#define CAN_F3R1_FB27 ((uint32_t)0x08000000) /*!<Filter bit 27 */
+#define CAN_F3R1_FB28 ((uint32_t)0x10000000) /*!<Filter bit 28 */
+#define CAN_F3R1_FB29 ((uint32_t)0x20000000) /*!<Filter bit 29 */
+#define CAN_F3R1_FB30 ((uint32_t)0x40000000) /*!<Filter bit 30 */
+#define CAN_F3R1_FB31 ((uint32_t)0x80000000) /*!<Filter bit 31 */
+
+/******************* Bit definition for CAN_F4R1 register *******************/
+#define CAN_F4R1_FB0 ((uint32_t)0x00000001) /*!<Filter bit 0 */
+#define CAN_F4R1_FB1 ((uint32_t)0x00000002) /*!<Filter bit 1 */
+#define CAN_F4R1_FB2 ((uint32_t)0x00000004) /*!<Filter bit 2 */
+#define CAN_F4R1_FB3 ((uint32_t)0x00000008) /*!<Filter bit 3 */
+#define CAN_F4R1_FB4 ((uint32_t)0x00000010) /*!<Filter bit 4 */
+#define CAN_F4R1_FB5 ((uint32_t)0x00000020) /*!<Filter bit 5 */
+#define CAN_F4R1_FB6 ((uint32_t)0x00000040) /*!<Filter bit 6 */
+#define CAN_F4R1_FB7 ((uint32_t)0x00000080) /*!<Filter bit 7 */
+#define CAN_F4R1_FB8 ((uint32_t)0x00000100) /*!<Filter bit 8 */
+#define CAN_F4R1_FB9 ((uint32_t)0x00000200) /*!<Filter bit 9 */
+#define CAN_F4R1_FB10 ((uint32_t)0x00000400) /*!<Filter bit 10 */
+#define CAN_F4R1_FB11 ((uint32_t)0x00000800) /*!<Filter bit 11 */
+#define CAN_F4R1_FB12 ((uint32_t)0x00001000) /*!<Filter bit 12 */
+#define CAN_F4R1_FB13 ((uint32_t)0x00002000) /*!<Filter bit 13 */
+#define CAN_F4R1_FB14 ((uint32_t)0x00004000) /*!<Filter bit 14 */
+#define CAN_F4R1_FB15 ((uint32_t)0x00008000) /*!<Filter bit 15 */
+#define CAN_F4R1_FB16 ((uint32_t)0x00010000) /*!<Filter bit 16 */
+#define CAN_F4R1_FB17 ((uint32_t)0x00020000) /*!<Filter bit 17 */
+#define CAN_F4R1_FB18 ((uint32_t)0x00040000) /*!<Filter bit 18 */
+#define CAN_F4R1_FB19 ((uint32_t)0x00080000) /*!<Filter bit 19 */
+#define CAN_F4R1_FB20 ((uint32_t)0x00100000) /*!<Filter bit 20 */
+#define CAN_F4R1_FB21 ((uint32_t)0x00200000) /*!<Filter bit 21 */
+#define CAN_F4R1_FB22 ((uint32_t)0x00400000) /*!<Filter bit 22 */
+#define CAN_F4R1_FB23 ((uint32_t)0x00800000) /*!<Filter bit 23 */
+#define CAN_F4R1_FB24 ((uint32_t)0x01000000) /*!<Filter bit 24 */
+#define CAN_F4R1_FB25 ((uint32_t)0x02000000) /*!<Filter bit 25 */
+#define CAN_F4R1_FB26 ((uint32_t)0x04000000) /*!<Filter bit 26 */
+#define CAN_F4R1_FB27 ((uint32_t)0x08000000) /*!<Filter bit 27 */
+#define CAN_F4R1_FB28 ((uint32_t)0x10000000) /*!<Filter bit 28 */
+#define CAN_F4R1_FB29 ((uint32_t)0x20000000) /*!<Filter bit 29 */
+#define CAN_F4R1_FB30 ((uint32_t)0x40000000) /*!<Filter bit 30 */
+#define CAN_F4R1_FB31 ((uint32_t)0x80000000) /*!<Filter bit 31 */
+
+/******************* Bit definition for CAN_F5R1 register *******************/
+#define CAN_F5R1_FB0 ((uint32_t)0x00000001) /*!<Filter bit 0 */
+#define CAN_F5R1_FB1 ((uint32_t)0x00000002) /*!<Filter bit 1 */
+#define CAN_F5R1_FB2 ((uint32_t)0x00000004) /*!<Filter bit 2 */
+#define CAN_F5R1_FB3 ((uint32_t)0x00000008) /*!<Filter bit 3 */
+#define CAN_F5R1_FB4 ((uint32_t)0x00000010) /*!<Filter bit 4 */
+#define CAN_F5R1_FB5 ((uint32_t)0x00000020) /*!<Filter bit 5 */
+#define CAN_F5R1_FB6 ((uint32_t)0x00000040) /*!<Filter bit 6 */
+#define CAN_F5R1_FB7 ((uint32_t)0x00000080) /*!<Filter bit 7 */
+#define CAN_F5R1_FB8 ((uint32_t)0x00000100) /*!<Filter bit 8 */
+#define CAN_F5R1_FB9 ((uint32_t)0x00000200) /*!<Filter bit 9 */
+#define CAN_F5R1_FB10 ((uint32_t)0x00000400) /*!<Filter bit 10 */
+#define CAN_F5R1_FB11 ((uint32_t)0x00000800) /*!<Filter bit 11 */
+#define CAN_F5R1_FB12 ((uint32_t)0x00001000) /*!<Filter bit 12 */
+#define CAN_F5R1_FB13 ((uint32_t)0x00002000) /*!<Filter bit 13 */
+#define CAN_F5R1_FB14 ((uint32_t)0x00004000) /*!<Filter bit 14 */
+#define CAN_F5R1_FB15 ((uint32_t)0x00008000) /*!<Filter bit 15 */
+#define CAN_F5R1_FB16 ((uint32_t)0x00010000) /*!<Filter bit 16 */
+#define CAN_F5R1_FB17 ((uint32_t)0x00020000) /*!<Filter bit 17 */
+#define CAN_F5R1_FB18 ((uint32_t)0x00040000) /*!<Filter bit 18 */
+#define CAN_F5R1_FB19 ((uint32_t)0x00080000) /*!<Filter bit 19 */
+#define CAN_F5R1_FB20 ((uint32_t)0x00100000) /*!<Filter bit 20 */
+#define CAN_F5R1_FB21 ((uint32_t)0x00200000) /*!<Filter bit 21 */
+#define CAN_F5R1_FB22 ((uint32_t)0x00400000) /*!<Filter bit 22 */
+#define CAN_F5R1_FB23 ((uint32_t)0x00800000) /*!<Filter bit 23 */
+#define CAN_F5R1_FB24 ((uint32_t)0x01000000) /*!<Filter bit 24 */
+#define CAN_F5R1_FB25 ((uint32_t)0x02000000) /*!<Filter bit 25 */
+#define CAN_F5R1_FB26 ((uint32_t)0x04000000) /*!<Filter bit 26 */
+#define CAN_F5R1_FB27 ((uint32_t)0x08000000) /*!<Filter bit 27 */
+#define CAN_F5R1_FB28 ((uint32_t)0x10000000) /*!<Filter bit 28 */
+#define CAN_F5R1_FB29 ((uint32_t)0x20000000) /*!<Filter bit 29 */
+#define CAN_F5R1_FB30 ((uint32_t)0x40000000) /*!<Filter bit 30 */
+#define CAN_F5R1_FB31 ((uint32_t)0x80000000) /*!<Filter bit 31 */
+
+/******************* Bit definition for CAN_F6R1 register *******************/
+#define CAN_F6R1_FB0 ((uint32_t)0x00000001) /*!<Filter bit 0 */
+#define CAN_F6R1_FB1 ((uint32_t)0x00000002) /*!<Filter bit 1 */
+#define CAN_F6R1_FB2 ((uint32_t)0x00000004) /*!<Filter bit 2 */
+#define CAN_F6R1_FB3 ((uint32_t)0x00000008) /*!<Filter bit 3 */
+#define CAN_F6R1_FB4 ((uint32_t)0x00000010) /*!<Filter bit 4 */
+#define CAN_F6R1_FB5 ((uint32_t)0x00000020) /*!<Filter bit 5 */
+#define CAN_F6R1_FB6 ((uint32_t)0x00000040) /*!<Filter bit 6 */
+#define CAN_F6R1_FB7 ((uint32_t)0x00000080) /*!<Filter bit 7 */
+#define CAN_F6R1_FB8 ((uint32_t)0x00000100) /*!<Filter bit 8 */
+#define CAN_F6R1_FB9 ((uint32_t)0x00000200) /*!<Filter bit 9 */
+#define CAN_F6R1_FB10 ((uint32_t)0x00000400) /*!<Filter bit 10 */
+#define CAN_F6R1_FB11 ((uint32_t)0x00000800) /*!<Filter bit 11 */
+#define CAN_F6R1_FB12 ((uint32_t)0x00001000) /*!<Filter bit 12 */
+#define CAN_F6R1_FB13 ((uint32_t)0x00002000) /*!<Filter bit 13 */
+#define CAN_F6R1_FB14 ((uint32_t)0x00004000) /*!<Filter bit 14 */
+#define CAN_F6R1_FB15 ((uint32_t)0x00008000) /*!<Filter bit 15 */
+#define CAN_F6R1_FB16 ((uint32_t)0x00010000) /*!<Filter bit 16 */
+#define CAN_F6R1_FB17 ((uint32_t)0x00020000) /*!<Filter bit 17 */
+#define CAN_F6R1_FB18 ((uint32_t)0x00040000) /*!<Filter bit 18 */
+#define CAN_F6R1_FB19 ((uint32_t)0x00080000) /*!<Filter bit 19 */
+#define CAN_F6R1_FB20 ((uint32_t)0x00100000) /*!<Filter bit 20 */
+#define CAN_F6R1_FB21 ((uint32_t)0x00200000) /*!<Filter bit 21 */
+#define CAN_F6R1_FB22 ((uint32_t)0x00400000) /*!<Filter bit 22 */
+#define CAN_F6R1_FB23 ((uint32_t)0x00800000) /*!<Filter bit 23 */
+#define CAN_F6R1_FB24 ((uint32_t)0x01000000) /*!<Filter bit 24 */
+#define CAN_F6R1_FB25 ((uint32_t)0x02000000) /*!<Filter bit 25 */
+#define CAN_F6R1_FB26 ((uint32_t)0x04000000) /*!<Filter bit 26 */
+#define CAN_F6R1_FB27 ((uint32_t)0x08000000) /*!<Filter bit 27 */
+#define CAN_F6R1_FB28 ((uint32_t)0x10000000) /*!<Filter bit 28 */
+#define CAN_F6R1_FB29 ((uint32_t)0x20000000) /*!<Filter bit 29 */
+#define CAN_F6R1_FB30 ((uint32_t)0x40000000) /*!<Filter bit 30 */
+#define CAN_F6R1_FB31 ((uint32_t)0x80000000) /*!<Filter bit 31 */
+
+/******************* Bit definition for CAN_F7R1 register *******************/
+#define CAN_F7R1_FB0 ((uint32_t)0x00000001) /*!<Filter bit 0 */
+#define CAN_F7R1_FB1 ((uint32_t)0x00000002) /*!<Filter bit 1 */
+#define CAN_F7R1_FB2 ((uint32_t)0x00000004) /*!<Filter bit 2 */
+#define CAN_F7R1_FB3 ((uint32_t)0x00000008) /*!<Filter bit 3 */
+#define CAN_F7R1_FB4 ((uint32_t)0x00000010) /*!<Filter bit 4 */
+#define CAN_F7R1_FB5 ((uint32_t)0x00000020) /*!<Filter bit 5 */
+#define CAN_F7R1_FB6 ((uint32_t)0x00000040) /*!<Filter bit 6 */
+#define CAN_F7R1_FB7 ((uint32_t)0x00000080) /*!<Filter bit 7 */
+#define CAN_F7R1_FB8 ((uint32_t)0x00000100) /*!<Filter bit 8 */
+#define CAN_F7R1_FB9 ((uint32_t)0x00000200) /*!<Filter bit 9 */
+#define CAN_F7R1_FB10 ((uint32_t)0x00000400) /*!<Filter bit 10 */
+#define CAN_F7R1_FB11 ((uint32_t)0x00000800) /*!<Filter bit 11 */
+#define CAN_F7R1_FB12 ((uint32_t)0x00001000) /*!<Filter bit 12 */
+#define CAN_F7R1_FB13 ((uint32_t)0x00002000) /*!<Filter bit 13 */
+#define CAN_F7R1_FB14 ((uint32_t)0x00004000) /*!<Filter bit 14 */
+#define CAN_F7R1_FB15 ((uint32_t)0x00008000) /*!<Filter bit 15 */
+#define CAN_F7R1_FB16 ((uint32_t)0x00010000) /*!<Filter bit 16 */
+#define CAN_F7R1_FB17 ((uint32_t)0x00020000) /*!<Filter bit 17 */
+#define CAN_F7R1_FB18 ((uint32_t)0x00040000) /*!<Filter bit 18 */
+#define CAN_F7R1_FB19 ((uint32_t)0x00080000) /*!<Filter bit 19 */
+#define CAN_F7R1_FB20 ((uint32_t)0x00100000) /*!<Filter bit 20 */
+#define CAN_F7R1_FB21 ((uint32_t)0x00200000) /*!<Filter bit 21 */
+#define CAN_F7R1_FB22 ((uint32_t)0x00400000) /*!<Filter bit 22 */
+#define CAN_F7R1_FB23 ((uint32_t)0x00800000) /*!<Filter bit 23 */
+#define CAN_F7R1_FB24 ((uint32_t)0x01000000) /*!<Filter bit 24 */
+#define CAN_F7R1_FB25 ((uint32_t)0x02000000) /*!<Filter bit 25 */
+#define CAN_F7R1_FB26 ((uint32_t)0x04000000) /*!<Filter bit 26 */
+#define CAN_F7R1_FB27 ((uint32_t)0x08000000) /*!<Filter bit 27 */
+#define CAN_F7R1_FB28 ((uint32_t)0x10000000) /*!<Filter bit 28 */
+#define CAN_F7R1_FB29 ((uint32_t)0x20000000) /*!<Filter bit 29 */
+#define CAN_F7R1_FB30 ((uint32_t)0x40000000) /*!<Filter bit 30 */
+#define CAN_F7R1_FB31 ((uint32_t)0x80000000) /*!<Filter bit 31 */
+
+/******************* Bit definition for CAN_F8R1 register *******************/
+#define CAN_F8R1_FB0 ((uint32_t)0x00000001) /*!<Filter bit 0 */
+#define CAN_F8R1_FB1 ((uint32_t)0x00000002) /*!<Filter bit 1 */
+#define CAN_F8R1_FB2 ((uint32_t)0x00000004) /*!<Filter bit 2 */
+#define CAN_F8R1_FB3 ((uint32_t)0x00000008) /*!<Filter bit 3 */
+#define CAN_F8R1_FB4 ((uint32_t)0x00000010) /*!<Filter bit 4 */
+#define CAN_F8R1_FB5 ((uint32_t)0x00000020) /*!<Filter bit 5 */
+#define CAN_F8R1_FB6 ((uint32_t)0x00000040) /*!<Filter bit 6 */
+#define CAN_F8R1_FB7 ((uint32_t)0x00000080) /*!<Filter bit 7 */
+#define CAN_F8R1_FB8 ((uint32_t)0x00000100) /*!<Filter bit 8 */
+#define CAN_F8R1_FB9 ((uint32_t)0x00000200) /*!<Filter bit 9 */
+#define CAN_F8R1_FB10 ((uint32_t)0x00000400) /*!<Filter bit 10 */
+#define CAN_F8R1_FB11 ((uint32_t)0x00000800) /*!<Filter bit 11 */
+#define CAN_F8R1_FB12 ((uint32_t)0x00001000) /*!<Filter bit 12 */
+#define CAN_F8R1_FB13 ((uint32_t)0x00002000) /*!<Filter bit 13 */
+#define CAN_F8R1_FB14 ((uint32_t)0x00004000) /*!<Filter bit 14 */
+#define CAN_F8R1_FB15 ((uint32_t)0x00008000) /*!<Filter bit 15 */
+#define CAN_F8R1_FB16 ((uint32_t)0x00010000) /*!<Filter bit 16 */
+#define CAN_F8R1_FB17 ((uint32_t)0x00020000) /*!<Filter bit 17 */
+#define CAN_F8R1_FB18 ((uint32_t)0x00040000) /*!<Filter bit 18 */
+#define CAN_F8R1_FB19 ((uint32_t)0x00080000) /*!<Filter bit 19 */
+#define CAN_F8R1_FB20 ((uint32_t)0x00100000) /*!<Filter bit 20 */
+#define CAN_F8R1_FB21 ((uint32_t)0x00200000) /*!<Filter bit 21 */
+#define CAN_F8R1_FB22 ((uint32_t)0x00400000) /*!<Filter bit 22 */
+#define CAN_F8R1_FB23 ((uint32_t)0x00800000) /*!<Filter bit 23 */
+#define CAN_F8R1_FB24 ((uint32_t)0x01000000) /*!<Filter bit 24 */
+#define CAN_F8R1_FB25 ((uint32_t)0x02000000) /*!<Filter bit 25 */
+#define CAN_F8R1_FB26 ((uint32_t)0x04000000) /*!<Filter bit 26 */
+#define CAN_F8R1_FB27 ((uint32_t)0x08000000) /*!<Filter bit 27 */
+#define CAN_F8R1_FB28 ((uint32_t)0x10000000) /*!<Filter bit 28 */
+#define CAN_F8R1_FB29 ((uint32_t)0x20000000) /*!<Filter bit 29 */
+#define CAN_F8R1_FB30 ((uint32_t)0x40000000) /*!<Filter bit 30 */
+#define CAN_F8R1_FB31 ((uint32_t)0x80000000) /*!<Filter bit 31 */
+
+/******************* Bit definition for CAN_F9R1 register *******************/
+#define CAN_F9R1_FB0 ((uint32_t)0x00000001) /*!<Filter bit 0 */
+#define CAN_F9R1_FB1 ((uint32_t)0x00000002) /*!<Filter bit 1 */
+#define CAN_F9R1_FB2 ((uint32_t)0x00000004) /*!<Filter bit 2 */
+#define CAN_F9R1_FB3 ((uint32_t)0x00000008) /*!<Filter bit 3 */
+#define CAN_F9R1_FB4 ((uint32_t)0x00000010) /*!<Filter bit 4 */
+#define CAN_F9R1_FB5 ((uint32_t)0x00000020) /*!<Filter bit 5 */
+#define CAN_F9R1_FB6 ((uint32_t)0x00000040) /*!<Filter bit 6 */
+#define CAN_F9R1_FB7 ((uint32_t)0x00000080) /*!<Filter bit 7 */
+#define CAN_F9R1_FB8 ((uint32_t)0x00000100) /*!<Filter bit 8 */
+#define CAN_F9R1_FB9 ((uint32_t)0x00000200) /*!<Filter bit 9 */
+#define CAN_F9R1_FB10 ((uint32_t)0x00000400) /*!<Filter bit 10 */
+#define CAN_F9R1_FB11 ((uint32_t)0x00000800) /*!<Filter bit 11 */
+#define CAN_F9R1_FB12 ((uint32_t)0x00001000) /*!<Filter bit 12 */
+#define CAN_F9R1_FB13 ((uint32_t)0x00002000) /*!<Filter bit 13 */
+#define CAN_F9R1_FB14 ((uint32_t)0x00004000) /*!<Filter bit 14 */
+#define CAN_F9R1_FB15 ((uint32_t)0x00008000) /*!<Filter bit 15 */
+#define CAN_F9R1_FB16 ((uint32_t)0x00010000) /*!<Filter bit 16 */
+#define CAN_F9R1_FB17 ((uint32_t)0x00020000) /*!<Filter bit 17 */
+#define CAN_F9R1_FB18 ((uint32_t)0x00040000) /*!<Filter bit 18 */
+#define CAN_F9R1_FB19 ((uint32_t)0x00080000) /*!<Filter bit 19 */
+#define CAN_F9R1_FB20 ((uint32_t)0x00100000) /*!<Filter bit 20 */
+#define CAN_F9R1_FB21 ((uint32_t)0x00200000) /*!<Filter bit 21 */
+#define CAN_F9R1_FB22 ((uint32_t)0x00400000) /*!<Filter bit 22 */
+#define CAN_F9R1_FB23 ((uint32_t)0x00800000) /*!<Filter bit 23 */
+#define CAN_F9R1_FB24 ((uint32_t)0x01000000) /*!<Filter bit 24 */
+#define CAN_F9R1_FB25 ((uint32_t)0x02000000) /*!<Filter bit 25 */
+#define CAN_F9R1_FB26 ((uint32_t)0x04000000) /*!<Filter bit 26 */
+#define CAN_F9R1_FB27 ((uint32_t)0x08000000) /*!<Filter bit 27 */
+#define CAN_F9R1_FB28 ((uint32_t)0x10000000) /*!<Filter bit 28 */
+#define CAN_F9R1_FB29 ((uint32_t)0x20000000) /*!<Filter bit 29 */
+#define CAN_F9R1_FB30 ((uint32_t)0x40000000) /*!<Filter bit 30 */
+#define CAN_F9R1_FB31 ((uint32_t)0x80000000) /*!<Filter bit 31 */
+
+/******************* Bit definition for CAN_F10R1 register ******************/
+#define CAN_F10R1_FB0 ((uint32_t)0x00000001) /*!<Filter bit 0 */
+#define CAN_F10R1_FB1 ((uint32_t)0x00000002) /*!<Filter bit 1 */
+#define CAN_F10R1_FB2 ((uint32_t)0x00000004) /*!<Filter bit 2 */
+#define CAN_F10R1_FB3 ((uint32_t)0x00000008) /*!<Filter bit 3 */
+#define CAN_F10R1_FB4 ((uint32_t)0x00000010) /*!<Filter bit 4 */
+#define CAN_F10R1_FB5 ((uint32_t)0x00000020) /*!<Filter bit 5 */
+#define CAN_F10R1_FB6 ((uint32_t)0x00000040) /*!<Filter bit 6 */
+#define CAN_F10R1_FB7 ((uint32_t)0x00000080) /*!<Filter bit 7 */
+#define CAN_F10R1_FB8 ((uint32_t)0x00000100) /*!<Filter bit 8 */
+#define CAN_F10R1_FB9 ((uint32_t)0x00000200) /*!<Filter bit 9 */
+#define CAN_F10R1_FB10 ((uint32_t)0x00000400) /*!<Filter bit 10 */
+#define CAN_F10R1_FB11 ((uint32_t)0x00000800) /*!<Filter bit 11 */
+#define CAN_F10R1_FB12 ((uint32_t)0x00001000) /*!<Filter bit 12 */
+#define CAN_F10R1_FB13 ((uint32_t)0x00002000) /*!<Filter bit 13 */
+#define CAN_F10R1_FB14 ((uint32_t)0x00004000) /*!<Filter bit 14 */
+#define CAN_F10R1_FB15 ((uint32_t)0x00008000) /*!<Filter bit 15 */
+#define CAN_F10R1_FB16 ((uint32_t)0x00010000) /*!<Filter bit 16 */
+#define CAN_F10R1_FB17 ((uint32_t)0x00020000) /*!<Filter bit 17 */
+#define CAN_F10R1_FB18 ((uint32_t)0x00040000) /*!<Filter bit 18 */
+#define CAN_F10R1_FB19 ((uint32_t)0x00080000) /*!<Filter bit 19 */
+#define CAN_F10R1_FB20 ((uint32_t)0x00100000) /*!<Filter bit 20 */
+#define CAN_F10R1_FB21 ((uint32_t)0x00200000) /*!<Filter bit 21 */
+#define CAN_F10R1_FB22 ((uint32_t)0x00400000) /*!<Filter bit 22 */
+#define CAN_F10R1_FB23 ((uint32_t)0x00800000) /*!<Filter bit 23 */
+#define CAN_F10R1_FB24 ((uint32_t)0x01000000) /*!<Filter bit 24 */
+#define CAN_F10R1_FB25 ((uint32_t)0x02000000) /*!<Filter bit 25 */
+#define CAN_F10R1_FB26 ((uint32_t)0x04000000) /*!<Filter bit 26 */
+#define CAN_F10R1_FB27 ((uint32_t)0x08000000) /*!<Filter bit 27 */
+#define CAN_F10R1_FB28 ((uint32_t)0x10000000) /*!<Filter bit 28 */
+#define CAN_F10R1_FB29 ((uint32_t)0x20000000) /*!<Filter bit 29 */
+#define CAN_F10R1_FB30 ((uint32_t)0x40000000) /*!<Filter bit 30 */
+#define CAN_F10R1_FB31 ((uint32_t)0x80000000) /*!<Filter bit 31 */
+
+/******************* Bit definition for CAN_F11R1 register ******************/
+#define CAN_F11R1_FB0 ((uint32_t)0x00000001) /*!<Filter bit 0 */
+#define CAN_F11R1_FB1 ((uint32_t)0x00000002) /*!<Filter bit 1 */
+#define CAN_F11R1_FB2 ((uint32_t)0x00000004) /*!<Filter bit 2 */
+#define CAN_F11R1_FB3 ((uint32_t)0x00000008) /*!<Filter bit 3 */
+#define CAN_F11R1_FB4 ((uint32_t)0x00000010) /*!<Filter bit 4 */
+#define CAN_F11R1_FB5 ((uint32_t)0x00000020) /*!<Filter bit 5 */
+#define CAN_F11R1_FB6 ((uint32_t)0x00000040) /*!<Filter bit 6 */
+#define CAN_F11R1_FB7 ((uint32_t)0x00000080) /*!<Filter bit 7 */
+#define CAN_F11R1_FB8 ((uint32_t)0x00000100) /*!<Filter bit 8 */
+#define CAN_F11R1_FB9 ((uint32_t)0x00000200) /*!<Filter bit 9 */
+#define CAN_F11R1_FB10 ((uint32_t)0x00000400) /*!<Filter bit 10 */
+#define CAN_F11R1_FB11 ((uint32_t)0x00000800) /*!<Filter bit 11 */
+#define CAN_F11R1_FB12 ((uint32_t)0x00001000) /*!<Filter bit 12 */
+#define CAN_F11R1_FB13 ((uint32_t)0x00002000) /*!<Filter bit 13 */
+#define CAN_F11R1_FB14 ((uint32_t)0x00004000) /*!<Filter bit 14 */
+#define CAN_F11R1_FB15 ((uint32_t)0x00008000) /*!<Filter bit 15 */
+#define CAN_F11R1_FB16 ((uint32_t)0x00010000) /*!<Filter bit 16 */
+#define CAN_F11R1_FB17 ((uint32_t)0x00020000) /*!<Filter bit 17 */
+#define CAN_F11R1_FB18 ((uint32_t)0x00040000) /*!<Filter bit 18 */
+#define CAN_F11R1_FB19 ((uint32_t)0x00080000) /*!<Filter bit 19 */
+#define CAN_F11R1_FB20 ((uint32_t)0x00100000) /*!<Filter bit 20 */
+#define CAN_F11R1_FB21 ((uint32_t)0x00200000) /*!<Filter bit 21 */
+#define CAN_F11R1_FB22 ((uint32_t)0x00400000) /*!<Filter bit 22 */
+#define CAN_F11R1_FB23 ((uint32_t)0x00800000) /*!<Filter bit 23 */
+#define CAN_F11R1_FB24 ((uint32_t)0x01000000) /*!<Filter bit 24 */
+#define CAN_F11R1_FB25 ((uint32_t)0x02000000) /*!<Filter bit 25 */
+#define CAN_F11R1_FB26 ((uint32_t)0x04000000) /*!<Filter bit 26 */
+#define CAN_F11R1_FB27 ((uint32_t)0x08000000) /*!<Filter bit 27 */
+#define CAN_F11R1_FB28 ((uint32_t)0x10000000) /*!<Filter bit 28 */
+#define CAN_F11R1_FB29 ((uint32_t)0x20000000) /*!<Filter bit 29 */
+#define CAN_F11R1_FB30 ((uint32_t)0x40000000) /*!<Filter bit 30 */
+#define CAN_F11R1_FB31 ((uint32_t)0x80000000) /*!<Filter bit 31 */
+
+/******************* Bit definition for CAN_F12R1 register ******************/
+#define CAN_F12R1_FB0 ((uint32_t)0x00000001) /*!<Filter bit 0 */
+#define CAN_F12R1_FB1 ((uint32_t)0x00000002) /*!<Filter bit 1 */
+#define CAN_F12R1_FB2 ((uint32_t)0x00000004) /*!<Filter bit 2 */
+#define CAN_F12R1_FB3 ((uint32_t)0x00000008) /*!<Filter bit 3 */
+#define CAN_F12R1_FB4 ((uint32_t)0x00000010) /*!<Filter bit 4 */
+#define CAN_F12R1_FB5 ((uint32_t)0x00000020) /*!<Filter bit 5 */
+#define CAN_F12R1_FB6 ((uint32_t)0x00000040) /*!<Filter bit 6 */
+#define CAN_F12R1_FB7 ((uint32_t)0x00000080) /*!<Filter bit 7 */
+#define CAN_F12R1_FB8 ((uint32_t)0x00000100) /*!<Filter bit 8 */
+#define CAN_F12R1_FB9 ((uint32_t)0x00000200) /*!<Filter bit 9 */
+#define CAN_F12R1_FB10 ((uint32_t)0x00000400) /*!<Filter bit 10 */
+#define CAN_F12R1_FB11 ((uint32_t)0x00000800) /*!<Filter bit 11 */
+#define CAN_F12R1_FB12 ((uint32_t)0x00001000) /*!<Filter bit 12 */
+#define CAN_F12R1_FB13 ((uint32_t)0x00002000) /*!<Filter bit 13 */
+#define CAN_F12R1_FB14 ((uint32_t)0x00004000) /*!<Filter bit 14 */
+#define CAN_F12R1_FB15 ((uint32_t)0x00008000) /*!<Filter bit 15 */
+#define CAN_F12R1_FB16 ((uint32_t)0x00010000) /*!<Filter bit 16 */
+#define CAN_F12R1_FB17 ((uint32_t)0x00020000) /*!<Filter bit 17 */
+#define CAN_F12R1_FB18 ((uint32_t)0x00040000) /*!<Filter bit 18 */
+#define CAN_F12R1_FB19 ((uint32_t)0x00080000) /*!<Filter bit 19 */
+#define CAN_F12R1_FB20 ((uint32_t)0x00100000) /*!<Filter bit 20 */
+#define CAN_F12R1_FB21 ((uint32_t)0x00200000) /*!<Filter bit 21 */
+#define CAN_F12R1_FB22 ((uint32_t)0x00400000) /*!<Filter bit 22 */
+#define CAN_F12R1_FB23 ((uint32_t)0x00800000) /*!<Filter bit 23 */
+#define CAN_F12R1_FB24 ((uint32_t)0x01000000) /*!<Filter bit 24 */
+#define CAN_F12R1_FB25 ((uint32_t)0x02000000) /*!<Filter bit 25 */
+#define CAN_F12R1_FB26 ((uint32_t)0x04000000) /*!<Filter bit 26 */
+#define CAN_F12R1_FB27 ((uint32_t)0x08000000) /*!<Filter bit 27 */
+#define CAN_F12R1_FB28 ((uint32_t)0x10000000) /*!<Filter bit 28 */
+#define CAN_F12R1_FB29 ((uint32_t)0x20000000) /*!<Filter bit 29 */
+#define CAN_F12R1_FB30 ((uint32_t)0x40000000) /*!<Filter bit 30 */
+#define CAN_F12R1_FB31 ((uint32_t)0x80000000) /*!<Filter bit 31 */
+
+/******************* Bit definition for CAN_F13R1 register ******************/
+#define CAN_F13R1_FB0 ((uint32_t)0x00000001) /*!<Filter bit 0 */
+#define CAN_F13R1_FB1 ((uint32_t)0x00000002) /*!<Filter bit 1 */
+#define CAN_F13R1_FB2 ((uint32_t)0x00000004) /*!<Filter bit 2 */
+#define CAN_F13R1_FB3 ((uint32_t)0x00000008) /*!<Filter bit 3 */
+#define CAN_F13R1_FB4 ((uint32_t)0x00000010) /*!<Filter bit 4 */
+#define CAN_F13R1_FB5 ((uint32_t)0x00000020) /*!<Filter bit 5 */
+#define CAN_F13R1_FB6 ((uint32_t)0x00000040) /*!<Filter bit 6 */
+#define CAN_F13R1_FB7 ((uint32_t)0x00000080) /*!<Filter bit 7 */
+#define CAN_F13R1_FB8 ((uint32_t)0x00000100) /*!<Filter bit 8 */
+#define CAN_F13R1_FB9 ((uint32_t)0x00000200) /*!<Filter bit 9 */
+#define CAN_F13R1_FB10 ((uint32_t)0x00000400) /*!<Filter bit 10 */
+#define CAN_F13R1_FB11 ((uint32_t)0x00000800) /*!<Filter bit 11 */
+#define CAN_F13R1_FB12 ((uint32_t)0x00001000) /*!<Filter bit 12 */
+#define CAN_F13R1_FB13 ((uint32_t)0x00002000) /*!<Filter bit 13 */
+#define CAN_F13R1_FB14 ((uint32_t)0x00004000) /*!<Filter bit 14 */
+#define CAN_F13R1_FB15 ((uint32_t)0x00008000) /*!<Filter bit 15 */
+#define CAN_F13R1_FB16 ((uint32_t)0x00010000) /*!<Filter bit 16 */
+#define CAN_F13R1_FB17 ((uint32_t)0x00020000) /*!<Filter bit 17 */
+#define CAN_F13R1_FB18 ((uint32_t)0x00040000) /*!<Filter bit 18 */
+#define CAN_F13R1_FB19 ((uint32_t)0x00080000) /*!<Filter bit 19 */
+#define CAN_F13R1_FB20 ((uint32_t)0x00100000) /*!<Filter bit 20 */
+#define CAN_F13R1_FB21 ((uint32_t)0x00200000) /*!<Filter bit 21 */
+#define CAN_F13R1_FB22 ((uint32_t)0x00400000) /*!<Filter bit 22 */
+#define CAN_F13R1_FB23 ((uint32_t)0x00800000) /*!<Filter bit 23 */
+#define CAN_F13R1_FB24 ((uint32_t)0x01000000) /*!<Filter bit 24 */
+#define CAN_F13R1_FB25 ((uint32_t)0x02000000) /*!<Filter bit 25 */
+#define CAN_F13R1_FB26 ((uint32_t)0x04000000) /*!<Filter bit 26 */
+#define CAN_F13R1_FB27 ((uint32_t)0x08000000) /*!<Filter bit 27 */
+#define CAN_F13R1_FB28 ((uint32_t)0x10000000) /*!<Filter bit 28 */
+#define CAN_F13R1_FB29 ((uint32_t)0x20000000) /*!<Filter bit 29 */
+#define CAN_F13R1_FB30 ((uint32_t)0x40000000) /*!<Filter bit 30 */
+#define CAN_F13R1_FB31 ((uint32_t)0x80000000) /*!<Filter bit 31 */
+
+/******************* Bit definition for CAN_F0R2 register *******************/
+#define CAN_F0R2_FB0 ((uint32_t)0x00000001) /*!<Filter bit 0 */
+#define CAN_F0R2_FB1 ((uint32_t)0x00000002) /*!<Filter bit 1 */
+#define CAN_F0R2_FB2 ((uint32_t)0x00000004) /*!<Filter bit 2 */
+#define CAN_F0R2_FB3 ((uint32_t)0x00000008) /*!<Filter bit 3 */
+#define CAN_F0R2_FB4 ((uint32_t)0x00000010) /*!<Filter bit 4 */
+#define CAN_F0R2_FB5 ((uint32_t)0x00000020) /*!<Filter bit 5 */
+#define CAN_F0R2_FB6 ((uint32_t)0x00000040) /*!<Filter bit 6 */
+#define CAN_F0R2_FB7 ((uint32_t)0x00000080) /*!<Filter bit 7 */
+#define CAN_F0R2_FB8 ((uint32_t)0x00000100) /*!<Filter bit 8 */
+#define CAN_F0R2_FB9 ((uint32_t)0x00000200) /*!<Filter bit 9 */
+#define CAN_F0R2_FB10 ((uint32_t)0x00000400) /*!<Filter bit 10 */
+#define CAN_F0R2_FB11 ((uint32_t)0x00000800) /*!<Filter bit 11 */
+#define CAN_F0R2_FB12 ((uint32_t)0x00001000) /*!<Filter bit 12 */
+#define CAN_F0R2_FB13 ((uint32_t)0x00002000) /*!<Filter bit 13 */
+#define CAN_F0R2_FB14 ((uint32_t)0x00004000) /*!<Filter bit 14 */
+#define CAN_F0R2_FB15 ((uint32_t)0x00008000) /*!<Filter bit 15 */
+#define CAN_F0R2_FB16 ((uint32_t)0x00010000) /*!<Filter bit 16 */
+#define CAN_F0R2_FB17 ((uint32_t)0x00020000) /*!<Filter bit 17 */
+#define CAN_F0R2_FB18 ((uint32_t)0x00040000) /*!<Filter bit 18 */
+#define CAN_F0R2_FB19 ((uint32_t)0x00080000) /*!<Filter bit 19 */
+#define CAN_F0R2_FB20 ((uint32_t)0x00100000) /*!<Filter bit 20 */
+#define CAN_F0R2_FB21 ((uint32_t)0x00200000) /*!<Filter bit 21 */
+#define CAN_F0R2_FB22 ((uint32_t)0x00400000) /*!<Filter bit 22 */
+#define CAN_F0R2_FB23 ((uint32_t)0x00800000) /*!<Filter bit 23 */
+#define CAN_F0R2_FB24 ((uint32_t)0x01000000) /*!<Filter bit 24 */
+#define CAN_F0R2_FB25 ((uint32_t)0x02000000) /*!<Filter bit 25 */
+#define CAN_F0R2_FB26 ((uint32_t)0x04000000) /*!<Filter bit 26 */
+#define CAN_F0R2_FB27 ((uint32_t)0x08000000) /*!<Filter bit 27 */
+#define CAN_F0R2_FB28 ((uint32_t)0x10000000) /*!<Filter bit 28 */
+#define CAN_F0R2_FB29 ((uint32_t)0x20000000) /*!<Filter bit 29 */
+#define CAN_F0R2_FB30 ((uint32_t)0x40000000) /*!<Filter bit 30 */
+#define CAN_F0R2_FB31 ((uint32_t)0x80000000) /*!<Filter bit 31 */
+
+/******************* Bit definition for CAN_F1R2 register *******************/
+#define CAN_F1R2_FB0 ((uint32_t)0x00000001) /*!<Filter bit 0 */
+#define CAN_F1R2_FB1 ((uint32_t)0x00000002) /*!<Filter bit 1 */
+#define CAN_F1R2_FB2 ((uint32_t)0x00000004) /*!<Filter bit 2 */
+#define CAN_F1R2_FB3 ((uint32_t)0x00000008) /*!<Filter bit 3 */
+#define CAN_F1R2_FB4 ((uint32_t)0x00000010) /*!<Filter bit 4 */
+#define CAN_F1R2_FB5 ((uint32_t)0x00000020) /*!<Filter bit 5 */
+#define CAN_F1R2_FB6 ((uint32_t)0x00000040) /*!<Filter bit 6 */
+#define CAN_F1R2_FB7 ((uint32_t)0x00000080) /*!<Filter bit 7 */
+#define CAN_F1R2_FB8 ((uint32_t)0x00000100) /*!<Filter bit 8 */
+#define CAN_F1R2_FB9 ((uint32_t)0x00000200) /*!<Filter bit 9 */
+#define CAN_F1R2_FB10 ((uint32_t)0x00000400) /*!<Filter bit 10 */
+#define CAN_F1R2_FB11 ((uint32_t)0x00000800) /*!<Filter bit 11 */
+#define CAN_F1R2_FB12 ((uint32_t)0x00001000) /*!<Filter bit 12 */
+#define CAN_F1R2_FB13 ((uint32_t)0x00002000) /*!<Filter bit 13 */
+#define CAN_F1R2_FB14 ((uint32_t)0x00004000) /*!<Filter bit 14 */
+#define CAN_F1R2_FB15 ((uint32_t)0x00008000) /*!<Filter bit 15 */
+#define CAN_F1R2_FB16 ((uint32_t)0x00010000) /*!<Filter bit 16 */
+#define CAN_F1R2_FB17 ((uint32_t)0x00020000) /*!<Filter bit 17 */
+#define CAN_F1R2_FB18 ((uint32_t)0x00040000) /*!<Filter bit 18 */
+#define CAN_F1R2_FB19 ((uint32_t)0x00080000) /*!<Filter bit 19 */
+#define CAN_F1R2_FB20 ((uint32_t)0x00100000) /*!<Filter bit 20 */
+#define CAN_F1R2_FB21 ((uint32_t)0x00200000) /*!<Filter bit 21 */
+#define CAN_F1R2_FB22 ((uint32_t)0x00400000) /*!<Filter bit 22 */
+#define CAN_F1R2_FB23 ((uint32_t)0x00800000) /*!<Filter bit 23 */
+#define CAN_F1R2_FB24 ((uint32_t)0x01000000) /*!<Filter bit 24 */
+#define CAN_F1R2_FB25 ((uint32_t)0x02000000) /*!<Filter bit 25 */
+#define CAN_F1R2_FB26 ((uint32_t)0x04000000) /*!<Filter bit 26 */
+#define CAN_F1R2_FB27 ((uint32_t)0x08000000) /*!<Filter bit 27 */
+#define CAN_F1R2_FB28 ((uint32_t)0x10000000) /*!<Filter bit 28 */
+#define CAN_F1R2_FB29 ((uint32_t)0x20000000) /*!<Filter bit 29 */
+#define CAN_F1R2_FB30 ((uint32_t)0x40000000) /*!<Filter bit 30 */
+#define CAN_F1R2_FB31 ((uint32_t)0x80000000) /*!<Filter bit 31 */
+
+/******************* Bit definition for CAN_F2R2 register *******************/
+#define CAN_F2R2_FB0 ((uint32_t)0x00000001) /*!<Filter bit 0 */
+#define CAN_F2R2_FB1 ((uint32_t)0x00000002) /*!<Filter bit 1 */
+#define CAN_F2R2_FB2 ((uint32_t)0x00000004) /*!<Filter bit 2 */
+#define CAN_F2R2_FB3 ((uint32_t)0x00000008) /*!<Filter bit 3 */
+#define CAN_F2R2_FB4 ((uint32_t)0x00000010) /*!<Filter bit 4 */
+#define CAN_F2R2_FB5 ((uint32_t)0x00000020) /*!<Filter bit 5 */
+#define CAN_F2R2_FB6 ((uint32_t)0x00000040) /*!<Filter bit 6 */
+#define CAN_F2R2_FB7 ((uint32_t)0x00000080) /*!<Filter bit 7 */
+#define CAN_F2R2_FB8 ((uint32_t)0x00000100) /*!<Filter bit 8 */
+#define CAN_F2R2_FB9 ((uint32_t)0x00000200) /*!<Filter bit 9 */
+#define CAN_F2R2_FB10 ((uint32_t)0x00000400) /*!<Filter bit 10 */
+#define CAN_F2R2_FB11 ((uint32_t)0x00000800) /*!<Filter bit 11 */
+#define CAN_F2R2_FB12 ((uint32_t)0x00001000) /*!<Filter bit 12 */
+#define CAN_F2R2_FB13 ((uint32_t)0x00002000) /*!<Filter bit 13 */
+#define CAN_F2R2_FB14 ((uint32_t)0x00004000) /*!<Filter bit 14 */
+#define CAN_F2R2_FB15 ((uint32_t)0x00008000) /*!<Filter bit 15 */
+#define CAN_F2R2_FB16 ((uint32_t)0x00010000) /*!<Filter bit 16 */
+#define CAN_F2R2_FB17 ((uint32_t)0x00020000) /*!<Filter bit 17 */
+#define CAN_F2R2_FB18 ((uint32_t)0x00040000) /*!<Filter bit 18 */
+#define CAN_F2R2_FB19 ((uint32_t)0x00080000) /*!<Filter bit 19 */
+#define CAN_F2R2_FB20 ((uint32_t)0x00100000) /*!<Filter bit 20 */
+#define CAN_F2R2_FB21 ((uint32_t)0x00200000) /*!<Filter bit 21 */
+#define CAN_F2R2_FB22 ((uint32_t)0x00400000) /*!<Filter bit 22 */
+#define CAN_F2R2_FB23 ((uint32_t)0x00800000) /*!<Filter bit 23 */
+#define CAN_F2R2_FB24 ((uint32_t)0x01000000) /*!<Filter bit 24 */
+#define CAN_F2R2_FB25 ((uint32_t)0x02000000) /*!<Filter bit 25 */
+#define CAN_F2R2_FB26 ((uint32_t)0x04000000) /*!<Filter bit 26 */
+#define CAN_F2R2_FB27 ((uint32_t)0x08000000) /*!<Filter bit 27 */
+#define CAN_F2R2_FB28 ((uint32_t)0x10000000) /*!<Filter bit 28 */
+#define CAN_F2R2_FB29 ((uint32_t)0x20000000) /*!<Filter bit 29 */
+#define CAN_F2R2_FB30 ((uint32_t)0x40000000) /*!<Filter bit 30 */
+#define CAN_F2R2_FB31 ((uint32_t)0x80000000) /*!<Filter bit 31 */
+
+/******************* Bit definition for CAN_F3R2 register *******************/
+#define CAN_F3R2_FB0 ((uint32_t)0x00000001) /*!<Filter bit 0 */
+#define CAN_F3R2_FB1 ((uint32_t)0x00000002) /*!<Filter bit 1 */
+#define CAN_F3R2_FB2 ((uint32_t)0x00000004) /*!<Filter bit 2 */
+#define CAN_F3R2_FB3 ((uint32_t)0x00000008) /*!<Filter bit 3 */
+#define CAN_F3R2_FB4 ((uint32_t)0x00000010) /*!<Filter bit 4 */
+#define CAN_F3R2_FB5 ((uint32_t)0x00000020) /*!<Filter bit 5 */
+#define CAN_F3R2_FB6 ((uint32_t)0x00000040) /*!<Filter bit 6 */
+#define CAN_F3R2_FB7 ((uint32_t)0x00000080) /*!<Filter bit 7 */
+#define CAN_F3R2_FB8 ((uint32_t)0x00000100) /*!<Filter bit 8 */
+#define CAN_F3R2_FB9 ((uint32_t)0x00000200) /*!<Filter bit 9 */
+#define CAN_F3R2_FB10 ((uint32_t)0x00000400) /*!<Filter bit 10 */
+#define CAN_F3R2_FB11 ((uint32_t)0x00000800) /*!<Filter bit 11 */
+#define CAN_F3R2_FB12 ((uint32_t)0x00001000) /*!<Filter bit 12 */
+#define CAN_F3R2_FB13 ((uint32_t)0x00002000) /*!<Filter bit 13 */
+#define CAN_F3R2_FB14 ((uint32_t)0x00004000) /*!<Filter bit 14 */
+#define CAN_F3R2_FB15 ((uint32_t)0x00008000) /*!<Filter bit 15 */
+#define CAN_F3R2_FB16 ((uint32_t)0x00010000) /*!<Filter bit 16 */
+#define CAN_F3R2_FB17 ((uint32_t)0x00020000) /*!<Filter bit 17 */
+#define CAN_F3R2_FB18 ((uint32_t)0x00040000) /*!<Filter bit 18 */
+#define CAN_F3R2_FB19 ((uint32_t)0x00080000) /*!<Filter bit 19 */
+#define CAN_F3R2_FB20 ((uint32_t)0x00100000) /*!<Filter bit 20 */
+#define CAN_F3R2_FB21 ((uint32_t)0x00200000) /*!<Filter bit 21 */
+#define CAN_F3R2_FB22 ((uint32_t)0x00400000) /*!<Filter bit 22 */
+#define CAN_F3R2_FB23 ((uint32_t)0x00800000) /*!<Filter bit 23 */
+#define CAN_F3R2_FB24 ((uint32_t)0x01000000) /*!<Filter bit 24 */
+#define CAN_F3R2_FB25 ((uint32_t)0x02000000) /*!<Filter bit 25 */
+#define CAN_F3R2_FB26 ((uint32_t)0x04000000) /*!<Filter bit 26 */
+#define CAN_F3R2_FB27 ((uint32_t)0x08000000) /*!<Filter bit 27 */
+#define CAN_F3R2_FB28 ((uint32_t)0x10000000) /*!<Filter bit 28 */
+#define CAN_F3R2_FB29 ((uint32_t)0x20000000) /*!<Filter bit 29 */
+#define CAN_F3R2_FB30 ((uint32_t)0x40000000) /*!<Filter bit 30 */
+#define CAN_F3R2_FB31 ((uint32_t)0x80000000) /*!<Filter bit 31 */
+
+/******************* Bit definition for CAN_F4R2 register *******************/
+#define CAN_F4R2_FB0 ((uint32_t)0x00000001) /*!<Filter bit 0 */
+#define CAN_F4R2_FB1 ((uint32_t)0x00000002) /*!<Filter bit 1 */
+#define CAN_F4R2_FB2 ((uint32_t)0x00000004) /*!<Filter bit 2 */
+#define CAN_F4R2_FB3 ((uint32_t)0x00000008) /*!<Filter bit 3 */
+#define CAN_F4R2_FB4 ((uint32_t)0x00000010) /*!<Filter bit 4 */
+#define CAN_F4R2_FB5 ((uint32_t)0x00000020) /*!<Filter bit 5 */
+#define CAN_F4R2_FB6 ((uint32_t)0x00000040) /*!<Filter bit 6 */
+#define CAN_F4R2_FB7 ((uint32_t)0x00000080) /*!<Filter bit 7 */
+#define CAN_F4R2_FB8 ((uint32_t)0x00000100) /*!<Filter bit 8 */
+#define CAN_F4R2_FB9 ((uint32_t)0x00000200) /*!<Filter bit 9 */
+#define CAN_F4R2_FB10 ((uint32_t)0x00000400) /*!<Filter bit 10 */
+#define CAN_F4R2_FB11 ((uint32_t)0x00000800) /*!<Filter bit 11 */
+#define CAN_F4R2_FB12 ((uint32_t)0x00001000) /*!<Filter bit 12 */
+#define CAN_F4R2_FB13 ((uint32_t)0x00002000) /*!<Filter bit 13 */
+#define CAN_F4R2_FB14 ((uint32_t)0x00004000) /*!<Filter bit 14 */
+#define CAN_F4R2_FB15 ((uint32_t)0x00008000) /*!<Filter bit 15 */
+#define CAN_F4R2_FB16 ((uint32_t)0x00010000) /*!<Filter bit 16 */
+#define CAN_F4R2_FB17 ((uint32_t)0x00020000) /*!<Filter bit 17 */
+#define CAN_F4R2_FB18 ((uint32_t)0x00040000) /*!<Filter bit 18 */
+#define CAN_F4R2_FB19 ((uint32_t)0x00080000) /*!<Filter bit 19 */
+#define CAN_F4R2_FB20 ((uint32_t)0x00100000) /*!<Filter bit 20 */
+#define CAN_F4R2_FB21 ((uint32_t)0x00200000) /*!<Filter bit 21 */
+#define CAN_F4R2_FB22 ((uint32_t)0x00400000) /*!<Filter bit 22 */
+#define CAN_F4R2_FB23 ((uint32_t)0x00800000) /*!<Filter bit 23 */
+#define CAN_F4R2_FB24 ((uint32_t)0x01000000) /*!<Filter bit 24 */
+#define CAN_F4R2_FB25 ((uint32_t)0x02000000) /*!<Filter bit 25 */
+#define CAN_F4R2_FB26 ((uint32_t)0x04000000) /*!<Filter bit 26 */
+#define CAN_F4R2_FB27 ((uint32_t)0x08000000) /*!<Filter bit 27 */
+#define CAN_F4R2_FB28 ((uint32_t)0x10000000) /*!<Filter bit 28 */
+#define CAN_F4R2_FB29 ((uint32_t)0x20000000) /*!<Filter bit 29 */
+#define CAN_F4R2_FB30 ((uint32_t)0x40000000) /*!<Filter bit 30 */
+#define CAN_F4R2_FB31 ((uint32_t)0x80000000) /*!<Filter bit 31 */
+
+/******************* Bit definition for CAN_F5R2 register *******************/
+#define CAN_F5R2_FB0 ((uint32_t)0x00000001) /*!<Filter bit 0 */
+#define CAN_F5R2_FB1 ((uint32_t)0x00000002) /*!<Filter bit 1 */
+#define CAN_F5R2_FB2 ((uint32_t)0x00000004) /*!<Filter bit 2 */
+#define CAN_F5R2_FB3 ((uint32_t)0x00000008) /*!<Filter bit 3 */
+#define CAN_F5R2_FB4 ((uint32_t)0x00000010) /*!<Filter bit 4 */
+#define CAN_F5R2_FB5 ((uint32_t)0x00000020) /*!<Filter bit 5 */
+#define CAN_F5R2_FB6 ((uint32_t)0x00000040) /*!<Filter bit 6 */
+#define CAN_F5R2_FB7 ((uint32_t)0x00000080) /*!<Filter bit 7 */
+#define CAN_F5R2_FB8 ((uint32_t)0x00000100) /*!<Filter bit 8 */
+#define CAN_F5R2_FB9 ((uint32_t)0x00000200) /*!<Filter bit 9 */
+#define CAN_F5R2_FB10 ((uint32_t)0x00000400) /*!<Filter bit 10 */
+#define CAN_F5R2_FB11 ((uint32_t)0x00000800) /*!<Filter bit 11 */
+#define CAN_F5R2_FB12 ((uint32_t)0x00001000) /*!<Filter bit 12 */
+#define CAN_F5R2_FB13 ((uint32_t)0x00002000) /*!<Filter bit 13 */
+#define CAN_F5R2_FB14 ((uint32_t)0x00004000) /*!<Filter bit 14 */
+#define CAN_F5R2_FB15 ((uint32_t)0x00008000) /*!<Filter bit 15 */
+#define CAN_F5R2_FB16 ((uint32_t)0x00010000) /*!<Filter bit 16 */
+#define CAN_F5R2_FB17 ((uint32_t)0x00020000) /*!<Filter bit 17 */
+#define CAN_F5R2_FB18 ((uint32_t)0x00040000) /*!<Filter bit 18 */
+#define CAN_F5R2_FB19 ((uint32_t)0x00080000) /*!<Filter bit 19 */
+#define CAN_F5R2_FB20 ((uint32_t)0x00100000) /*!<Filter bit 20 */
+#define CAN_F5R2_FB21 ((uint32_t)0x00200000) /*!<Filter bit 21 */
+#define CAN_F5R2_FB22 ((uint32_t)0x00400000) /*!<Filter bit 22 */
+#define CAN_F5R2_FB23 ((uint32_t)0x00800000) /*!<Filter bit 23 */
+#define CAN_F5R2_FB24 ((uint32_t)0x01000000) /*!<Filter bit 24 */
+#define CAN_F5R2_FB25 ((uint32_t)0x02000000) /*!<Filter bit 25 */
+#define CAN_F5R2_FB26 ((uint32_t)0x04000000) /*!<Filter bit 26 */
+#define CAN_F5R2_FB27 ((uint32_t)0x08000000) /*!<Filter bit 27 */
+#define CAN_F5R2_FB28 ((uint32_t)0x10000000) /*!<Filter bit 28 */
+#define CAN_F5R2_FB29 ((uint32_t)0x20000000) /*!<Filter bit 29 */
+#define CAN_F5R2_FB30 ((uint32_t)0x40000000) /*!<Filter bit 30 */
+#define CAN_F5R2_FB31 ((uint32_t)0x80000000) /*!<Filter bit 31 */
+
+/******************* Bit definition for CAN_F6R2 register *******************/
+#define CAN_F6R2_FB0 ((uint32_t)0x00000001) /*!<Filter bit 0 */
+#define CAN_F6R2_FB1 ((uint32_t)0x00000002) /*!<Filter bit 1 */
+#define CAN_F6R2_FB2 ((uint32_t)0x00000004) /*!<Filter bit 2 */
+#define CAN_F6R2_FB3 ((uint32_t)0x00000008) /*!<Filter bit 3 */
+#define CAN_F6R2_FB4 ((uint32_t)0x00000010) /*!<Filter bit 4 */
+#define CAN_F6R2_FB5 ((uint32_t)0x00000020) /*!<Filter bit 5 */
+#define CAN_F6R2_FB6 ((uint32_t)0x00000040) /*!<Filter bit 6 */
+#define CAN_F6R2_FB7 ((uint32_t)0x00000080) /*!<Filter bit 7 */
+#define CAN_F6R2_FB8 ((uint32_t)0x00000100) /*!<Filter bit 8 */
+#define CAN_F6R2_FB9 ((uint32_t)0x00000200) /*!<Filter bit 9 */
+#define CAN_F6R2_FB10 ((uint32_t)0x00000400) /*!<Filter bit 10 */
+#define CAN_F6R2_FB11 ((uint32_t)0x00000800) /*!<Filter bit 11 */
+#define CAN_F6R2_FB12 ((uint32_t)0x00001000) /*!<Filter bit 12 */
+#define CAN_F6R2_FB13 ((uint32_t)0x00002000) /*!<Filter bit 13 */
+#define CAN_F6R2_FB14 ((uint32_t)0x00004000) /*!<Filter bit 14 */
+#define CAN_F6R2_FB15 ((uint32_t)0x00008000) /*!<Filter bit 15 */
+#define CAN_F6R2_FB16 ((uint32_t)0x00010000) /*!<Filter bit 16 */
+#define CAN_F6R2_FB17 ((uint32_t)0x00020000) /*!<Filter bit 17 */
+#define CAN_F6R2_FB18 ((uint32_t)0x00040000) /*!<Filter bit 18 */
+#define CAN_F6R2_FB19 ((uint32_t)0x00080000) /*!<Filter bit 19 */
+#define CAN_F6R2_FB20 ((uint32_t)0x00100000) /*!<Filter bit 20 */
+#define CAN_F6R2_FB21 ((uint32_t)0x00200000) /*!<Filter bit 21 */
+#define CAN_F6R2_FB22 ((uint32_t)0x00400000) /*!<Filter bit 22 */
+#define CAN_F6R2_FB23 ((uint32_t)0x00800000) /*!<Filter bit 23 */
+#define CAN_F6R2_FB24 ((uint32_t)0x01000000) /*!<Filter bit 24 */
+#define CAN_F6R2_FB25 ((uint32_t)0x02000000) /*!<Filter bit 25 */
+#define CAN_F6R2_FB26 ((uint32_t)0x04000000) /*!<Filter bit 26 */
+#define CAN_F6R2_FB27 ((uint32_t)0x08000000) /*!<Filter bit 27 */
+#define CAN_F6R2_FB28 ((uint32_t)0x10000000) /*!<Filter bit 28 */
+#define CAN_F6R2_FB29 ((uint32_t)0x20000000) /*!<Filter bit 29 */
+#define CAN_F6R2_FB30 ((uint32_t)0x40000000) /*!<Filter bit 30 */
+#define CAN_F6R2_FB31 ((uint32_t)0x80000000) /*!<Filter bit 31 */
+
+/******************* Bit definition for CAN_F7R2 register *******************/
+#define CAN_F7R2_FB0 ((uint32_t)0x00000001) /*!<Filter bit 0 */
+#define CAN_F7R2_FB1 ((uint32_t)0x00000002) /*!<Filter bit 1 */
+#define CAN_F7R2_FB2 ((uint32_t)0x00000004) /*!<Filter bit 2 */
+#define CAN_F7R2_FB3 ((uint32_t)0x00000008) /*!<Filter bit 3 */
+#define CAN_F7R2_FB4 ((uint32_t)0x00000010) /*!<Filter bit 4 */
+#define CAN_F7R2_FB5 ((uint32_t)0x00000020) /*!<Filter bit 5 */
+#define CAN_F7R2_FB6 ((uint32_t)0x00000040) /*!<Filter bit 6 */
+#define CAN_F7R2_FB7 ((uint32_t)0x00000080) /*!<Filter bit 7 */
+#define CAN_F7R2_FB8 ((uint32_t)0x00000100) /*!<Filter bit 8 */
+#define CAN_F7R2_FB9 ((uint32_t)0x00000200) /*!<Filter bit 9 */
+#define CAN_F7R2_FB10 ((uint32_t)0x00000400) /*!<Filter bit 10 */
+#define CAN_F7R2_FB11 ((uint32_t)0x00000800) /*!<Filter bit 11 */
+#define CAN_F7R2_FB12 ((uint32_t)0x00001000) /*!<Filter bit 12 */
+#define CAN_F7R2_FB13 ((uint32_t)0x00002000) /*!<Filter bit 13 */
+#define CAN_F7R2_FB14 ((uint32_t)0x00004000) /*!<Filter bit 14 */
+#define CAN_F7R2_FB15 ((uint32_t)0x00008000) /*!<Filter bit 15 */
+#define CAN_F7R2_FB16 ((uint32_t)0x00010000) /*!<Filter bit 16 */
+#define CAN_F7R2_FB17 ((uint32_t)0x00020000) /*!<Filter bit 17 */
+#define CAN_F7R2_FB18 ((uint32_t)0x00040000) /*!<Filter bit 18 */
+#define CAN_F7R2_FB19 ((uint32_t)0x00080000) /*!<Filter bit 19 */
+#define CAN_F7R2_FB20 ((uint32_t)0x00100000) /*!<Filter bit 20 */
+#define CAN_F7R2_FB21 ((uint32_t)0x00200000) /*!<Filter bit 21 */
+#define CAN_F7R2_FB22 ((uint32_t)0x00400000) /*!<Filter bit 22 */
+#define CAN_F7R2_FB23 ((uint32_t)0x00800000) /*!<Filter bit 23 */
+#define CAN_F7R2_FB24 ((uint32_t)0x01000000) /*!<Filter bit 24 */
+#define CAN_F7R2_FB25 ((uint32_t)0x02000000) /*!<Filter bit 25 */
+#define CAN_F7R2_FB26 ((uint32_t)0x04000000) /*!<Filter bit 26 */
+#define CAN_F7R2_FB27 ((uint32_t)0x08000000) /*!<Filter bit 27 */
+#define CAN_F7R2_FB28 ((uint32_t)0x10000000) /*!<Filter bit 28 */
+#define CAN_F7R2_FB29 ((uint32_t)0x20000000) /*!<Filter bit 29 */
+#define CAN_F7R2_FB30 ((uint32_t)0x40000000) /*!<Filter bit 30 */
+#define CAN_F7R2_FB31 ((uint32_t)0x80000000) /*!<Filter bit 31 */
+
+/******************* Bit definition for CAN_F8R2 register *******************/
+#define CAN_F8R2_FB0 ((uint32_t)0x00000001) /*!<Filter bit 0 */
+#define CAN_F8R2_FB1 ((uint32_t)0x00000002) /*!<Filter bit 1 */
+#define CAN_F8R2_FB2 ((uint32_t)0x00000004) /*!<Filter bit 2 */
+#define CAN_F8R2_FB3 ((uint32_t)0x00000008) /*!<Filter bit 3 */
+#define CAN_F8R2_FB4 ((uint32_t)0x00000010) /*!<Filter bit 4 */
+#define CAN_F8R2_FB5 ((uint32_t)0x00000020) /*!<Filter bit 5 */
+#define CAN_F8R2_FB6 ((uint32_t)0x00000040) /*!<Filter bit 6 */
+#define CAN_F8R2_FB7 ((uint32_t)0x00000080) /*!<Filter bit 7 */
+#define CAN_F8R2_FB8 ((uint32_t)0x00000100) /*!<Filter bit 8 */
+#define CAN_F8R2_FB9 ((uint32_t)0x00000200) /*!<Filter bit 9 */
+#define CAN_F8R2_FB10 ((uint32_t)0x00000400) /*!<Filter bit 10 */
+#define CAN_F8R2_FB11 ((uint32_t)0x00000800) /*!<Filter bit 11 */
+#define CAN_F8R2_FB12 ((uint32_t)0x00001000) /*!<Filter bit 12 */
+#define CAN_F8R2_FB13 ((uint32_t)0x00002000) /*!<Filter bit 13 */
+#define CAN_F8R2_FB14 ((uint32_t)0x00004000) /*!<Filter bit 14 */
+#define CAN_F8R2_FB15 ((uint32_t)0x00008000) /*!<Filter bit 15 */
+#define CAN_F8R2_FB16 ((uint32_t)0x00010000) /*!<Filter bit 16 */
+#define CAN_F8R2_FB17 ((uint32_t)0x00020000) /*!<Filter bit 17 */
+#define CAN_F8R2_FB18 ((uint32_t)0x00040000) /*!<Filter bit 18 */
+#define CAN_F8R2_FB19 ((uint32_t)0x00080000) /*!<Filter bit 19 */
+#define CAN_F8R2_FB20 ((uint32_t)0x00100000) /*!<Filter bit 20 */
+#define CAN_F8R2_FB21 ((uint32_t)0x00200000) /*!<Filter bit 21 */
+#define CAN_F8R2_FB22 ((uint32_t)0x00400000) /*!<Filter bit 22 */
+#define CAN_F8R2_FB23 ((uint32_t)0x00800000) /*!<Filter bit 23 */
+#define CAN_F8R2_FB24 ((uint32_t)0x01000000) /*!<Filter bit 24 */
+#define CAN_F8R2_FB25 ((uint32_t)0x02000000) /*!<Filter bit 25 */
+#define CAN_F8R2_FB26 ((uint32_t)0x04000000) /*!<Filter bit 26 */
+#define CAN_F8R2_FB27 ((uint32_t)0x08000000) /*!<Filter bit 27 */
+#define CAN_F8R2_FB28 ((uint32_t)0x10000000) /*!<Filter bit 28 */
+#define CAN_F8R2_FB29 ((uint32_t)0x20000000) /*!<Filter bit 29 */
+#define CAN_F8R2_FB30 ((uint32_t)0x40000000) /*!<Filter bit 30 */
+#define CAN_F8R2_FB31 ((uint32_t)0x80000000) /*!<Filter bit 31 */
+
+/******************* Bit definition for CAN_F9R2 register *******************/
+#define CAN_F9R2_FB0 ((uint32_t)0x00000001) /*!<Filter bit 0 */
+#define CAN_F9R2_FB1 ((uint32_t)0x00000002) /*!<Filter bit 1 */
+#define CAN_F9R2_FB2 ((uint32_t)0x00000004) /*!<Filter bit 2 */
+#define CAN_F9R2_FB3 ((uint32_t)0x00000008) /*!<Filter bit 3 */
+#define CAN_F9R2_FB4 ((uint32_t)0x00000010) /*!<Filter bit 4 */
+#define CAN_F9R2_FB5 ((uint32_t)0x00000020) /*!<Filter bit 5 */
+#define CAN_F9R2_FB6 ((uint32_t)0x00000040) /*!<Filter bit 6 */
+#define CAN_F9R2_FB7 ((uint32_t)0x00000080) /*!<Filter bit 7 */
+#define CAN_F9R2_FB8 ((uint32_t)0x00000100) /*!<Filter bit 8 */
+#define CAN_F9R2_FB9 ((uint32_t)0x00000200) /*!<Filter bit 9 */
+#define CAN_F9R2_FB10 ((uint32_t)0x00000400) /*!<Filter bit 10 */
+#define CAN_F9R2_FB11 ((uint32_t)0x00000800) /*!<Filter bit 11 */
+#define CAN_F9R2_FB12 ((uint32_t)0x00001000) /*!<Filter bit 12 */
+#define CAN_F9R2_FB13 ((uint32_t)0x00002000) /*!<Filter bit 13 */
+#define CAN_F9R2_FB14 ((uint32_t)0x00004000) /*!<Filter bit 14 */
+#define CAN_F9R2_FB15 ((uint32_t)0x00008000) /*!<Filter bit 15 */
+#define CAN_F9R2_FB16 ((uint32_t)0x00010000) /*!<Filter bit 16 */
+#define CAN_F9R2_FB17 ((uint32_t)0x00020000) /*!<Filter bit 17 */
+#define CAN_F9R2_FB18 ((uint32_t)0x00040000) /*!<Filter bit 18 */
+#define CAN_F9R2_FB19 ((uint32_t)0x00080000) /*!<Filter bit 19 */
+#define CAN_F9R2_FB20 ((uint32_t)0x00100000) /*!<Filter bit 20 */
+#define CAN_F9R2_FB21 ((uint32_t)0x00200000) /*!<Filter bit 21 */
+#define CAN_F9R2_FB22 ((uint32_t)0x00400000) /*!<Filter bit 22 */
+#define CAN_F9R2_FB23 ((uint32_t)0x00800000) /*!<Filter bit 23 */
+#define CAN_F9R2_FB24 ((uint32_t)0x01000000) /*!<Filter bit 24 */
+#define CAN_F9R2_FB25 ((uint32_t)0x02000000) /*!<Filter bit 25 */
+#define CAN_F9R2_FB26 ((uint32_t)0x04000000) /*!<Filter bit 26 */
+#define CAN_F9R2_FB27 ((uint32_t)0x08000000) /*!<Filter bit 27 */
+#define CAN_F9R2_FB28 ((uint32_t)0x10000000) /*!<Filter bit 28 */
+#define CAN_F9R2_FB29 ((uint32_t)0x20000000) /*!<Filter bit 29 */
+#define CAN_F9R2_FB30 ((uint32_t)0x40000000) /*!<Filter bit 30 */
+#define CAN_F9R2_FB31 ((uint32_t)0x80000000) /*!<Filter bit 31 */
+
+/******************* Bit definition for CAN_F10R2 register ******************/
+#define CAN_F10R2_FB0 ((uint32_t)0x00000001) /*!<Filter bit 0 */
+#define CAN_F10R2_FB1 ((uint32_t)0x00000002) /*!<Filter bit 1 */
+#define CAN_F10R2_FB2 ((uint32_t)0x00000004) /*!<Filter bit 2 */
+#define CAN_F10R2_FB3 ((uint32_t)0x00000008) /*!<Filter bit 3 */
+#define CAN_F10R2_FB4 ((uint32_t)0x00000010) /*!<Filter bit 4 */
+#define CAN_F10R2_FB5 ((uint32_t)0x00000020) /*!<Filter bit 5 */
+#define CAN_F10R2_FB6 ((uint32_t)0x00000040) /*!<Filter bit 6 */
+#define CAN_F10R2_FB7 ((uint32_t)0x00000080) /*!<Filter bit 7 */
+#define CAN_F10R2_FB8 ((uint32_t)0x00000100) /*!<Filter bit 8 */
+#define CAN_F10R2_FB9 ((uint32_t)0x00000200) /*!<Filter bit 9 */
+#define CAN_F10R2_FB10 ((uint32_t)0x00000400) /*!<Filter bit 10 */
+#define CAN_F10R2_FB11 ((uint32_t)0x00000800) /*!<Filter bit 11 */
+#define CAN_F10R2_FB12 ((uint32_t)0x00001000) /*!<Filter bit 12 */
+#define CAN_F10R2_FB13 ((uint32_t)0x00002000) /*!<Filter bit 13 */
+#define CAN_F10R2_FB14 ((uint32_t)0x00004000) /*!<Filter bit 14 */
+#define CAN_F10R2_FB15 ((uint32_t)0x00008000) /*!<Filter bit 15 */
+#define CAN_F10R2_FB16 ((uint32_t)0x00010000) /*!<Filter bit 16 */
+#define CAN_F10R2_FB17 ((uint32_t)0x00020000) /*!<Filter bit 17 */
+#define CAN_F10R2_FB18 ((uint32_t)0x00040000) /*!<Filter bit 18 */
+#define CAN_F10R2_FB19 ((uint32_t)0x00080000) /*!<Filter bit 19 */
+#define CAN_F10R2_FB20 ((uint32_t)0x00100000) /*!<Filter bit 20 */
+#define CAN_F10R2_FB21 ((uint32_t)0x00200000) /*!<Filter bit 21 */
+#define CAN_F10R2_FB22 ((uint32_t)0x00400000) /*!<Filter bit 22 */
+#define CAN_F10R2_FB23 ((uint32_t)0x00800000) /*!<Filter bit 23 */
+#define CAN_F10R2_FB24 ((uint32_t)0x01000000) /*!<Filter bit 24 */
+#define CAN_F10R2_FB25 ((uint32_t)0x02000000) /*!<Filter bit 25 */
+#define CAN_F10R2_FB26 ((uint32_t)0x04000000) /*!<Filter bit 26 */
+#define CAN_F10R2_FB27 ((uint32_t)0x08000000) /*!<Filter bit 27 */
+#define CAN_F10R2_FB28 ((uint32_t)0x10000000) /*!<Filter bit 28 */
+#define CAN_F10R2_FB29 ((uint32_t)0x20000000) /*!<Filter bit 29 */
+#define CAN_F10R2_FB30 ((uint32_t)0x40000000) /*!<Filter bit 30 */
+#define CAN_F10R2_FB31 ((uint32_t)0x80000000) /*!<Filter bit 31 */
+
+/******************* Bit definition for CAN_F11R2 register ******************/
+#define CAN_F11R2_FB0 ((uint32_t)0x00000001) /*!<Filter bit 0 */
+#define CAN_F11R2_FB1 ((uint32_t)0x00000002) /*!<Filter bit 1 */
+#define CAN_F11R2_FB2 ((uint32_t)0x00000004) /*!<Filter bit 2 */
+#define CAN_F11R2_FB3 ((uint32_t)0x00000008) /*!<Filter bit 3 */
+#define CAN_F11R2_FB4 ((uint32_t)0x00000010) /*!<Filter bit 4 */
+#define CAN_F11R2_FB5 ((uint32_t)0x00000020) /*!<Filter bit 5 */
+#define CAN_F11R2_FB6 ((uint32_t)0x00000040) /*!<Filter bit 6 */
+#define CAN_F11R2_FB7 ((uint32_t)0x00000080) /*!<Filter bit 7 */
+#define CAN_F11R2_FB8 ((uint32_t)0x00000100) /*!<Filter bit 8 */
+#define CAN_F11R2_FB9 ((uint32_t)0x00000200) /*!<Filter bit 9 */
+#define CAN_F11R2_FB10 ((uint32_t)0x00000400) /*!<Filter bit 10 */
+#define CAN_F11R2_FB11 ((uint32_t)0x00000800) /*!<Filter bit 11 */
+#define CAN_F11R2_FB12 ((uint32_t)0x00001000) /*!<Filter bit 12 */
+#define CAN_F11R2_FB13 ((uint32_t)0x00002000) /*!<Filter bit 13 */
+#define CAN_F11R2_FB14 ((uint32_t)0x00004000) /*!<Filter bit 14 */
+#define CAN_F11R2_FB15 ((uint32_t)0x00008000) /*!<Filter bit 15 */
+#define CAN_F11R2_FB16 ((uint32_t)0x00010000) /*!<Filter bit 16 */
+#define CAN_F11R2_FB17 ((uint32_t)0x00020000) /*!<Filter bit 17 */
+#define CAN_F11R2_FB18 ((uint32_t)0x00040000) /*!<Filter bit 18 */
+#define CAN_F11R2_FB19 ((uint32_t)0x00080000) /*!<Filter bit 19 */
+#define CAN_F11R2_FB20 ((uint32_t)0x00100000) /*!<Filter bit 20 */
+#define CAN_F11R2_FB21 ((uint32_t)0x00200000) /*!<Filter bit 21 */
+#define CAN_F11R2_FB22 ((uint32_t)0x00400000) /*!<Filter bit 22 */
+#define CAN_F11R2_FB23 ((uint32_t)0x00800000) /*!<Filter bit 23 */
+#define CAN_F11R2_FB24 ((uint32_t)0x01000000) /*!<Filter bit 24 */
+#define CAN_F11R2_FB25 ((uint32_t)0x02000000) /*!<Filter bit 25 */
+#define CAN_F11R2_FB26 ((uint32_t)0x04000000) /*!<Filter bit 26 */
+#define CAN_F11R2_FB27 ((uint32_t)0x08000000) /*!<Filter bit 27 */
+#define CAN_F11R2_FB28 ((uint32_t)0x10000000) /*!<Filter bit 28 */
+#define CAN_F11R2_FB29 ((uint32_t)0x20000000) /*!<Filter bit 29 */
+#define CAN_F11R2_FB30 ((uint32_t)0x40000000) /*!<Filter bit 30 */
+#define CAN_F11R2_FB31 ((uint32_t)0x80000000) /*!<Filter bit 31 */
+
+/******************* Bit definition for CAN_F12R2 register ******************/
+#define CAN_F12R2_FB0 ((uint32_t)0x00000001) /*!<Filter bit 0 */
+#define CAN_F12R2_FB1 ((uint32_t)0x00000002) /*!<Filter bit 1 */
+#define CAN_F12R2_FB2 ((uint32_t)0x00000004) /*!<Filter bit 2 */
+#define CAN_F12R2_FB3 ((uint32_t)0x00000008) /*!<Filter bit 3 */
+#define CAN_F12R2_FB4 ((uint32_t)0x00000010) /*!<Filter bit 4 */
+#define CAN_F12R2_FB5 ((uint32_t)0x00000020) /*!<Filter bit 5 */
+#define CAN_F12R2_FB6 ((uint32_t)0x00000040) /*!<Filter bit 6 */
+#define CAN_F12R2_FB7 ((uint32_t)0x00000080) /*!<Filter bit 7 */
+#define CAN_F12R2_FB8 ((uint32_t)0x00000100) /*!<Filter bit 8 */
+#define CAN_F12R2_FB9 ((uint32_t)0x00000200) /*!<Filter bit 9 */
+#define CAN_F12R2_FB10 ((uint32_t)0x00000400) /*!<Filter bit 10 */
+#define CAN_F12R2_FB11 ((uint32_t)0x00000800) /*!<Filter bit 11 */
+#define CAN_F12R2_FB12 ((uint32_t)0x00001000) /*!<Filter bit 12 */
+#define CAN_F12R2_FB13 ((uint32_t)0x00002000) /*!<Filter bit 13 */
+#define CAN_F12R2_FB14 ((uint32_t)0x00004000) /*!<Filter bit 14 */
+#define CAN_F12R2_FB15 ((uint32_t)0x00008000) /*!<Filter bit 15 */
+#define CAN_F12R2_FB16 ((uint32_t)0x00010000) /*!<Filter bit 16 */
+#define CAN_F12R2_FB17 ((uint32_t)0x00020000) /*!<Filter bit 17 */
+#define CAN_F12R2_FB18 ((uint32_t)0x00040000) /*!<Filter bit 18 */
+#define CAN_F12R2_FB19 ((uint32_t)0x00080000) /*!<Filter bit 19 */
+#define CAN_F12R2_FB20 ((uint32_t)0x00100000) /*!<Filter bit 20 */
+#define CAN_F12R2_FB21 ((uint32_t)0x00200000) /*!<Filter bit 21 */
+#define CAN_F12R2_FB22 ((uint32_t)0x00400000) /*!<Filter bit 22 */
+#define CAN_F12R2_FB23 ((uint32_t)0x00800000) /*!<Filter bit 23 */
+#define CAN_F12R2_FB24 ((uint32_t)0x01000000) /*!<Filter bit 24 */
+#define CAN_F12R2_FB25 ((uint32_t)0x02000000) /*!<Filter bit 25 */
+#define CAN_F12R2_FB26 ((uint32_t)0x04000000) /*!<Filter bit 26 */
+#define CAN_F12R2_FB27 ((uint32_t)0x08000000) /*!<Filter bit 27 */
+#define CAN_F12R2_FB28 ((uint32_t)0x10000000) /*!<Filter bit 28 */
+#define CAN_F12R2_FB29 ((uint32_t)0x20000000) /*!<Filter bit 29 */
+#define CAN_F12R2_FB30 ((uint32_t)0x40000000) /*!<Filter bit 30 */
+#define CAN_F12R2_FB31 ((uint32_t)0x80000000) /*!<Filter bit 31 */
+
+/******************* Bit definition for CAN_F13R2 register ******************/
+#define CAN_F13R2_FB0 ((uint32_t)0x00000001) /*!<Filter bit 0 */
+#define CAN_F13R2_FB1 ((uint32_t)0x00000002) /*!<Filter bit 1 */
+#define CAN_F13R2_FB2 ((uint32_t)0x00000004) /*!<Filter bit 2 */
+#define CAN_F13R2_FB3 ((uint32_t)0x00000008) /*!<Filter bit 3 */
+#define CAN_F13R2_FB4 ((uint32_t)0x00000010) /*!<Filter bit 4 */
+#define CAN_F13R2_FB5 ((uint32_t)0x00000020) /*!<Filter bit 5 */
+#define CAN_F13R2_FB6 ((uint32_t)0x00000040) /*!<Filter bit 6 */
+#define CAN_F13R2_FB7 ((uint32_t)0x00000080) /*!<Filter bit 7 */
+#define CAN_F13R2_FB8 ((uint32_t)0x00000100) /*!<Filter bit 8 */
+#define CAN_F13R2_FB9 ((uint32_t)0x00000200) /*!<Filter bit 9 */
+#define CAN_F13R2_FB10 ((uint32_t)0x00000400) /*!<Filter bit 10 */
+#define CAN_F13R2_FB11 ((uint32_t)0x00000800) /*!<Filter bit 11 */
+#define CAN_F13R2_FB12 ((uint32_t)0x00001000) /*!<Filter bit 12 */
+#define CAN_F13R2_FB13 ((uint32_t)0x00002000) /*!<Filter bit 13 */
+#define CAN_F13R2_FB14 ((uint32_t)0x00004000) /*!<Filter bit 14 */
+#define CAN_F13R2_FB15 ((uint32_t)0x00008000) /*!<Filter bit 15 */
+#define CAN_F13R2_FB16 ((uint32_t)0x00010000) /*!<Filter bit 16 */
+#define CAN_F13R2_FB17 ((uint32_t)0x00020000) /*!<Filter bit 17 */
+#define CAN_F13R2_FB18 ((uint32_t)0x00040000) /*!<Filter bit 18 */
+#define CAN_F13R2_FB19 ((uint32_t)0x00080000) /*!<Filter bit 19 */
+#define CAN_F13R2_FB20 ((uint32_t)0x00100000) /*!<Filter bit 20 */
+#define CAN_F13R2_FB21 ((uint32_t)0x00200000) /*!<Filter bit 21 */
+#define CAN_F13R2_FB22 ((uint32_t)0x00400000) /*!<Filter bit 22 */
+#define CAN_F13R2_FB23 ((uint32_t)0x00800000) /*!<Filter bit 23 */
+#define CAN_F13R2_FB24 ((uint32_t)0x01000000) /*!<Filter bit 24 */
+#define CAN_F13R2_FB25 ((uint32_t)0x02000000) /*!<Filter bit 25 */
+#define CAN_F13R2_FB26 ((uint32_t)0x04000000) /*!<Filter bit 26 */
+#define CAN_F13R2_FB27 ((uint32_t)0x08000000) /*!<Filter bit 27 */
+#define CAN_F13R2_FB28 ((uint32_t)0x10000000) /*!<Filter bit 28 */
+#define CAN_F13R2_FB29 ((uint32_t)0x20000000) /*!<Filter bit 29 */
+#define CAN_F13R2_FB30 ((uint32_t)0x40000000) /*!<Filter bit 30 */
+#define CAN_F13R2_FB31 ((uint32_t)0x80000000) /*!<Filter bit 31 */
+
+/******************************************************************************/
+/* */
+/* Serial Peripheral Interface */
+/* */
+/******************************************************************************/
+
+/******************* Bit definition for SPI_CR1 register ********************/
+#define SPI_CR1_CPHA ((uint16_t)0x0001) /*!<Clock Phase */
+#define SPI_CR1_CPOL ((uint16_t)0x0002) /*!<Clock Polarity */
+#define SPI_CR1_MSTR ((uint16_t)0x0004) /*!<Master Selection */
+
+#define SPI_CR1_BR ((uint16_t)0x0038) /*!<BR[2:0] bits (Baud Rate Control) */
+#define SPI_CR1_BR_0 ((uint16_t)0x0008) /*!<Bit 0 */
+#define SPI_CR1_BR_1 ((uint16_t)0x0010) /*!<Bit 1 */
+#define SPI_CR1_BR_2 ((uint16_t)0x0020) /*!<Bit 2 */
+
+#define SPI_CR1_SPE ((uint16_t)0x0040) /*!<SPI Enable */
+#define SPI_CR1_LSBFIRST ((uint16_t)0x0080) /*!<Frame Format */
+#define SPI_CR1_SSI ((uint16_t)0x0100) /*!<Internal slave select */
+#define SPI_CR1_SSM ((uint16_t)0x0200) /*!<Software slave management */
+#define SPI_CR1_RXONLY ((uint16_t)0x0400) /*!<Receive only */
+#define SPI_CR1_DFF ((uint16_t)0x0800) /*!<Data Frame Format */
+#define SPI_CR1_CRCNEXT ((uint16_t)0x1000) /*!<Transmit CRC next */
+#define SPI_CR1_CRCEN ((uint16_t)0x2000) /*!<Hardware CRC calculation enable */
+#define SPI_CR1_BIDIOE ((uint16_t)0x4000) /*!<Output enable in bidirectional mode */
+#define SPI_CR1_BIDIMODE ((uint16_t)0x8000) /*!<Bidirectional data mode enable */
+
+/******************* Bit definition for SPI_CR2 register ********************/
+#define SPI_CR2_RXDMAEN ((uint8_t)0x01) /*!<Rx Buffer DMA Enable */
+#define SPI_CR2_TXDMAEN ((uint8_t)0x02) /*!<Tx Buffer DMA Enable */
+#define SPI_CR2_SSOE ((uint8_t)0x04) /*!<SS Output Enable */
+#define SPI_CR2_ERRIE ((uint8_t)0x20) /*!<Error Interrupt Enable */
+#define SPI_CR2_RXNEIE ((uint8_t)0x40) /*!<RX buffer Not Empty Interrupt Enable */
+#define SPI_CR2_TXEIE ((uint8_t)0x80) /*!<Tx buffer Empty Interrupt Enable */
+
+/******************** Bit definition for SPI_SR register ********************/
+#define SPI_SR_RXNE ((uint8_t)0x01) /*!<Receive buffer Not Empty */
+#define SPI_SR_TXE ((uint8_t)0x02) /*!<Transmit buffer Empty */
+#define SPI_SR_CHSIDE ((uint8_t)0x04) /*!<Channel side */
+#define SPI_SR_UDR ((uint8_t)0x08) /*!<Underrun flag */
+#define SPI_SR_CRCERR ((uint8_t)0x10) /*!<CRC Error flag */
+#define SPI_SR_MODF ((uint8_t)0x20) /*!<Mode fault */
+#define SPI_SR_OVR ((uint8_t)0x40) /*!<Overrun flag */
+#define SPI_SR_BSY ((uint8_t)0x80) /*!<Busy flag */
+
+/******************** Bit definition for SPI_DR register ********************/
+#define SPI_DR_DR ((uint16_t)0xFFFF) /*!<Data Register */
+
+/******************* Bit definition for SPI_CRCPR register ******************/
+#define SPI_CRCPR_CRCPOLY ((uint16_t)0xFFFF) /*!<CRC polynomial register */
+
+/****************** Bit definition for SPI_RXCRCR register ******************/
+#define SPI_RXCRCR_RXCRC ((uint16_t)0xFFFF) /*!<Rx CRC Register */
+
+/****************** Bit definition for SPI_TXCRCR register ******************/
+#define SPI_TXCRCR_TXCRC ((uint16_t)0xFFFF) /*!<Tx CRC Register */
+
+/****************** Bit definition for SPI_I2SCFGR register *****************/
+#define SPI_I2SCFGR_CHLEN ((uint16_t)0x0001) /*!<Channel length (number of bits per audio channel) */
+
+#define SPI_I2SCFGR_DATLEN ((uint16_t)0x0006) /*!<DATLEN[1:0] bits (Data length to be transferred) */
+#define SPI_I2SCFGR_DATLEN_0 ((uint16_t)0x0002) /*!<Bit 0 */
+#define SPI_I2SCFGR_DATLEN_1 ((uint16_t)0x0004) /*!<Bit 1 */
+
+#define SPI_I2SCFGR_CKPOL ((uint16_t)0x0008) /*!<steady state clock polarity */
+
+#define SPI_I2SCFGR_I2SSTD ((uint16_t)0x0030) /*!<I2SSTD[1:0] bits (I2S standard selection) */
+#define SPI_I2SCFGR_I2SSTD_0 ((uint16_t)0x0010) /*!<Bit 0 */
+#define SPI_I2SCFGR_I2SSTD_1 ((uint16_t)0x0020) /*!<Bit 1 */
+
+#define SPI_I2SCFGR_PCMSYNC ((uint16_t)0x0080) /*!<PCM frame synchronization */
+
+#define SPI_I2SCFGR_I2SCFG ((uint16_t)0x0300) /*!<I2SCFG[1:0] bits (I2S configuration mode) */
+#define SPI_I2SCFGR_I2SCFG_0 ((uint16_t)0x0100) /*!<Bit 0 */
+#define SPI_I2SCFGR_I2SCFG_1 ((uint16_t)0x0200) /*!<Bit 1 */
+
+#define SPI_I2SCFGR_I2SE ((uint16_t)0x0400) /*!<I2S Enable */
+#define SPI_I2SCFGR_I2SMOD ((uint16_t)0x0800) /*!<I2S mode selection */
+
+/****************** Bit definition for SPI_I2SPR register *******************/
+#define SPI_I2SPR_I2SDIV ((uint16_t)0x00FF) /*!<I2S Linear prescaler */
+#define SPI_I2SPR_ODD ((uint16_t)0x0100) /*!<Odd factor for the prescaler */
+#define SPI_I2SPR_MCKOE ((uint16_t)0x0200) /*!<Master Clock Output Enable */
+
+/******************************************************************************/
+/* */
+/* Inter-integrated Circuit Interface */
+/* */
+/******************************************************************************/
+
+/******************* Bit definition for I2C_CR1 register ********************/
+#define I2C_CR1_PE ((uint16_t)0x0001) /*!<Peripheral Enable */
+#define I2C_CR1_SMBUS ((uint16_t)0x0002) /*!<SMBus Mode */
+#define I2C_CR1_SMBTYPE ((uint16_t)0x0008) /*!<SMBus Type */
+#define I2C_CR1_ENARP ((uint16_t)0x0010) /*!<ARP Enable */
+#define I2C_CR1_ENPEC ((uint16_t)0x0020) /*!<PEC Enable */
+#define I2C_CR1_ENGC ((uint16_t)0x0040) /*!<General Call Enable */
+#define I2C_CR1_NOSTRETCH ((uint16_t)0x0080) /*!<Clock Stretching Disable (Slave mode) */
+#define I2C_CR1_START ((uint16_t)0x0100) /*!<Start Generation */
+#define I2C_CR1_STOP ((uint16_t)0x0200) /*!<Stop Generation */
+#define I2C_CR1_ACK ((uint16_t)0x0400) /*!<Acknowledge Enable */
+#define I2C_CR1_POS ((uint16_t)0x0800) /*!<Acknowledge/PEC Position (for data reception) */
+#define I2C_CR1_PEC ((uint16_t)0x1000) /*!<Packet Error Checking */
+#define I2C_CR1_ALERT ((uint16_t)0x2000) /*!<SMBus Alert */
+#define I2C_CR1_SWRST ((uint16_t)0x8000) /*!<Software Reset */
+
+/******************* Bit definition for I2C_CR2 register ********************/
+#define I2C_CR2_FREQ ((uint16_t)0x003F) /*!<FREQ[5:0] bits (Peripheral Clock Frequency) */
+#define I2C_CR2_FREQ_0 ((uint16_t)0x0001) /*!<Bit 0 */
+#define I2C_CR2_FREQ_1 ((uint16_t)0x0002) /*!<Bit 1 */
+#define I2C_CR2_FREQ_2 ((uint16_t)0x0004) /*!<Bit 2 */
+#define I2C_CR2_FREQ_3 ((uint16_t)0x0008) /*!<Bit 3 */
+#define I2C_CR2_FREQ_4 ((uint16_t)0x0010) /*!<Bit 4 */
+#define I2C_CR2_FREQ_5 ((uint16_t)0x0020) /*!<Bit 5 */
+
+#define I2C_CR2_ITERREN ((uint16_t)0x0100) /*!<Error Interrupt Enable */
+#define I2C_CR2_ITEVTEN ((uint16_t)0x0200) /*!<Event Interrupt Enable */
+#define I2C_CR2_ITBUFEN ((uint16_t)0x0400) /*!<Buffer Interrupt Enable */
+#define I2C_CR2_DMAEN ((uint16_t)0x0800) /*!<DMA Requests Enable */
+#define I2C_CR2_LAST ((uint16_t)0x1000) /*!<DMA Last Transfer */
+
+/******************* Bit definition for I2C_OAR1 register *******************/
+#define I2C_OAR1_ADD1_7 ((uint16_t)0x00FE) /*!<Interface Address */
+#define I2C_OAR1_ADD8_9 ((uint16_t)0x0300) /*!<Interface Address */
+
+#define I2C_OAR1_ADD0 ((uint16_t)0x0001) /*!<Bit 0 */
+#define I2C_OAR1_ADD1 ((uint16_t)0x0002) /*!<Bit 1 */
+#define I2C_OAR1_ADD2 ((uint16_t)0x0004) /*!<Bit 2 */
+#define I2C_OAR1_ADD3 ((uint16_t)0x0008) /*!<Bit 3 */
+#define I2C_OAR1_ADD4 ((uint16_t)0x0010) /*!<Bit 4 */
+#define I2C_OAR1_ADD5 ((uint16_t)0x0020) /*!<Bit 5 */
+#define I2C_OAR1_ADD6 ((uint16_t)0x0040) /*!<Bit 6 */
+#define I2C_OAR1_ADD7 ((uint16_t)0x0080) /*!<Bit 7 */
+#define I2C_OAR1_ADD8 ((uint16_t)0x0100) /*!<Bit 8 */
+#define I2C_OAR1_ADD9 ((uint16_t)0x0200) /*!<Bit 9 */
+
+#define I2C_OAR1_ADDMODE ((uint16_t)0x8000) /*!<Addressing Mode (Slave mode) */
+
+/******************* Bit definition for I2C_OAR2 register *******************/
+#define I2C_OAR2_ENDUAL ((uint8_t)0x01) /*!<Dual addressing mode enable */
+#define I2C_OAR2_ADD2 ((uint8_t)0xFE) /*!<Interface address */
+
+/******************** Bit definition for I2C_DR register ********************/
+#define I2C_DR_DR ((uint8_t)0xFF) /*!<8-bit Data Register */
+
+/******************* Bit definition for I2C_SR1 register ********************/
+#define I2C_SR1_SB ((uint16_t)0x0001) /*!<Start Bit (Master mode) */
+#define I2C_SR1_ADDR ((uint16_t)0x0002) /*!<Address sent (master mode)/matched (slave mode) */
+#define I2C_SR1_BTF ((uint16_t)0x0004) /*!<Byte Transfer Finished */
+#define I2C_SR1_ADD10 ((uint16_t)0x0008) /*!<10-bit header sent (Master mode) */
+#define I2C_SR1_STOPF ((uint16_t)0x0010) /*!<Stop detection (Slave mode) */
+#define I2C_SR1_RXNE ((uint16_t)0x0040) /*!<Data Register not Empty (receivers) */
+#define I2C_SR1_TXE ((uint16_t)0x0080) /*!<Data Register Empty (transmitters) */
+#define I2C_SR1_BERR ((uint16_t)0x0100) /*!<Bus Error */
+#define I2C_SR1_ARLO ((uint16_t)0x0200) /*!<Arbitration Lost (master mode) */
+#define I2C_SR1_AF ((uint16_t)0x0400) /*!<Acknowledge Failure */
+#define I2C_SR1_OVR ((uint16_t)0x0800) /*!<Overrun/Underrun */
+#define I2C_SR1_PECERR ((uint16_t)0x1000) /*!<PEC Error in reception */
+#define I2C_SR1_TIMEOUT ((uint16_t)0x4000) /*!<Timeout or Tlow Error */
+#define I2C_SR1_SMBALERT ((uint16_t)0x8000) /*!<SMBus Alert */
+
+/******************* Bit definition for I2C_SR2 register ********************/
+#define I2C_SR2_MSL ((uint16_t)0x0001) /*!<Master/Slave */
+#define I2C_SR2_BUSY ((uint16_t)0x0002) /*!<Bus Busy */
+#define I2C_SR2_TRA ((uint16_t)0x0004) /*!<Transmitter/Receiver */
+#define I2C_SR2_GENCALL ((uint16_t)0x0010) /*!<General Call Address (Slave mode) */
+#define I2C_SR2_SMBDEFAULT ((uint16_t)0x0020) /*!<SMBus Device Default Address (Slave mode) */
+#define I2C_SR2_SMBHOST ((uint16_t)0x0040) /*!<SMBus Host Header (Slave mode) */
+#define I2C_SR2_DUALF ((uint16_t)0x0080) /*!<Dual Flag (Slave mode) */
+#define I2C_SR2_PEC ((uint16_t)0xFF00) /*!<Packet Error Checking Register */
+
+/******************* Bit definition for I2C_CCR register ********************/
+#define I2C_CCR_CCR ((uint16_t)0x0FFF) /*!<Clock Control Register in Fast/Standard mode (Master mode) */
+#define I2C_CCR_DUTY ((uint16_t)0x4000) /*!<Fast Mode Duty Cycle */
+#define I2C_CCR_FS ((uint16_t)0x8000) /*!<I2C Master Mode Selection */
+
+/****************** Bit definition for I2C_TRISE register *******************/
+#define I2C_TRISE_TRISE ((uint8_t)0x3F) /*!<Maximum Rise Time in Fast/Standard mode (Master mode) */
+
+/******************************************************************************/
+/* */
+/* Universal Synchronous Asynchronous Receiver Transmitter */
+/* */
+/******************************************************************************/
+
+/******************* Bit definition for USART_SR register *******************/
+#define USART_SR_PE ((uint16_t)0x0001) /*!<Parity Error */
+#define USART_SR_FE ((uint16_t)0x0002) /*!<Framing Error */
+#define USART_SR_NE ((uint16_t)0x0004) /*!<Noise Error Flag */
+#define USART_SR_ORE ((uint16_t)0x0008) /*!<OverRun Error */
+#define USART_SR_IDLE ((uint16_t)0x0010) /*!<IDLE line detected */
+#define USART_SR_RXNE ((uint16_t)0x0020) /*!<Read Data Register Not Empty */
+#define USART_SR_TC ((uint16_t)0x0040) /*!<Transmission Complete */
+#define USART_SR_TXE ((uint16_t)0x0080) /*!<Transmit Data Register Empty */
+#define USART_SR_LBD ((uint16_t)0x0100) /*!<LIN Break Detection Flag */
+#define USART_SR_CTS ((uint16_t)0x0200) /*!<CTS Flag */
+
+/******************* Bit definition for USART_DR register *******************/
+#define USART_DR_DR ((uint16_t)0x01FF) /*!<Data value */
+
+/****************** Bit definition for USART_BRR register *******************/
+#define USART_BRR_DIV_Fraction ((uint16_t)0x000F) /*!<Fraction of USARTDIV */
+#define USART_BRR_DIV_Mantissa ((uint16_t)0xFFF0) /*!<Mantissa of USARTDIV */
+
+/****************** Bit definition for USART_CR1 register *******************/
+#define USART_CR1_SBK ((uint16_t)0x0001) /*!<Send Break */
+#define USART_CR1_RWU ((uint16_t)0x0002) /*!<Receiver wakeup */
+#define USART_CR1_RE ((uint16_t)0x0004) /*!<Receiver Enable */
+#define USART_CR1_TE ((uint16_t)0x0008) /*!<Transmitter Enable */
+#define USART_CR1_IDLEIE ((uint16_t)0x0010) /*!<IDLE Interrupt Enable */
+#define USART_CR1_RXNEIE ((uint16_t)0x0020) /*!<RXNE Interrupt Enable */
+#define USART_CR1_TCIE ((uint16_t)0x0040) /*!<Transmission Complete Interrupt Enable */
+#define USART_CR1_TXEIE ((uint16_t)0x0080) /*!<PE Interrupt Enable */
+#define USART_CR1_PEIE ((uint16_t)0x0100) /*!<PE Interrupt Enable */
+#define USART_CR1_PS ((uint16_t)0x0200) /*!<Parity Selection */
+#define USART_CR1_PCE ((uint16_t)0x0400) /*!<Parity Control Enable */
+#define USART_CR1_WAKE ((uint16_t)0x0800) /*!<Wakeup method */
+#define USART_CR1_M ((uint16_t)0x1000) /*!<Word length */
+#define USART_CR1_UE ((uint16_t)0x2000) /*!<USART Enable */
+
+/****************** Bit definition for USART_CR2 register *******************/
+#define USART_CR2_ADD ((uint16_t)0x000F) /*!<Address of the USART node */
+#define USART_CR2_LBDL ((uint16_t)0x0020) /*!<LIN Break Detection Length */
+#define USART_CR2_LBDIE ((uint16_t)0x0040) /*!<LIN Break Detection Interrupt Enable */
+#define USART_CR2_LBCL ((uint16_t)0x0100) /*!<Last Bit Clock pulse */
+#define USART_CR2_CPHA ((uint16_t)0x0200) /*!<Clock Phase */
+#define USART_CR2_CPOL ((uint16_t)0x0400) /*!<Clock Polarity */
+#define USART_CR2_CLKEN ((uint16_t)0x0800) /*!<Clock Enable */
+
+#define USART_CR2_STOP ((uint16_t)0x3000) /*!<STOP[1:0] bits (STOP bits) */
+#define USART_CR2_STOP_0 ((uint16_t)0x1000) /*!<Bit 0 */
+#define USART_CR2_STOP_1 ((uint16_t)0x2000) /*!<Bit 1 */
+
+#define USART_CR2_LINEN ((uint16_t)0x4000) /*!<LIN mode enable */
+
+/****************** Bit definition for USART_CR3 register *******************/
+#define USART_CR3_EIE ((uint16_t)0x0001) /*!<Error Interrupt Enable */
+#define USART_CR3_IREN ((uint16_t)0x0002) /*!<IrDA mode Enable */
+#define USART_CR3_IRLP ((uint16_t)0x0004) /*!<IrDA Low-Power */
+#define USART_CR3_HDSEL ((uint16_t)0x0008) /*!<Half-Duplex Selection */
+#define USART_CR3_NACK ((uint16_t)0x0010) /*!<Smartcard NACK enable */
+#define USART_CR3_SCEN ((uint16_t)0x0020) /*!<Smartcard mode enable */
+#define USART_CR3_DMAR ((uint16_t)0x0040) /*!<DMA Enable Receiver */
+#define USART_CR3_DMAT ((uint16_t)0x0080) /*!<DMA Enable Transmitter */
+#define USART_CR3_RTSE ((uint16_t)0x0100) /*!<RTS Enable */
+#define USART_CR3_CTSE ((uint16_t)0x0200) /*!<CTS Enable */
+#define USART_CR3_CTSIE ((uint16_t)0x0400) /*!<CTS Interrupt Enable */
+
+/****************** Bit definition for USART_GTPR register ******************/
+#define USART_GTPR_PSC ((uint16_t)0x00FF) /*!<PSC[7:0] bits (Prescaler value) */
+#define USART_GTPR_PSC_0 ((uint16_t)0x0001) /*!<Bit 0 */
+#define USART_GTPR_PSC_1 ((uint16_t)0x0002) /*!<Bit 1 */
+#define USART_GTPR_PSC_2 ((uint16_t)0x0004) /*!<Bit 2 */
+#define USART_GTPR_PSC_3 ((uint16_t)0x0008) /*!<Bit 3 */
+#define USART_GTPR_PSC_4 ((uint16_t)0x0010) /*!<Bit 4 */
+#define USART_GTPR_PSC_5 ((uint16_t)0x0020) /*!<Bit 5 */
+#define USART_GTPR_PSC_6 ((uint16_t)0x0040) /*!<Bit 6 */
+#define USART_GTPR_PSC_7 ((uint16_t)0x0080) /*!<Bit 7 */
+
+#define USART_GTPR_GT ((uint16_t)0xFF00) /*!<Guard time value */
+
+/******************************************************************************/
+/* */
+/* Debug MCU */
+/* */
+/******************************************************************************/
+
+/**************** Bit definition for DBGMCU_IDCODE register *****************/
+#define DBGMCU_IDCODE_DEV_ID ((uint32_t)0x00000FFF) /*!<Device Identifier */
+
+#define DBGMCU_IDCODE_REV_ID ((uint32_t)0xFFFF0000) /*!<REV_ID[15:0] bits (Revision Identifier) */
+#define DBGMCU_IDCODE_REV_ID_0 ((uint32_t)0x00010000) /*!<Bit 0 */
+#define DBGMCU_IDCODE_REV_ID_1 ((uint32_t)0x00020000) /*!<Bit 1 */
+#define DBGMCU_IDCODE_REV_ID_2 ((uint32_t)0x00040000) /*!<Bit 2 */
+#define DBGMCU_IDCODE_REV_ID_3 ((uint32_t)0x00080000) /*!<Bit 3 */
+#define DBGMCU_IDCODE_REV_ID_4 ((uint32_t)0x00100000) /*!<Bit 4 */
+#define DBGMCU_IDCODE_REV_ID_5 ((uint32_t)0x00200000) /*!<Bit 5 */
+#define DBGMCU_IDCODE_REV_ID_6 ((uint32_t)0x00400000) /*!<Bit 6 */
+#define DBGMCU_IDCODE_REV_ID_7 ((uint32_t)0x00800000) /*!<Bit 7 */
+#define DBGMCU_IDCODE_REV_ID_8 ((uint32_t)0x01000000) /*!<Bit 8 */
+#define DBGMCU_IDCODE_REV_ID_9 ((uint32_t)0x02000000) /*!<Bit 9 */
+#define DBGMCU_IDCODE_REV_ID_10 ((uint32_t)0x04000000) /*!<Bit 10 */
+#define DBGMCU_IDCODE_REV_ID_11 ((uint32_t)0x08000000) /*!<Bit 11 */
+#define DBGMCU_IDCODE_REV_ID_12 ((uint32_t)0x10000000) /*!<Bit 12 */
+#define DBGMCU_IDCODE_REV_ID_13 ((uint32_t)0x20000000) /*!<Bit 13 */
+#define DBGMCU_IDCODE_REV_ID_14 ((uint32_t)0x40000000) /*!<Bit 14 */
+#define DBGMCU_IDCODE_REV_ID_15 ((uint32_t)0x80000000) /*!<Bit 15 */
+
+/****************** Bit definition for DBGMCU_CR register *******************/
+#define DBGMCU_CR_DBG_SLEEP ((uint32_t)0x00000001) /*!<Debug Sleep Mode */
+#define DBGMCU_CR_DBG_STOP ((uint32_t)0x00000002) /*!<Debug Stop Mode */
+#define DBGMCU_CR_DBG_STANDBY ((uint32_t)0x00000004) /*!<Debug Standby mode */
+#define DBGMCU_CR_TRACE_IOEN ((uint32_t)0x00000020) /*!<Trace Pin Assignment Control */
+
+#define DBGMCU_CR_TRACE_MODE ((uint32_t)0x000000C0) /*!<TRACE_MODE[1:0] bits (Trace Pin Assignment Control) */
+#define DBGMCU_CR_TRACE_MODE_0 ((uint32_t)0x00000040) /*!<Bit 0 */
+#define DBGMCU_CR_TRACE_MODE_1 ((uint32_t)0x00000080) /*!<Bit 1 */
+
+#define DBGMCU_CR_DBG_IWDG_STOP ((uint32_t)0x00000100) /*!<Debug Independent Watchdog stopped when Core is halted */
+#define DBGMCU_CR_DBG_WWDG_STOP ((uint32_t)0x00000200) /*!<Debug Window Watchdog stopped when Core is halted */
+#define DBGMCU_CR_DBG_TIM1_STOP ((uint32_t)0x00000400) /*!<TIM1 counter stopped when core is halted */
+#define DBGMCU_CR_DBG_TIM2_STOP ((uint32_t)0x00000800) /*!<TIM2 counter stopped when core is halted */
+#define DBGMCU_CR_DBG_TIM3_STOP ((uint32_t)0x00001000) /*!<TIM3 counter stopped when core is halted */
+#define DBGMCU_CR_DBG_TIM4_STOP ((uint32_t)0x00002000) /*!<TIM4 counter stopped when core is halted */
+#define DBGMCU_CR_DBG_CAN1_STOP ((uint32_t)0x00004000) /*!<Debug CAN1 stopped when Core is halted */
+#define DBGMCU_CR_DBG_I2C1_SMBUS_TIMEOUT ((uint32_t)0x00008000) /*!<SMBUS timeout mode stopped when Core is halted */
+#define DBGMCU_CR_DBG_I2C2_SMBUS_TIMEOUT ((uint32_t)0x00010000) /*!<SMBUS timeout mode stopped when Core is halted */
+#define DBGMCU_CR_DBG_TIM8_STOP ((uint32_t)0x00020000) /*!<TIM8 counter stopped when core is halted */
+#define DBGMCU_CR_DBG_TIM5_STOP ((uint32_t)0x00040000) /*!<TIM5 counter stopped when core is halted */
+#define DBGMCU_CR_DBG_TIM6_STOP ((uint32_t)0x00080000) /*!<TIM6 counter stopped when core is halted */
+#define DBGMCU_CR_DBG_TIM7_STOP ((uint32_t)0x00100000) /*!<TIM7 counter stopped when core is halted */
+#define DBGMCU_CR_DBG_CAN2_STOP ((uint32_t)0x00200000) /*!<Debug CAN2 stopped when Core is halted */
+
+/******************************************************************************/
+/* */
+/* FLASH and Option Bytes Registers */
+/* */
+/******************************************************************************/
+
+/******************* Bit definition for FLASH_ACR register ******************/
+#define FLASH_ACR_LATENCY ((uint8_t)0x03) /*!<LATENCY[2:0] bits (Latency) */
+#define FLASH_ACR_LATENCY_0 ((uint8_t)0x00) /*!<Bit 0 */
+#define FLASH_ACR_LATENCY_1 ((uint8_t)0x01) /*!<Bit 0 */
+#define FLASH_ACR_LATENCY_2 ((uint8_t)0x02) /*!<Bit 1 */
+
+#define FLASH_ACR_HLFCYA ((uint8_t)0x08) /*!<Flash Half Cycle Access Enable */
+#define FLASH_ACR_PRFTBE ((uint8_t)0x10) /*!<Prefetch Buffer Enable */
+#define FLASH_ACR_PRFTBS ((uint8_t)0x20) /*!<Prefetch Buffer Status */
+
+/****************** Bit definition for FLASH_KEYR register ******************/
+#define FLASH_KEYR_FKEYR ((uint32_t)0xFFFFFFFF) /*!<FPEC Key */
+
+/***************** Bit definition for FLASH_OPTKEYR register ****************/
+#define FLASH_OPTKEYR_OPTKEYR ((uint32_t)0xFFFFFFFF) /*!<Option Byte Key */
+
+/****************** Bit definition for FLASH_SR register *******************/
+#define FLASH_SR_BSY ((uint8_t)0x01) /*!<Busy */
+#define FLASH_SR_PGERR ((uint8_t)0x04) /*!<Programming Error */
+#define FLASH_SR_WRPRTERR ((uint8_t)0x10) /*!<Write Protection Error */
+#define FLASH_SR_EOP ((uint8_t)0x20) /*!<End of operation */
+
+/******************* Bit definition for FLASH_CR register *******************/
+#define FLASH_CR_PG ((uint16_t)0x0001) /*!<Programming */
+#define FLASH_CR_PER ((uint16_t)0x0002) /*!<Page Erase */
+#define FLASH_CR_MER ((uint16_t)0x0004) /*!<Mass Erase */
+#define FLASH_CR_OPTPG ((uint16_t)0x0010) /*!<Option Byte Programming */
+#define FLASH_CR_OPTER ((uint16_t)0x0020) /*!<Option Byte Erase */
+#define FLASH_CR_STRT ((uint16_t)0x0040) /*!<Start */
+#define FLASH_CR_LOCK ((uint16_t)0x0080) /*!<Lock */
+#define FLASH_CR_OPTWRE ((uint16_t)0x0200) /*!<Option Bytes Write Enable */
+#define FLASH_CR_ERRIE ((uint16_t)0x0400) /*!<Error Interrupt Enable */
+#define FLASH_CR_EOPIE ((uint16_t)0x1000) /*!<End of operation interrupt enable */
+
+/******************* Bit definition for FLASH_AR register *******************/
+#define FLASH_AR_FAR ((uint32_t)0xFFFFFFFF) /*!<Flash Address */
+
+/****************** Bit definition for FLASH_OBR register *******************/
+#define FLASH_OBR_OPTERR ((uint16_t)0x0001) /*!<Option Byte Error */
+#define FLASH_OBR_RDPRT ((uint16_t)0x0002) /*!<Read protection */
+
+#define FLASH_OBR_USER ((uint16_t)0x03FC) /*!<User Option Bytes */
+#define FLASH_OBR_WDG_SW ((uint16_t)0x0004) /*!<WDG_SW */
+#define FLASH_OBR_nRST_STOP ((uint16_t)0x0008) /*!<nRST_STOP */
+#define FLASH_OBR_nRST_STDBY ((uint16_t)0x0010) /*!<nRST_STDBY */
+#define FLASH_OBR_Notused ((uint16_t)0x03E0) /*!<Not used */
+
+/****************** Bit definition for FLASH_WRPR register ******************/
+#define FLASH_WRPR_WRP ((uint32_t)0xFFFFFFFF) /*!<Write Protect */
+
+/*----------------------------------------------------------------------------*/
+
+/****************** Bit definition for FLASH_RDP register *******************/
+#define FLASH_RDP_RDP ((uint32_t)0x000000FF) /*!<Read protection option byte */
+#define FLASH_RDP_nRDP ((uint32_t)0x0000FF00) /*!<Read protection complemented option byte */
+
+/****************** Bit definition for FLASH_USER register ******************/
+#define FLASH_USER_USER ((uint32_t)0x00FF0000) /*!<User option byte */
+#define FLASH_USER_nUSER ((uint32_t)0xFF000000) /*!<User complemented option byte */
+
+/****************** Bit definition for FLASH_Data0 register *****************/
+#define FLASH_Data0_Data0 ((uint32_t)0x000000FF) /*!<User data storage option byte */
+#define FLASH_Data0_nData0 ((uint32_t)0x0000FF00) /*!<User data storage complemented option byte */
+
+/****************** Bit definition for FLASH_Data1 register *****************/
+#define FLASH_Data1_Data1 ((uint32_t)0x00FF0000) /*!<User data storage option byte */
+#define FLASH_Data1_nData1 ((uint32_t)0xFF000000) /*!<User data storage complemented option byte */
+
+/****************** Bit definition for FLASH_WRP0 register ******************/
+#define FLASH_WRP0_WRP0 ((uint32_t)0x000000FF) /*!<Flash memory write protection option bytes */
+#define FLASH_WRP0_nWRP0 ((uint32_t)0x0000FF00) /*!<Flash memory write protection complemented option bytes */
+
+/****************** Bit definition for FLASH_WRP1 register ******************/
+#define FLASH_WRP1_WRP1 ((uint32_t)0x00FF0000) /*!<Flash memory write protection option bytes */
+#define FLASH_WRP1_nWRP1 ((uint32_t)0xFF000000) /*!<Flash memory write protection complemented option bytes */
+
+/****************** Bit definition for FLASH_WRP2 register ******************/
+#define FLASH_WRP2_WRP2 ((uint32_t)0x000000FF) /*!<Flash memory write protection option bytes */
+#define FLASH_WRP2_nWRP2 ((uint32_t)0x0000FF00) /*!<Flash memory write protection complemented option bytes */
+
+/****************** Bit definition for FLASH_WRP3 register ******************/
+#define FLASH_WRP3_WRP3 ((uint32_t)0x00FF0000) /*!<Flash memory write protection option bytes */
+#define FLASH_WRP3_nWRP3 ((uint32_t)0xFF000000) /*!<Flash memory write protection complemented option bytes */
+
+#ifdef STM32F10X_CL
+/******************************************************************************/
+/* Ethernet MAC Registers bits definitions */
+/******************************************************************************/
+/* Bit definition for Ethernet MAC Control Register register */
+#define ETH_MACCR_WD ((uint32_t)0x00800000) /* Watchdog disable */
+#define ETH_MACCR_JD ((uint32_t)0x00400000) /* Jabber disable */
+#define ETH_MACCR_IFG ((uint32_t)0x000E0000) /* Inter-frame gap */
+ #define ETH_MACCR_IFG_96Bit ((uint32_t)0x00000000) /* Minimum IFG between frames during transmission is 96Bit */
+ #define ETH_MACCR_IFG_88Bit ((uint32_t)0x00020000) /* Minimum IFG between frames during transmission is 88Bit */
+ #define ETH_MACCR_IFG_80Bit ((uint32_t)0x00040000) /* Minimum IFG between frames during transmission is 80Bit */
+ #define ETH_MACCR_IFG_72Bit ((uint32_t)0x00060000) /* Minimum IFG between frames during transmission is 72Bit */
+ #define ETH_MACCR_IFG_64Bit ((uint32_t)0x00080000) /* Minimum IFG between frames during transmission is 64Bit */
+ #define ETH_MACCR_IFG_56Bit ((uint32_t)0x000A0000) /* Minimum IFG between frames during transmission is 56Bit */
+ #define ETH_MACCR_IFG_48Bit ((uint32_t)0x000C0000) /* Minimum IFG between frames during transmission is 48Bit */
+ #define ETH_MACCR_IFG_40Bit ((uint32_t)0x000E0000) /* Minimum IFG between frames during transmission is 40Bit */
+#define ETH_MACCR_CSD ((uint32_t)0x00010000) /* Carrier sense disable (during transmission) */
+#define ETH_MACCR_FES ((uint32_t)0x00004000) /* Fast ethernet speed */
+#define ETH_MACCR_ROD ((uint32_t)0x00002000) /* Receive own disable */
+#define ETH_MACCR_LM ((uint32_t)0x00001000) /* loopback mode */
+#define ETH_MACCR_DM ((uint32_t)0x00000800) /* Duplex mode */
+#define ETH_MACCR_IPCO ((uint32_t)0x00000400) /* IP Checksum offload */
+#define ETH_MACCR_RD ((uint32_t)0x00000200) /* Retry disable */
+#define ETH_MACCR_APCS ((uint32_t)0x00000080) /* Automatic Pad/CRC stripping */
+#define ETH_MACCR_BL ((uint32_t)0x00000060) /* Back-off limit: random integer number (r) of slot time delays before rescheduling
+ a transmission attempt during retries after a collision: 0 =< r <2^k */
+ #define ETH_MACCR_BL_10 ((uint32_t)0x00000000) /* k = min (n, 10) */
+ #define ETH_MACCR_BL_8 ((uint32_t)0x00000020) /* k = min (n, 8) */
+ #define ETH_MACCR_BL_4 ((uint32_t)0x00000040) /* k = min (n, 4) */
+ #define ETH_MACCR_BL_1 ((uint32_t)0x00000060) /* k = min (n, 1) */
+#define ETH_MACCR_DC ((uint32_t)0x00000010) /* Defferal check */
+#define ETH_MACCR_TE ((uint32_t)0x00000008) /* Transmitter enable */
+#define ETH_MACCR_RE ((uint32_t)0x00000004) /* Receiver enable */
+
+/* Bit definition for Ethernet MAC Frame Filter Register */
+#define ETH_MACFFR_RA ((uint32_t)0x80000000) /* Receive all */
+#define ETH_MACFFR_HPF ((uint32_t)0x00000400) /* Hash or perfect filter */
+#define ETH_MACFFR_SAF ((uint32_t)0x00000200) /* Source address filter enable */
+#define ETH_MACFFR_SAIF ((uint32_t)0x00000100) /* SA inverse filtering */
+#define ETH_MACFFR_PCF ((uint32_t)0x000000C0) /* Pass control frames: 3 cases */
+ #define ETH_MACFFR_PCF_BlockAll ((uint32_t)0x00000040) /* MAC filters all control frames from reaching the application */
+ #define ETH_MACFFR_PCF_ForwardAll ((uint32_t)0x00000080) /* MAC forwards all control frames to application even if they fail the Address Filter */
+ #define ETH_MACFFR_PCF_ForwardPassedAddrFilter ((uint32_t)0x000000C0) /* MAC forwards control frames that pass the Address Filter. */
+#define ETH_MACFFR_BFD ((uint32_t)0x00000020) /* Broadcast frame disable */
+#define ETH_MACFFR_PAM ((uint32_t)0x00000010) /* Pass all mutlicast */
+#define ETH_MACFFR_DAIF ((uint32_t)0x00000008) /* DA Inverse filtering */
+#define ETH_MACFFR_HM ((uint32_t)0x00000004) /* Hash multicast */
+#define ETH_MACFFR_HU ((uint32_t)0x00000002) /* Hash unicast */
+#define ETH_MACFFR_PM ((uint32_t)0x00000001) /* Promiscuous mode */
+
+/* Bit definition for Ethernet MAC Hash Table High Register */
+#define ETH_MACHTHR_HTH ((uint32_t)0xFFFFFFFF) /* Hash table high */
+
+/* Bit definition for Ethernet MAC Hash Table Low Register */
+#define ETH_MACHTLR_HTL ((uint32_t)0xFFFFFFFF) /* Hash table low */
+
+/* Bit definition for Ethernet MAC MII Address Register */
+#define ETH_MACMIIAR_PA ((uint32_t)0x0000F800) /* Physical layer address */
+#define ETH_MACMIIAR_MR ((uint32_t)0x000007C0) /* MII register in the selected PHY */
+#define ETH_MACMIIAR_CR ((uint32_t)0x0000001C) /* CR clock range: 6 cases */
+ #define ETH_MACMIIAR_CR_Div42 ((uint32_t)0x00000000) /* HCLK:60-72 MHz; MDC clock= HCLK/42 */
+ #define ETH_MACMIIAR_CR_Div16 ((uint32_t)0x00000008) /* HCLK:20-35 MHz; MDC clock= HCLK/16 */
+ #define ETH_MACMIIAR_CR_Div26 ((uint32_t)0x0000000C) /* HCLK:35-60 MHz; MDC clock= HCLK/26 */
+#define ETH_MACMIIAR_MW ((uint32_t)0x00000002) /* MII write */
+#define ETH_MACMIIAR_MB ((uint32_t)0x00000001) /* MII busy */
+
+/* Bit definition for Ethernet MAC MII Data Register */
+#define ETH_MACMIIDR_MD ((uint32_t)0x0000FFFF) /* MII data: read/write data from/to PHY */
+
+/* Bit definition for Ethernet MAC Flow Control Register */
+#define ETH_MACFCR_PT ((uint32_t)0xFFFF0000) /* Pause time */
+#define ETH_MACFCR_ZQPD ((uint32_t)0x00000080) /* Zero-quanta pause disable */
+#define ETH_MACFCR_PLT ((uint32_t)0x00000030) /* Pause low threshold: 4 cases */
+ #define ETH_MACFCR_PLT_Minus4 ((uint32_t)0x00000000) /* Pause time minus 4 slot times */
+ #define ETH_MACFCR_PLT_Minus28 ((uint32_t)0x00000010) /* Pause time minus 28 slot times */
+ #define ETH_MACFCR_PLT_Minus144 ((uint32_t)0x00000020) /* Pause time minus 144 slot times */
+ #define ETH_MACFCR_PLT_Minus256 ((uint32_t)0x00000030) /* Pause time minus 256 slot times */
+#define ETH_MACFCR_UPFD ((uint32_t)0x00000008) /* Unicast pause frame detect */
+#define ETH_MACFCR_RFCE ((uint32_t)0x00000004) /* Receive flow control enable */
+#define ETH_MACFCR_TFCE ((uint32_t)0x00000002) /* Transmit flow control enable */
+#define ETH_MACFCR_FCBBPA ((uint32_t)0x00000001) /* Flow control busy/backpressure activate */
+
+/* Bit definition for Ethernet MAC VLAN Tag Register */
+#define ETH_MACVLANTR_VLANTC ((uint32_t)0x00010000) /* 12-bit VLAN tag comparison */
+#define ETH_MACVLANTR_VLANTI ((uint32_t)0x0000FFFF) /* VLAN tag identifier (for receive frames) */
+
+/* Bit definition for Ethernet MAC Remote Wake-UpFrame Filter Register */
+#define ETH_MACRWUFFR_D ((uint32_t)0xFFFFFFFF) /* Wake-up frame filter register data */
+/* Eight sequential Writes to this address (offset 0x28) will write all Wake-UpFrame Filter Registers.
+ Eight sequential Reads from this address (offset 0x28) will read all Wake-UpFrame Filter Registers. */
+/* Wake-UpFrame Filter Reg0 : Filter 0 Byte Mask
+ Wake-UpFrame Filter Reg1 : Filter 1 Byte Mask
+ Wake-UpFrame Filter Reg2 : Filter 2 Byte Mask
+ Wake-UpFrame Filter Reg3 : Filter 3 Byte Mask
+ Wake-UpFrame Filter Reg4 : RSVD - Filter3 Command - RSVD - Filter2 Command -
+ RSVD - Filter1 Command - RSVD - Filter0 Command
+ Wake-UpFrame Filter Re5 : Filter3 Offset - Filter2 Offset - Filter1 Offset - Filter0 Offset
+ Wake-UpFrame Filter Re6 : Filter1 CRC16 - Filter0 CRC16
+ Wake-UpFrame Filter Re7 : Filter3 CRC16 - Filter2 CRC16 */
+
+/* Bit definition for Ethernet MAC PMT Control and Status Register */
+#define ETH_MACPMTCSR_WFFRPR ((uint32_t)0x80000000) /* Wake-Up Frame Filter Register Pointer Reset */
+#define ETH_MACPMTCSR_GU ((uint32_t)0x00000200) /* Global Unicast */
+#define ETH_MACPMTCSR_WFR ((uint32_t)0x00000040) /* Wake-Up Frame Received */
+#define ETH_MACPMTCSR_MPR ((uint32_t)0x00000020) /* Magic Packet Received */
+#define ETH_MACPMTCSR_WFE ((uint32_t)0x00000004) /* Wake-Up Frame Enable */
+#define ETH_MACPMTCSR_MPE ((uint32_t)0x00000002) /* Magic Packet Enable */
+#define ETH_MACPMTCSR_PD ((uint32_t)0x00000001) /* Power Down */
+
+/* Bit definition for Ethernet MAC Status Register */
+#define ETH_MACSR_TSTS ((uint32_t)0x00000200) /* Time stamp trigger status */
+#define ETH_MACSR_MMCTS ((uint32_t)0x00000040) /* MMC transmit status */
+#define ETH_MACSR_MMMCRS ((uint32_t)0x00000020) /* MMC receive status */
+#define ETH_MACSR_MMCS ((uint32_t)0x00000010) /* MMC status */
+#define ETH_MACSR_PMTS ((uint32_t)0x00000008) /* PMT status */
+
+/* Bit definition for Ethernet MAC Interrupt Mask Register */
+#define ETH_MACIMR_TSTIM ((uint32_t)0x00000200) /* Time stamp trigger interrupt mask */
+#define ETH_MACIMR_PMTIM ((uint32_t)0x00000008) /* PMT interrupt mask */
+
+/* Bit definition for Ethernet MAC Address0 High Register */
+#define ETH_MACA0HR_MACA0H ((uint32_t)0x0000FFFF) /* MAC address0 high */
+
+/* Bit definition for Ethernet MAC Address0 Low Register */
+#define ETH_MACA0LR_MACA0L ((uint32_t)0xFFFFFFFF) /* MAC address0 low */
+
+/* Bit definition for Ethernet MAC Address1 High Register */
+#define ETH_MACA1HR_AE ((uint32_t)0x80000000) /* Address enable */
+#define ETH_MACA1HR_SA ((uint32_t)0x40000000) /* Source address */
+#define ETH_MACA1HR_MBC ((uint32_t)0x3F000000) /* Mask byte control: bits to mask for comparison of the MAC Address bytes */
+ #define ETH_MACA1HR_MBC_HBits15_8 ((uint32_t)0x20000000) /* Mask MAC Address high reg bits [15:8] */
+ #define ETH_MACA1HR_MBC_HBits7_0 ((uint32_t)0x10000000) /* Mask MAC Address high reg bits [7:0] */
+ #define ETH_MACA1HR_MBC_LBits31_24 ((uint32_t)0x08000000) /* Mask MAC Address low reg bits [31:24] */
+ #define ETH_MACA1HR_MBC_LBits23_16 ((uint32_t)0x04000000) /* Mask MAC Address low reg bits [23:16] */
+ #define ETH_MACA1HR_MBC_LBits15_8 ((uint32_t)0x02000000) /* Mask MAC Address low reg bits [15:8] */
+ #define ETH_MACA1HR_MBC_LBits7_0 ((uint32_t)0x01000000) /* Mask MAC Address low reg bits [7:0] */
+#define ETH_MACA1HR_MACA1H ((uint32_t)0x0000FFFF) /* MAC address1 high */
+
+/* Bit definition for Ethernet MAC Address1 Low Register */
+#define ETH_MACA1LR_MACA1L ((uint32_t)0xFFFFFFFF) /* MAC address1 low */
+
+/* Bit definition for Ethernet MAC Address2 High Register */
+#define ETH_MACA2HR_AE ((uint32_t)0x80000000) /* Address enable */
+#define ETH_MACA2HR_SA ((uint32_t)0x40000000) /* Source address */
+#define ETH_MACA2HR_MBC ((uint32_t)0x3F000000) /* Mask byte control */
+ #define ETH_MACA2HR_MBC_HBits15_8 ((uint32_t)0x20000000) /* Mask MAC Address high reg bits [15:8] */
+ #define ETH_MACA2HR_MBC_HBits7_0 ((uint32_t)0x10000000) /* Mask MAC Address high reg bits [7:0] */
+ #define ETH_MACA2HR_MBC_LBits31_24 ((uint32_t)0x08000000) /* Mask MAC Address low reg bits [31:24] */
+ #define ETH_MACA2HR_MBC_LBits23_16 ((uint32_t)0x04000000) /* Mask MAC Address low reg bits [23:16] */
+ #define ETH_MACA2HR_MBC_LBits15_8 ((uint32_t)0x02000000) /* Mask MAC Address low reg bits [15:8] */
+ #define ETH_MACA2HR_MBC_LBits7_0 ((uint32_t)0x01000000) /* Mask MAC Address low reg bits [70] */
+#define ETH_MACA2HR_MACA2H ((uint32_t)0x0000FFFF) /* MAC address1 high */
+
+/* Bit definition for Ethernet MAC Address2 Low Register */
+#define ETH_MACA2LR_MACA2L ((uint32_t)0xFFFFFFFF) /* MAC address2 low */
+
+/* Bit definition for Ethernet MAC Address3 High Register */
+#define ETH_MACA3HR_AE ((uint32_t)0x80000000) /* Address enable */
+#define ETH_MACA3HR_SA ((uint32_t)0x40000000) /* Source address */
+#define ETH_MACA3HR_MBC ((uint32_t)0x3F000000) /* Mask byte control */
+ #define ETH_MACA3HR_MBC_HBits15_8 ((uint32_t)0x20000000) /* Mask MAC Address high reg bits [15:8] */
+ #define ETH_MACA3HR_MBC_HBits7_0 ((uint32_t)0x10000000) /* Mask MAC Address high reg bits [7:0] */
+ #define ETH_MACA3HR_MBC_LBits31_24 ((uint32_t)0x08000000) /* Mask MAC Address low reg bits [31:24] */
+ #define ETH_MACA3HR_MBC_LBits23_16 ((uint32_t)0x04000000) /* Mask MAC Address low reg bits [23:16] */
+ #define ETH_MACA3HR_MBC_LBits15_8 ((uint32_t)0x02000000) /* Mask MAC Address low reg bits [15:8] */
+ #define ETH_MACA3HR_MBC_LBits7_0 ((uint32_t)0x01000000) /* Mask MAC Address low reg bits [70] */
+#define ETH_MACA3HR_MACA3H ((uint32_t)0x0000FFFF) /* MAC address3 high */
+
+/* Bit definition for Ethernet MAC Address3 Low Register */
+#define ETH_MACA3LR_MACA3L ((uint32_t)0xFFFFFFFF) /* MAC address3 low */
+
+/******************************************************************************/
+/* Ethernet MMC Registers bits definition */
+/******************************************************************************/
+
+/* Bit definition for Ethernet MMC Contol Register */
+#define ETH_MMCCR_MCF ((uint32_t)0x00000008) /* MMC Counter Freeze */
+#define ETH_MMCCR_ROR ((uint32_t)0x00000004) /* Reset on Read */
+#define ETH_MMCCR_CSR ((uint32_t)0x00000002) /* Counter Stop Rollover */
+#define ETH_MMCCR_CR ((uint32_t)0x00000001) /* Counters Reset */
+
+/* Bit definition for Ethernet MMC Receive Interrupt Register */
+#define ETH_MMCRIR_RGUFS ((uint32_t)0x00020000) /* Set when Rx good unicast frames counter reaches half the maximum value */
+#define ETH_MMCRIR_RFAES ((uint32_t)0x00000040) /* Set when Rx alignment error counter reaches half the maximum value */
+#define ETH_MMCRIR_RFCES ((uint32_t)0x00000020) /* Set when Rx crc error counter reaches half the maximum value */
+
+/* Bit definition for Ethernet MMC Transmit Interrupt Register */
+#define ETH_MMCTIR_TGFS ((uint32_t)0x00200000) /* Set when Tx good frame count counter reaches half the maximum value */
+#define ETH_MMCTIR_TGFMSCS ((uint32_t)0x00008000) /* Set when Tx good multi col counter reaches half the maximum value */
+#define ETH_MMCTIR_TGFSCS ((uint32_t)0x00004000) /* Set when Tx good single col counter reaches half the maximum value */
+
+/* Bit definition for Ethernet MMC Receive Interrupt Mask Register */
+#define ETH_MMCRIMR_RGUFM ((uint32_t)0x00020000) /* Mask the interrupt when Rx good unicast frames counter reaches half the maximum value */
+#define ETH_MMCRIMR_RFAEM ((uint32_t)0x00000040) /* Mask the interrupt when when Rx alignment error counter reaches half the maximum value */
+#define ETH_MMCRIMR_RFCEM ((uint32_t)0x00000020) /* Mask the interrupt when Rx crc error counter reaches half the maximum value */
+
+/* Bit definition for Ethernet MMC Transmit Interrupt Mask Register */
+#define ETH_MMCTIMR_TGFM ((uint32_t)0x00200000) /* Mask the interrupt when Tx good frame count counter reaches half the maximum value */
+#define ETH_MMCTIMR_TGFMSCM ((uint32_t)0x00008000) /* Mask the interrupt when Tx good multi col counter reaches half the maximum value */
+#define ETH_MMCTIMR_TGFSCM ((uint32_t)0x00004000) /* Mask the interrupt when Tx good single col counter reaches half the maximum value */
+
+/* Bit definition for Ethernet MMC Transmitted Good Frames after Single Collision Counter Register */
+#define ETH_MMCTGFSCCR_TGFSCC ((uint32_t)0xFFFFFFFF) /* Number of successfully transmitted frames after a single collision in Half-duplex mode. */
+
+/* Bit definition for Ethernet MMC Transmitted Good Frames after More than a Single Collision Counter Register */
+#define ETH_MMCTGFMSCCR_TGFMSCC ((uint32_t)0xFFFFFFFF) /* Number of successfully transmitted frames after more than a single collision in Half-duplex mode. */
+
+/* Bit definition for Ethernet MMC Transmitted Good Frames Counter Register */
+#define ETH_MMCTGFCR_TGFC ((uint32_t)0xFFFFFFFF) /* Number of good frames transmitted. */
+
+/* Bit definition for Ethernet MMC Received Frames with CRC Error Counter Register */
+#define ETH_MMCRFCECR_RFCEC ((uint32_t)0xFFFFFFFF) /* Number of frames received with CRC error. */
+
+/* Bit definition for Ethernet MMC Received Frames with Alignement Error Counter Register */
+#define ETH_MMCRFAECR_RFAEC ((uint32_t)0xFFFFFFFF) /* Number of frames received with alignment (dribble) error */
+
+/* Bit definition for Ethernet MMC Received Good Unicast Frames Counter Register */
+#define ETH_MMCRGUFCR_RGUFC ((uint32_t)0xFFFFFFFF) /* Number of good unicast frames received. */
+
+/******************************************************************************/
+/* Ethernet PTP Registers bits definition */
+/******************************************************************************/
+
+/* Bit definition for Ethernet PTP Time Stamp Contol Register */
+#define ETH_PTPTSCR_TSARU ((uint32_t)0x00000020) /* Addend register update */
+#define ETH_PTPTSCR_TSITE ((uint32_t)0x00000010) /* Time stamp interrupt trigger enable */
+#define ETH_PTPTSCR_TSSTU ((uint32_t)0x00000008) /* Time stamp update */
+#define ETH_PTPTSCR_TSSTI ((uint32_t)0x00000004) /* Time stamp initialize */
+#define ETH_PTPTSCR_TSFCU ((uint32_t)0x00000002) /* Time stamp fine or coarse update */
+#define ETH_PTPTSCR_TSE ((uint32_t)0x00000001) /* Time stamp enable */
+
+/* Bit definition for Ethernet PTP Sub-Second Increment Register */
+#define ETH_PTPSSIR_STSSI ((uint32_t)0x000000FF) /* System time Sub-second increment value */
+
+/* Bit definition for Ethernet PTP Time Stamp High Register */
+#define ETH_PTPTSHR_STS ((uint32_t)0xFFFFFFFF) /* System Time second */
+
+/* Bit definition for Ethernet PTP Time Stamp Low Register */
+#define ETH_PTPTSLR_STPNS ((uint32_t)0x80000000) /* System Time Positive or negative time */
+#define ETH_PTPTSLR_STSS ((uint32_t)0x7FFFFFFF) /* System Time sub-seconds */
+
+/* Bit definition for Ethernet PTP Time Stamp High Update Register */
+#define ETH_PTPTSHUR_TSUS ((uint32_t)0xFFFFFFFF) /* Time stamp update seconds */
+
+/* Bit definition for Ethernet PTP Time Stamp Low Update Register */
+#define ETH_PTPTSLUR_TSUPNS ((uint32_t)0x80000000) /* Time stamp update Positive or negative time */
+#define ETH_PTPTSLUR_TSUSS ((uint32_t)0x7FFFFFFF) /* Time stamp update sub-seconds */
+
+/* Bit definition for Ethernet PTP Time Stamp Addend Register */
+#define ETH_PTPTSAR_TSA ((uint32_t)0xFFFFFFFF) /* Time stamp addend */
+
+/* Bit definition for Ethernet PTP Target Time High Register */
+#define ETH_PTPTTHR_TTSH ((uint32_t)0xFFFFFFFF) /* Target time stamp high */
+
+/* Bit definition for Ethernet PTP Target Time Low Register */
+#define ETH_PTPTTLR_TTSL ((uint32_t)0xFFFFFFFF) /* Target time stamp low */
+
+/******************************************************************************/
+/* Ethernet DMA Registers bits definition */
+/******************************************************************************/
+
+/* Bit definition for Ethernet DMA Bus Mode Register */
+#define ETH_DMABMR_AAB ((uint32_t)0x02000000) /* Address-Aligned beats */
+#define ETH_DMABMR_FPM ((uint32_t)0x01000000) /* 4xPBL mode */
+#define ETH_DMABMR_USP ((uint32_t)0x00800000) /* Use separate PBL */
+#define ETH_DMABMR_RDP ((uint32_t)0x007E0000) /* RxDMA PBL */
+ #define ETH_DMABMR_RDP_1Beat ((uint32_t)0x00020000) /* maximum number of beats to be transferred in one RxDMA transaction is 1 */
+ #define ETH_DMABMR_RDP_2Beat ((uint32_t)0x00040000) /* maximum number of beats to be transferred in one RxDMA transaction is 2 */
+ #define ETH_DMABMR_RDP_4Beat ((uint32_t)0x00080000) /* maximum number of beats to be transferred in one RxDMA transaction is 4 */
+ #define ETH_DMABMR_RDP_8Beat ((uint32_t)0x00100000) /* maximum number of beats to be transferred in one RxDMA transaction is 8 */
+ #define ETH_DMABMR_RDP_16Beat ((uint32_t)0x00200000) /* maximum number of beats to be transferred in one RxDMA transaction is 16 */
+ #define ETH_DMABMR_RDP_32Beat ((uint32_t)0x00400000) /* maximum number of beats to be transferred in one RxDMA transaction is 32 */
+ #define ETH_DMABMR_RDP_4xPBL_4Beat ((uint32_t)0x01020000) /* maximum number of beats to be transferred in one RxDMA transaction is 4 */
+ #define ETH_DMABMR_RDP_4xPBL_8Beat ((uint32_t)0x01040000) /* maximum number of beats to be transferred in one RxDMA transaction is 8 */
+ #define ETH_DMABMR_RDP_4xPBL_16Beat ((uint32_t)0x01080000) /* maximum number of beats to be transferred in one RxDMA transaction is 16 */
+ #define ETH_DMABMR_RDP_4xPBL_32Beat ((uint32_t)0x01100000) /* maximum number of beats to be transferred in one RxDMA transaction is 32 */
+ #define ETH_DMABMR_RDP_4xPBL_64Beat ((uint32_t)0x01200000) /* maximum number of beats to be transferred in one RxDMA transaction is 64 */
+ #define ETH_DMABMR_RDP_4xPBL_128Beat ((uint32_t)0x01400000) /* maximum number of beats to be transferred in one RxDMA transaction is 128 */
+#define ETH_DMABMR_FB ((uint32_t)0x00010000) /* Fixed Burst */
+#define ETH_DMABMR_RTPR ((uint32_t)0x0000C000) /* Rx Tx priority ratio */
+ #define ETH_DMABMR_RTPR_1_1 ((uint32_t)0x00000000) /* Rx Tx priority ratio */
+ #define ETH_DMABMR_RTPR_2_1 ((uint32_t)0x00004000) /* Rx Tx priority ratio */
+ #define ETH_DMABMR_RTPR_3_1 ((uint32_t)0x00008000) /* Rx Tx priority ratio */
+ #define ETH_DMABMR_RTPR_4_1 ((uint32_t)0x0000C000) /* Rx Tx priority ratio */
+#define ETH_DMABMR_PBL ((uint32_t)0x00003F00) /* Programmable burst length */
+ #define ETH_DMABMR_PBL_1Beat ((uint32_t)0x00000100) /* maximum number of beats to be transferred in one TxDMA (or both) transaction is 1 */
+ #define ETH_DMABMR_PBL_2Beat ((uint32_t)0x00000200) /* maximum number of beats to be transferred in one TxDMA (or both) transaction is 2 */
+ #define ETH_DMABMR_PBL_4Beat ((uint32_t)0x00000400) /* maximum number of beats to be transferred in one TxDMA (or both) transaction is 4 */
+ #define ETH_DMABMR_PBL_8Beat ((uint32_t)0x00000800) /* maximum number of beats to be transferred in one TxDMA (or both) transaction is 8 */
+ #define ETH_DMABMR_PBL_16Beat ((uint32_t)0x00001000) /* maximum number of beats to be transferred in one TxDMA (or both) transaction is 16 */
+ #define ETH_DMABMR_PBL_32Beat ((uint32_t)0x00002000) /* maximum number of beats to be transferred in one TxDMA (or both) transaction is 32 */
+ #define ETH_DMABMR_PBL_4xPBL_4Beat ((uint32_t)0x01000100) /* maximum number of beats to be transferred in one TxDMA (or both) transaction is 4 */
+ #define ETH_DMABMR_PBL_4xPBL_8Beat ((uint32_t)0x01000200) /* maximum number of beats to be transferred in one TxDMA (or both) transaction is 8 */
+ #define ETH_DMABMR_PBL_4xPBL_16Beat ((uint32_t)0x01000400) /* maximum number of beats to be transferred in one TxDMA (or both) transaction is 16 */
+ #define ETH_DMABMR_PBL_4xPBL_32Beat ((uint32_t)0x01000800) /* maximum number of beats to be transferred in one TxDMA (or both) transaction is 32 */
+ #define ETH_DMABMR_PBL_4xPBL_64Beat ((uint32_t)0x01001000) /* maximum number of beats to be transferred in one TxDMA (or both) transaction is 64 */
+ #define ETH_DMABMR_PBL_4xPBL_128Beat ((uint32_t)0x01002000) /* maximum number of beats to be transferred in one TxDMA (or both) transaction is 128 */
+#define ETH_DMABMR_DSL ((uint32_t)0x0000007C) /* Descriptor Skip Length */
+#define ETH_DMABMR_DA ((uint32_t)0x00000002) /* DMA arbitration scheme */
+#define ETH_DMABMR_SR ((uint32_t)0x00000001) /* Software reset */
+
+/* Bit definition for Ethernet DMA Transmit Poll Demand Register */
+#define ETH_DMATPDR_TPD ((uint32_t)0xFFFFFFFF) /* Transmit poll demand */
+
+/* Bit definition for Ethernet DMA Receive Poll Demand Register */
+#define ETH_DMARPDR_RPD ((uint32_t)0xFFFFFFFF) /* Receive poll demand */
+
+/* Bit definition for Ethernet DMA Receive Descriptor List Address Register */
+#define ETH_DMARDLAR_SRL ((uint32_t)0xFFFFFFFF) /* Start of receive list */
+
+/* Bit definition for Ethernet DMA Transmit Descriptor List Address Register */
+#define ETH_DMATDLAR_STL ((uint32_t)0xFFFFFFFF) /* Start of transmit list */
+
+/* Bit definition for Ethernet DMA Status Register */
+#define ETH_DMASR_TSTS ((uint32_t)0x20000000) /* Time-stamp trigger status */
+#define ETH_DMASR_PMTS ((uint32_t)0x10000000) /* PMT status */
+#define ETH_DMASR_MMCS ((uint32_t)0x08000000) /* MMC status */
+#define ETH_DMASR_EBS ((uint32_t)0x03800000) /* Error bits status */
+ /* combination with EBS[2:0] for GetFlagStatus function */
+ #define ETH_DMASR_EBS_DescAccess ((uint32_t)0x02000000) /* Error bits 0-data buffer, 1-desc. access */
+ #define ETH_DMASR_EBS_ReadTransf ((uint32_t)0x01000000) /* Error bits 0-write trnsf, 1-read transfr */
+ #define ETH_DMASR_EBS_DataTransfTx ((uint32_t)0x00800000) /* Error bits 0-Rx DMA, 1-Tx DMA */
+#define ETH_DMASR_TPS ((uint32_t)0x00700000) /* Transmit process state */
+ #define ETH_DMASR_TPS_Stopped ((uint32_t)0x00000000) /* Stopped - Reset or Stop Tx Command issued */
+ #define ETH_DMASR_TPS_Fetching ((uint32_t)0x00100000) /* Running - fetching the Tx descriptor */
+ #define ETH_DMASR_TPS_Waiting ((uint32_t)0x00200000) /* Running - waiting for status */
+ #define ETH_DMASR_TPS_Reading ((uint32_t)0x00300000) /* Running - reading the data from host memory */
+ #define ETH_DMASR_TPS_Suspended ((uint32_t)0x00600000) /* Suspended - Tx Descriptor unavailabe */
+ #define ETH_DMASR_TPS_Closing ((uint32_t)0x00700000) /* Running - closing Rx descriptor */
+#define ETH_DMASR_RPS ((uint32_t)0x000E0000) /* Receive process state */
+ #define ETH_DMASR_RPS_Stopped ((uint32_t)0x00000000) /* Stopped - Reset or Stop Rx Command issued */
+ #define ETH_DMASR_RPS_Fetching ((uint32_t)0x00020000) /* Running - fetching the Rx descriptor */
+ #define ETH_DMASR_RPS_Waiting ((uint32_t)0x00060000) /* Running - waiting for packet */
+ #define ETH_DMASR_RPS_Suspended ((uint32_t)0x00080000) /* Suspended - Rx Descriptor unavailable */
+ #define ETH_DMASR_RPS_Closing ((uint32_t)0x000A0000) /* Running - closing descriptor */
+ #define ETH_DMASR_RPS_Queuing ((uint32_t)0x000E0000) /* Running - queuing the recieve frame into host memory */
+#define ETH_DMASR_NIS ((uint32_t)0x00010000) /* Normal interrupt summary */
+#define ETH_DMASR_AIS ((uint32_t)0x00008000) /* Abnormal interrupt summary */
+#define ETH_DMASR_ERS ((uint32_t)0x00004000) /* Early receive status */
+#define ETH_DMASR_FBES ((uint32_t)0x00002000) /* Fatal bus error status */
+#define ETH_DMASR_ETS ((uint32_t)0x00000400) /* Early transmit status */
+#define ETH_DMASR_RWTS ((uint32_t)0x00000200) /* Receive watchdog timeout status */
+#define ETH_DMASR_RPSS ((uint32_t)0x00000100) /* Receive process stopped status */
+#define ETH_DMASR_RBUS ((uint32_t)0x00000080) /* Receive buffer unavailable status */
+#define ETH_DMASR_RS ((uint32_t)0x00000040) /* Receive status */
+#define ETH_DMASR_TUS ((uint32_t)0x00000020) /* Transmit underflow status */
+#define ETH_DMASR_ROS ((uint32_t)0x00000010) /* Receive overflow status */
+#define ETH_DMASR_TJTS ((uint32_t)0x00000008) /* Transmit jabber timeout status */
+#define ETH_DMASR_TBUS ((uint32_t)0x00000004) /* Transmit buffer unavailable status */
+#define ETH_DMASR_TPSS ((uint32_t)0x00000002) /* Transmit process stopped status */
+#define ETH_DMASR_TS ((uint32_t)0x00000001) /* Transmit status */
+
+/* Bit definition for Ethernet DMA Operation Mode Register */
+#define ETH_DMAOMR_DTCEFD ((uint32_t)0x04000000) /* Disable Dropping of TCP/IP checksum error frames */
+#define ETH_DMAOMR_RSF ((uint32_t)0x02000000) /* Receive store and forward */
+#define ETH_DMAOMR_DFRF ((uint32_t)0x01000000) /* Disable flushing of received frames */
+#define ETH_DMAOMR_TSF ((uint32_t)0x00200000) /* Transmit store and forward */
+#define ETH_DMAOMR_FTF ((uint32_t)0x00100000) /* Flush transmit FIFO */
+#define ETH_DMAOMR_TTC ((uint32_t)0x0001C000) /* Transmit threshold control */
+ #define ETH_DMAOMR_TTC_64Bytes ((uint32_t)0x00000000) /* threshold level of the MTL Transmit FIFO is 64 Bytes */
+ #define ETH_DMAOMR_TTC_128Bytes ((uint32_t)0x00004000) /* threshold level of the MTL Transmit FIFO is 128 Bytes */
+ #define ETH_DMAOMR_TTC_192Bytes ((uint32_t)0x00008000) /* threshold level of the MTL Transmit FIFO is 192 Bytes */
+ #define ETH_DMAOMR_TTC_256Bytes ((uint32_t)0x0000C000) /* threshold level of the MTL Transmit FIFO is 256 Bytes */
+ #define ETH_DMAOMR_TTC_40Bytes ((uint32_t)0x00010000) /* threshold level of the MTL Transmit FIFO is 40 Bytes */
+ #define ETH_DMAOMR_TTC_32Bytes ((uint32_t)0x00014000) /* threshold level of the MTL Transmit FIFO is 32 Bytes */
+ #define ETH_DMAOMR_TTC_24Bytes ((uint32_t)0x00018000) /* threshold level of the MTL Transmit FIFO is 24 Bytes */
+ #define ETH_DMAOMR_TTC_16Bytes ((uint32_t)0x0001C000) /* threshold level of the MTL Transmit FIFO is 16 Bytes */
+#define ETH_DMAOMR_ST ((uint32_t)0x00002000) /* Start/stop transmission command */
+#define ETH_DMAOMR_FEF ((uint32_t)0x00000080) /* Forward error frames */
+#define ETH_DMAOMR_FUGF ((uint32_t)0x00000040) /* Forward undersized good frames */
+#define ETH_DMAOMR_RTC ((uint32_t)0x00000018) /* receive threshold control */
+ #define ETH_DMAOMR_RTC_64Bytes ((uint32_t)0x00000000) /* threshold level of the MTL Receive FIFO is 64 Bytes */
+ #define ETH_DMAOMR_RTC_32Bytes ((uint32_t)0x00000008) /* threshold level of the MTL Receive FIFO is 32 Bytes */
+ #define ETH_DMAOMR_RTC_96Bytes ((uint32_t)0x00000010) /* threshold level of the MTL Receive FIFO is 96 Bytes */
+ #define ETH_DMAOMR_RTC_128Bytes ((uint32_t)0x00000018) /* threshold level of the MTL Receive FIFO is 128 Bytes */
+#define ETH_DMAOMR_OSF ((uint32_t)0x00000004) /* operate on second frame */
+#define ETH_DMAOMR_SR ((uint32_t)0x00000002) /* Start/stop receive */
+
+/* Bit definition for Ethernet DMA Interrupt Enable Register */
+#define ETH_DMAIER_NISE ((uint32_t)0x00010000) /* Normal interrupt summary enable */
+#define ETH_DMAIER_AISE ((uint32_t)0x00008000) /* Abnormal interrupt summary enable */
+#define ETH_DMAIER_ERIE ((uint32_t)0x00004000) /* Early receive interrupt enable */
+#define ETH_DMAIER_FBEIE ((uint32_t)0x00002000) /* Fatal bus error interrupt enable */
+#define ETH_DMAIER_ETIE ((uint32_t)0x00000400) /* Early transmit interrupt enable */
+#define ETH_DMAIER_RWTIE ((uint32_t)0x00000200) /* Receive watchdog timeout interrupt enable */
+#define ETH_DMAIER_RPSIE ((uint32_t)0x00000100) /* Receive process stopped interrupt enable */
+#define ETH_DMAIER_RBUIE ((uint32_t)0x00000080) /* Receive buffer unavailable interrupt enable */
+#define ETH_DMAIER_RIE ((uint32_t)0x00000040) /* Receive interrupt enable */
+#define ETH_DMAIER_TUIE ((uint32_t)0x00000020) /* Transmit Underflow interrupt enable */
+#define ETH_DMAIER_ROIE ((uint32_t)0x00000010) /* Receive Overflow interrupt enable */
+#define ETH_DMAIER_TJTIE ((uint32_t)0x00000008) /* Transmit jabber timeout interrupt enable */
+#define ETH_DMAIER_TBUIE ((uint32_t)0x00000004) /* Transmit buffer unavailable interrupt enable */
+#define ETH_DMAIER_TPSIE ((uint32_t)0x00000002) /* Transmit process stopped interrupt enable */
+#define ETH_DMAIER_TIE ((uint32_t)0x00000001) /* Transmit interrupt enable */
+
+/* Bit definition for Ethernet DMA Missed Frame and Buffer Overflow Counter Register */
+#define ETH_DMAMFBOCR_OFOC ((uint32_t)0x10000000) /* Overflow bit for FIFO overflow counter */
+#define ETH_DMAMFBOCR_MFA ((uint32_t)0x0FFE0000) /* Number of frames missed by the application */
+#define ETH_DMAMFBOCR_OMFC ((uint32_t)0x00010000) /* Overflow bit for missed frame counter */
+#define ETH_DMAMFBOCR_MFC ((uint32_t)0x0000FFFF) /* Number of frames missed by the controller */
+
+/* Bit definition for Ethernet DMA Current Host Transmit Descriptor Register */
+#define ETH_DMACHTDR_HTDAP ((uint32_t)0xFFFFFFFF) /* Host transmit descriptor address pointer */
+
+/* Bit definition for Ethernet DMA Current Host Receive Descriptor Register */
+#define ETH_DMACHRDR_HRDAP ((uint32_t)0xFFFFFFFF) /* Host receive descriptor address pointer */
+
+/* Bit definition for Ethernet DMA Current Host Transmit Buffer Address Register */
+#define ETH_DMACHTBAR_HTBAP ((uint32_t)0xFFFFFFFF) /* Host transmit buffer address pointer */
+
+/* Bit definition for Ethernet DMA Current Host Receive Buffer Address Register */
+#define ETH_DMACHRBAR_HRBAP ((uint32_t)0xFFFFFFFF) /* Host receive buffer address pointer */
+#endif /* STM32F10X_CL */
+
+/**
+ * @}
+ */
+
+ /**
+ * @}
+ */
+
+#ifdef USE_STDPERIPH_DRIVER
+ #include "stm32f10x_conf.h"
+#endif
+
+/** @addtogroup Exported_macro
+ * @{
+ */
+
+#define SET_BIT(REG, BIT) ((REG) |= (BIT))
+
+#define CLEAR_BIT(REG, BIT) ((REG) &= ~(BIT))
+
+#define READ_BIT(REG, BIT) ((REG) & (BIT))
+
+#define CLEAR_REG(REG) ((REG) = (0x0))
+
+#define WRITE_REG(REG, VAL) ((REG) = (VAL))
+
+#define READ_REG(REG) ((REG))
+
+#define MODIFY_REG(REG, CLEARMASK, SETMASK) WRITE_REG((REG), (((READ_REG(REG)) & (~(CLEARMASK))) | (SETMASK)))
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32F10x_H */
+
+/**
+ * @}
+ */
+
+ /**
+ * @}
+ */
+
+/******************* (C) COPYRIGHT 2009 STMicroelectronics *****END OF FILE****/
diff --git a/os/ports/GCC/ARMCM3/STM32F103/vectors.s b/os/ports/GCC/ARMCM3/STM32F103/vectors.s
new file mode 100644
index 000000000..222255c15
--- /dev/null
+++ b/os/ports/GCC/ARMCM3/STM32F103/vectors.s
@@ -0,0 +1,256 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT 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 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT 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, see <http://www.gnu.org/licenses/>.
+*/
+
+.syntax unified
+.thumb
+
+.section vectors
+_vectors:
+ .word __ram_end__
+ .word ResetHandler
+ .word NMIVector
+ .word HardFaultVector
+ .word MemManageVector
+ .word BusFaultVector
+ .word UsageFaultVector
+ .word Vector1C
+ .word Vector20
+ .word Vector24
+ .word Vector28
+ .word SVCallVector
+ .word DebugMonitorVector
+ .word Vector34
+ .word PendSVVector
+ .word SysTickVector
+ .word Vector40
+ .word Vector44
+ .word Vector48
+ .word Vector4C
+ .word Vector50
+ .word Vector54
+ .word Vector58
+ .word Vector5C
+ .word Vector60
+ .word Vector64
+ .word Vector68
+ .word Vector6C
+ .word Vector70
+ .word Vector74
+ .word Vector78
+ .word Vector7C
+ .word Vector80
+ .word Vector84
+ .word Vector88
+ .word Vector8C
+ .word Vector90
+ .word Vector94
+ .word Vector98
+ .word Vector9C
+ .word VectorA0
+ .word VectorA4
+ .word VectorA8
+ .word VectorAC
+ .word VectorB0
+ .word VectorB4
+ .word VectorB8
+ .word VectorBC
+ .word VectorC0
+ .word VectorC4
+ .word VectorC8
+ .word VectorCC
+ .word VectorD0
+ .word VectorD4
+ .word VectorD8
+ .word VectorDC
+ .word VectorE0
+ .word VectorE4
+ .word VectorE8
+
+.weak NMIVector
+NMIVector:
+
+.weak HardFaultVector
+HardFaultVector:
+
+.weak MemManageVector
+MemManageVector:
+
+.weak BusFaultVector
+BusFaultVector:
+
+.weak UsageFaultVector
+UsageFaultVector:
+
+.weak Vector1C
+Vector1C:
+
+.weak Vector20
+Vector20:
+
+.weak Vector24
+Vector24:
+
+.weak Vector28
+Vector28:
+
+.weak SVCallVector
+SVCallVector:
+
+.weak DebugMonitorVector
+DebugMonitorVector:
+
+.weak Vector34
+Vector34:
+
+.weak PendSVVector
+PendSVVector:
+
+.weak SysTickVector
+SysTickVector:
+
+.weak Vector40
+Vector40:
+
+.weak Vector44
+Vector44:
+
+.weak Vector48
+Vector48:
+
+.weak Vector4C
+Vector4C:
+
+.weak Vector50
+Vector50:
+
+.weak Vector54
+Vector54:
+
+.weak Vector58
+Vector58:
+
+.weak Vector5C
+Vector5C:
+
+.weak Vector60
+Vector60:
+
+.weak Vector64
+Vector64:
+
+.weak Vector68
+Vector68:
+
+.weak Vector6C
+Vector6C:
+
+.weak Vector70
+Vector70:
+
+.weak Vector74
+Vector74:
+
+.weak Vector78
+Vector78:
+
+.weak Vector7C
+Vector7C:
+
+.weak Vector80
+Vector80:
+
+.weak Vector84
+Vector84:
+
+.weak Vector88
+Vector88:
+
+.weak Vector8C
+Vector8C:
+
+.weak Vector90
+Vector90:
+
+.weak Vector94
+Vector94:
+
+.weak Vector98
+Vector98:
+
+.weak Vector9C
+Vector9C:
+
+.weak VectorA0
+VectorA0:
+
+.weak VectorA4
+VectorA4:
+
+.weak VectorA8
+VectorA8:
+
+.weak VectorAC
+VectorAC:
+
+.weak VectorB0
+VectorB0:
+
+.weak VectorB4
+VectorB4:
+
+.weak VectorB8
+VectorB8:
+
+.weak VectorBC
+VectorBC:
+
+.weak VectorC0
+VectorC0:
+
+.weak VectorC4
+VectorC4:
+
+.weak VectorC8
+VectorC8:
+
+.weak VectorCC
+VectorCC:
+
+.weak VectorD0
+VectorD0:
+
+.weak VectorD4
+VectorD4:
+
+.weak VectorD8
+VectorD8:
+
+.weak VectorDC
+VectorDC:
+
+.weak VectorE0
+VectorE0:
+
+.weak VectorE4
+VectorE4:
+
+.weak VectorE8
+VectorE8:
+
+here: b here
diff --git a/os/ports/GCC/ARMCM3/chcore.c b/os/ports/GCC/ARMCM3/chcore.c
new file mode 100644
index 000000000..80bd13490
--- /dev/null
+++ b/os/ports/GCC/ARMCM3/chcore.c
@@ -0,0 +1,177 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT 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 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT 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, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file ports/ARMCM3/chcore.c
+ * @brief ARM Cortex-M3 architecture port code.
+ * @addtogroup ARMCM3_CORE
+ * @{
+ */
+
+#include <ch.h>
+#include <nvic.h>
+
+/**
+ * Halts the system.
+ * @note The function is declared as a weak symbol, it is possible to redefine
+ * it in your application code.
+ */
+/** @cond never */
+__attribute__((weak))
+/** @endcond */
+void port_halt(void) {
+
+ port_disable();
+ while (TRUE) {
+ }
+}
+
+#if !CH_OPTIMIZE_SPEED
+void _port_lock(void) {
+ register uint32_t tmp asm ("r3") = BASEPRI_KERNEL;
+ asm volatile ("msr BASEPRI, %0" : : "r" (tmp));
+}
+
+void _port_unlock(void) {
+ register uint32_t tmp asm ("r3") = BASEPRI_USER;
+ asm volatile ("msr BASEPRI, %0" : : "r" (tmp));
+}
+#endif
+
+/**
+ * System Timer vector.
+ * This interrupt is used as system tick.
+ * @note The timer is initialized in the board setup code.
+ */
+CH_IRQ_HANDLER(SysTickVector) {
+
+ CH_IRQ_PROLOGUE();
+
+ chSysLockFromIsr();
+ chSysTimerHandlerI();
+ chSysUnlockFromIsr();
+
+ CH_IRQ_EPILOGUE();
+}
+
+/**
+ * The SVC vector is used for commanded context switch.
+ * @param otp the thread to be switched out
+ * @param ntp the thread to be switched it
+ */
+/** @cond never */
+__attribute__((naked))
+/** @endcond */
+void SVCallVector(Thread *otp, Thread *ntp) {
+ /* { r0 = otp, r1 = ntp } */
+ /* get the BASEPRI in r3 */
+ /* get the PSP in r12 */
+ /* push the registers on the PSP stack */
+ /* stores the modified PSP into the thread context */
+ /* fetches the PSP position from the new thread context */
+ /* pop the registers from the PSP stack */
+ /* set the PSP from r12 */
+ /* set the BASEPRI from R3 */
+#ifdef CH_CURRP_REGISTER_CACHE
+ asm volatile ("mrs r3, BASEPRI \n\t" \
+ "mrs r12, PSP \n\t" \
+ "stmdb r12!, {r3-r6,r8-r11, lr} \n\t" \
+ "str r12, [r0, #16] \n\t" \
+ "ldr r12, [r1, #16] \n\t" \
+ "ldmia r12!, {r3-r6,r8-r11, lr} \n\t" \
+ "msr PSP, r12 \n\t" \
+ "msr BASEPRI, r3 \n\t" \
+ "bx lr ");
+#else
+ asm volatile ("mrs r3, BASEPRI \n\t" \
+ "mrs r12, PSP \n\t" \
+ "stmdb r12!, {r3-r11, lr} \n\t" \
+ "str r12, [r0, #16] \n\t" \
+ "ldr r12, [r1, #16] \n\t" \
+ "ldmia r12!, {r3-r11, lr} \n\t" \
+ "msr PSP, r12 \n\t" \
+ "msr BASEPRI, r3 \n\t" \
+ "bx lr ");
+#endif
+}
+
+#ifdef CH_CURRP_REGISTER_CACHE
+#define PUSH_CONTEXT(sp) { \
+ register uint32_t tmp asm ("r3") = BASEPRI_USER; \
+ asm volatile ("mrs %0, PSP \n\t" \
+ "stmdb %0!, {r3-r6,r8-r11, lr}" : \
+ "=r" (sp) : "r" (sp), "r" (tmp)); \
+}
+
+#define POP_CONTEXT(sp) { \
+ asm volatile ("ldmia %0!, {r3-r6,r8-r11, lr} \n\t" \
+ "msr PSP, %0 \n\t" \
+ "msr BASEPRI, r3 \n\t" \
+ "bx lr" : "=r" (sp) : "r" (sp)); \
+}
+#else
+#define PUSH_CONTEXT(sp) { \
+ register uint32_t tmp asm ("r3") = BASEPRI_USER; \
+ asm volatile ("mrs %0, PSP \n\t" \
+ "stmdb %0!, {r3-r11,lr}" : \
+ "=r" (sp) : "r" (sp), "r" (tmp)); \
+}
+
+#define POP_CONTEXT(sp) { \
+ asm volatile ("ldmia %0!, {r3-r11, lr} \n\t" \
+ "msr PSP, %0 \n\t" \
+ "msr BASEPRI, r3 \n\t" \
+ "bx lr" : "=r" (sp) : "r" (sp)); \
+}
+#endif
+
+/**
+ * Preemption invoked context switch.
+ */
+/** @cond never */
+__attribute__((naked))
+/** @endcond */
+void PendSVVector(void) {
+ Thread *otp;
+ register struct intctx *sp_thd asm("r12");
+
+ chSysLockFromIsr();
+ asm volatile ("push {lr}");
+ if (!chSchRescRequiredI()) {
+ chSysUnlockFromIsr();
+ asm volatile ("pop {pc}");
+ }
+ asm volatile ("pop {lr}");
+
+ PUSH_CONTEXT(sp_thd);
+
+ (otp = currp)->p_ctx.r13 = sp_thd;
+ (currp = fifo_remove((void *)&rlist))->p_state = PRCURR;
+ chSchReadyI(otp);
+#if CH_USE_ROUNDROBIN
+ /* set the round-robin time quantum */
+ rlist.r_preempt = CH_TIME_QUANTUM;
+#endif
+ chDbgTrace(otp, currp);
+ sp_thd = currp->p_ctx.r13;
+
+ POP_CONTEXT(sp_thd);
+}
+
+/** @} */
diff --git a/os/ports/GCC/ARMCM3/chcore.h b/os/ports/GCC/ARMCM3/chcore.h
new file mode 100644
index 000000000..e54f3ca64
--- /dev/null
+++ b/os/ports/GCC/ARMCM3/chcore.h
@@ -0,0 +1,333 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT 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 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT 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, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file ports/ARMCM3/chcore.h
+ * @brief ARM Cortex-M3 architecture port macros and structures.
+ * @addtogroup ARMCM3_CORE
+ * @{
+ */
+
+#ifndef _CHCORE_H_
+#define _CHCORE_H_
+
+/*
+ * Port-related configuration parameters.
+ */
+
+/**
+ * Enables the use of the WFI ins.
+ */
+#ifndef ENABLE_WFI_IDLE
+#define ENABLE_WFI_IDLE 0
+#endif
+
+/**
+ * BASEPRI user level, 0 = disabled.
+ */
+#ifndef BASEPRI_USER
+#define BASEPRI_USER 0
+#endif
+
+/**
+ * BASEPRI level within kernel lock.
+ * Priority levels higher than this one (lower values) are unaffected by
+ * the OS activity and can be classified as fast interrupt sources, see
+ * @ref interrupt_classes.
+ */
+#ifndef BASEPRI_KERNEL
+#define BASEPRI_KERNEL 0x40
+#endif
+
+/**
+ * SVCALL handler priority.
+ * @note This priority must always be one level above the @p BASEPRI_KERNEL
+ * value.
+ * @note It is recommended to leave this priority level for this handler alone.
+ */
+#ifndef PRIORITY_SVCALL
+#define PRIORITY_SVCALL (BASEPRI_KERNEL - 0x10)
+#endif
+
+/**
+ * SYSTICK handler priority.
+ */
+#ifndef PRIORITY_SYSTICK
+#define PRIORITY_SYSTICK 0x80
+#endif
+
+/**
+ * PENDSV handler priority.
+ * @note It is recommended to leave this priority level for this handler alone.
+ * @note This is a reserved handler and its priority must always be the
+ * lowest priority in the system in order to be always executed last
+ * in the interrupt servicing chain.
+ */
+#ifndef PRIORITY_PENDSV
+#define PRIORITY_PENDSV 0xF0
+#endif
+
+/**
+ * Macro defining the ARM Cortex-M3 architecture.
+ */
+#define CH_ARCHITECTURE_ARMCM3
+
+/**
+ * Name of the implemented architecture.
+ */
+#define CH_ARCHITECTURE_NAME "ARM Cortex-M3"
+
+/**
+ * 32 bit stack alignment.
+ */
+typedef uint32_t stkalign_t;
+
+/**
+ * Generic ARM register.
+ */
+typedef void *regarm_t;
+
+/** @cond never */
+/**
+ * Interrupt saved context, empty in this architecture.
+ */
+struct extctx {
+};
+/** @endcond */
+
+/** @cond never */
+/**
+ * This structure represents the inner stack frame during a context switching.
+ */
+struct intctx {
+ regarm_t basepri;
+ regarm_t r4;
+ regarm_t r5;
+ regarm_t r6;
+#ifndef CH_CURRP_REGISTER_CACHE
+ regarm_t r7;
+#endif
+ regarm_t r8;
+ regarm_t r9;
+ regarm_t r10;
+ regarm_t r11;
+ regarm_t lr_exc;
+ regarm_t r0;
+ regarm_t r1;
+ regarm_t r2;
+ regarm_t r3;
+ regarm_t r12;
+ regarm_t lr_thd;
+ regarm_t pc;
+ regarm_t xpsr;
+};
+/** @endcond */
+
+/** @cond never */
+/**
+ * Cortex-M3 context structure.
+ */
+struct context {
+ struct intctx *r13;
+};
+/** @endcond */
+
+/**
+ * Platform dependent part of the @p chThdInit() API.
+ * This code usually setup the context switching frame represented by a
+ * @p intctx structure.
+ */
+#define SETUP_CONTEXT(workspace, wsize, pf, arg) { \
+ tp->p_ctx.r13 = (struct intctx *)((uint8_t *)workspace + \
+ wsize - \
+ sizeof(struct intctx)); \
+ tp->p_ctx.r13->basepri = BASEPRI_USER; \
+ tp->p_ctx.r13->lr_exc = (regarm_t)0xFFFFFFFD; \
+ tp->p_ctx.r13->r0 = arg; \
+ tp->p_ctx.r13->lr_thd = chThdExit; \
+ tp->p_ctx.r13->pc = pf; \
+ tp->p_ctx.r13->xpsr = (regarm_t)0x01000000; \
+}
+
+/**
+ * The default idle thread implementation requires no extra stack space in
+ * this port.
+ */
+#ifndef IDLE_THREAD_STACK_SIZE
+#define IDLE_THREAD_STACK_SIZE 0
+#endif
+
+/**
+ * This port requires no extra stack space for interrupt handling.
+ */
+#ifndef INT_REQUIRED_STACK
+#define INT_REQUIRED_STACK 0
+#endif
+
+/**
+ * Enforces a correct alignment for a stack area size value.
+ */
+#define STACK_ALIGN(n) ((((n) - 1) | (sizeof(stkalign_t) - 1)) + 1)
+
+/**
+ * Computes the thread working area global size.
+ */
+#define THD_WA_SIZE(n) STACK_ALIGN(sizeof(Thread) + \
+ sizeof(struct intctx) + \
+ sizeof(struct extctx) + \
+ (n) + (INT_REQUIRED_STACK))
+
+/**
+ * Macro used to allocate a thread working area aligned as both position and
+ * size.
+ */
+#define WORKING_AREA(s, n) stkalign_t s[THD_WA_SIZE(n) / sizeof(stkalign_t)];
+
+/**
+ * IRQ prologue code, inserted at the start of all IRQ handlers enabled to
+ * invoke system APIs.
+ */
+#define PORT_IRQ_PROLOGUE()
+
+/**
+ * IRQ epilogue code, inserted at the end of all IRQ handlers enabled to
+ * invoke system APIs.
+ */
+#define PORT_IRQ_EPILOGUE() { \
+ SCB_ICSR = ICSR_PENDSVSET; \
+}
+
+/**
+ * IRQ handler function declaration.
+ */
+#define PORT_IRQ_HANDLER(id) void id(void)
+
+/**
+ * This function is empty in this port.
+ */
+#define port_init()
+
+/**
+ * Raises the base priority to kernel level.
+ */
+#if CH_OPTIMIZE_SPEED
+#define port_lock() { \
+ register uint32_t tmp asm ("r3") = BASEPRI_KERNEL; \
+ asm volatile ("msr BASEPRI, %0" : : "r" (tmp)); \
+}
+#else
+#define port_lock() { \
+ asm volatile ("bl _port_lock" : : : "r3", "lr"); \
+}
+#endif
+
+/**
+ * Lowers the base priority to user level.
+ */
+#if CH_OPTIMIZE_SPEED
+#define port_unlock() { \
+ register uint32_t tmp asm ("r3") = BASEPRI_USER; \
+ asm volatile ("msr BASEPRI, %0" : : "r" (tmp)); \
+}
+#else
+#define port_unlock() { \
+ asm volatile ("bl _port_unlock" : : : "r3", "lr"); \
+}
+#endif
+
+/**
+ * Same as @p port_lock() in this port.
+ */
+#define port_lock_from_isr() port_lock()
+
+/**
+ * Same as @p port_unlock() in this port.
+ */
+#define port_unlock_from_isr() port_unlock()
+
+/**
+ * Disables all the interrupt sources by raising the priority mask to level 0.
+ */
+#define port_disable() asm volatile ("cpsid i")
+
+/**
+ * Raises/lowers the base priority to kernel level.
+ */
+#define port_suspend() { \
+ register uint32_t tmp asm ("r3") = BASEPRI_KERNEL; \
+ asm volatile ("msr BASEPRI, %0 \n\t" \
+ "cpsie i" : : "r" (tmp)); \
+}
+
+/**
+ * Lowers the base priority to user level.
+ */
+#define port_enable() { \
+ register uint32_t tmp asm ("r3") = BASEPRI_USER; \
+ asm volatile ("msr BASEPRI, %0 \n\t" \
+ "cpsie i" : : "r" (tmp)); \
+}
+
+/**
+ * This port function is implemented as inlined code for performance reasons.
+ */
+#if ENABLE_WFI_IDLE || defined(__DOXYGEN__)
+#define port_wait_for_interrupt() { \
+ asm volatile ("wfi"); \
+}
+#else
+#define port_wait_for_interrupt()
+#endif
+
+/**
+ * This port function is implemented as inlined code for performance reasons.
+ */
+#if CH_DBG_ENABLE_STACK_CHECK
+#define port_switch(otp, ntp) { \
+ register Thread *_otp asm ("r0") = (otp); \
+ register Thread *_ntp asm ("r1") = (ntp); \
+ register char *sp asm ("sp"); \
+ if (sp - sizeof(struct intctx) - sizeof(Thread) < (char *)_otp) \
+ asm volatile ("movs r0, #0 \n\t" \
+ "b chDbgPanic"); \
+ asm volatile ("svc #0" : : "r" (_otp), "r" (_ntp)); \
+}
+#else /* !CH_DBG_ENABLE_STACK_CHECK */
+#define port_switch(otp, ntp) { \
+ register Thread *_otp asm ("r0") = (otp); \
+ register Thread *_ntp asm ("r1") = (ntp); \
+ asm volatile ("svc #0" : : "r" (_otp), "r" (_ntp)); \
+}
+#endif /* !CH_DBG_ENABLE_STACK_CHECK */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void port_halt(void);
+#if !CH_OPTIMIZE_SPEED
+ void _port_lock(void);
+ void _port_unlock(void);
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _CHCORE_H_ */
+
+/** @} */
diff --git a/os/ports/GCC/ARMCM3/chtypes.h b/os/ports/GCC/ARMCM3/chtypes.h
new file mode 100644
index 000000000..7373b9823
--- /dev/null
+++ b/os/ports/GCC/ARMCM3/chtypes.h
@@ -0,0 +1,56 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT 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 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT 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, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file ports/ARMCM3/chtypes.h
+ * @brief ARM Cortex-M3 architecture port system types.
+ * @addtogroup ARMCM3_CORE
+ * @{
+ */
+
+#ifndef _CHTYPES_H_
+#define _CHTYPES_H_
+
+#define __need_NULL
+#define __need_size_t
+#define __need_ptrdiff_t
+#include <stddef.h>
+
+#if !defined(_STDINT_H) && !defined(__STDINT_H_)
+#include <stdint.h>
+#endif
+
+typedef int32_t bool_t; /**< Fast boolean type. */
+typedef uint8_t tmode_t; /**< Thread flags. */
+typedef uint8_t tstate_t; /**< Thread state. */
+typedef uint32_t tprio_t; /**< Thread priority. */
+typedef int32_t msg_t; /**< Inter-thread message. */
+typedef int32_t eventid_t; /**< Event Id. */
+typedef uint32_t eventmask_t; /**< Events mask. */
+typedef uint32_t systime_t; /**< System time. */
+typedef int32_t cnt_t; /**< Resources counter. */
+
+#define INLINE inline
+#define PACK_STRUCT_STRUCT __attribute__((packed))
+#define PACK_STRUCT_BEGIN
+#define PACK_STRUCT_END
+
+#endif /* _CHTYPES_H_ */
+
+/** @} */
diff --git a/os/ports/GCC/ARMCM3/cmsis/core_cm3.c b/os/ports/GCC/ARMCM3/cmsis/core_cm3.c
new file mode 100644
index 000000000..ea8cb1ac0
--- /dev/null
+++ b/os/ports/GCC/ARMCM3/cmsis/core_cm3.c
@@ -0,0 +1,829 @@
+/******************************************************************************
+ * @file: core_cm3.c
+ * @purpose: CMSIS Cortex-M3 Core Peripheral Access Layer Source File
+ * @version: V1.20
+ * @date: 22. May 2009
+ *----------------------------------------------------------------------------
+ *
+ * Copyright (C) 2009 ARM Limited. All rights reserved.
+ *
+ * ARM Limited (ARM) is supplying this software for use with Cortex-Mx
+ * processor based microcontrollers. This file can be freely distributed
+ * within development tools that are supporting such ARM based processors.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
+ * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
+ * ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
+ * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
+ *
+ ******************************************************************************/
+
+
+
+#include <stdint.h>
+
+
+/* define compiler specific symbols */
+#if defined ( __CC_ARM )
+ #define __ASM __asm /*!< asm keyword for armcc */
+ #define __INLINE __inline /*!< inline keyword for armcc */
+
+#elif defined ( __ICCARM__ )
+ #define __ASM __asm /*!< asm keyword for iarcc */
+ #define __INLINE inline /*!< inline keyword for iarcc. Only avaiable in High optimization mode! */
+
+#elif defined ( __GNUC__ )
+ #define __ASM __asm /*!< asm keyword for gcc */
+ #define __INLINE inline /*!< inline keyword for gcc */
+
+#elif defined ( __TASKING__ )
+ #define __ASM __asm /*!< asm keyword for TASKING Compiler */
+ #define __INLINE inline /*!< inline keyword for TASKING Compiler */
+
+#endif
+
+
+
+#if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/
+
+/**
+ * @brief Return the Process Stack Pointer
+ *
+ * @param none
+ * @return uint32_t ProcessStackPointer
+ *
+ * Return the actual process stack pointer
+ */
+__ASM uint32_t __get_PSP(void)
+{
+ mrs r0, psp
+ bx lr
+}
+
+/**
+ * @brief Set the Process Stack Pointer
+ *
+ * @param uint32_t Process Stack Pointer
+ * @return none
+ *
+ * Assign the value ProcessStackPointer to the MSP
+ * (process stack pointer) Cortex processor register
+ */
+__ASM void __set_PSP(uint32_t topOfProcStack)
+{
+ msr psp, r0
+ bx lr
+}
+
+/**
+ * @brief Return the Main Stack Pointer
+ *
+ * @param none
+ * @return uint32_t Main Stack Pointer
+ *
+ * Return the current value of the MSP (main stack pointer)
+ * Cortex processor register
+ */
+__ASM uint32_t __get_MSP(void)
+{
+ mrs r0, msp
+ bx lr
+}
+
+/**
+ * @brief Set the Main Stack Pointer
+ *
+ * @param uint32_t Main Stack Pointer
+ * @return none
+ *
+ * Assign the value mainStackPointer to the MSP
+ * (main stack pointer) Cortex processor register
+ */
+__ASM void __set_MSP(uint32_t mainStackPointer)
+{
+ msr msp, r0
+ bx lr
+}
+
+/**
+ * @brief Reverse byte order in unsigned short value
+ *
+ * @param uint16_t value to reverse
+ * @return uint32_t reversed value
+ *
+ * Reverse byte order in unsigned short value
+ */
+__ASM uint32_t __REV16(uint16_t value)
+{
+ rev16 r0, r0
+ bx lr
+}
+
+/**
+ * @brief Reverse byte order in signed short value with sign extension to integer
+ *
+ * @param int16_t value to reverse
+ * @return int32_t reversed value
+ *
+ * Reverse byte order in signed short value with sign extension to integer
+ */
+__ASM int32_t __REVSH(int16_t value)
+{
+ revsh r0, r0
+ bx lr
+}
+
+
+#if (__ARMCC_VERSION < 400000)
+
+/**
+ * @brief Remove the exclusive lock created by ldrex
+ *
+ * @param none
+ * @return none
+ *
+ * Removes the exclusive lock which is created by ldrex.
+ */
+__ASM void __CLREX(void)
+{
+ clrex
+}
+
+/**
+ * @brief Return the Base Priority value
+ *
+ * @param none
+ * @return uint32_t BasePriority
+ *
+ * Return the content of the base priority register
+ */
+__ASM uint32_t __get_BASEPRI(void)
+{
+ mrs r0, basepri
+ bx lr
+}
+
+/**
+ * @brief Set the Base Priority value
+ *
+ * @param uint32_t BasePriority
+ * @return none
+ *
+ * Set the base priority register
+ */
+__ASM void __set_BASEPRI(uint32_t basePri)
+{
+ msr basepri, r0
+ bx lr
+}
+
+/**
+ * @brief Return the Priority Mask value
+ *
+ * @param none
+ * @return uint32_t PriMask
+ *
+ * Return the state of the priority mask bit from the priority mask
+ * register
+ */
+__ASM uint32_t __get_PRIMASK(void)
+{
+ mrs r0, primask
+ bx lr
+}
+
+/**
+ * @brief Set the Priority Mask value
+ *
+ * @param uint32_t PriMask
+ * @return none
+ *
+ * Set the priority mask bit in the priority mask register
+ */
+__ASM void __set_PRIMASK(uint32_t priMask)
+{
+ msr primask, r0
+ bx lr
+}
+
+/**
+ * @brief Return the Fault Mask value
+ *
+ * @param none
+ * @return uint32_t FaultMask
+ *
+ * Return the content of the fault mask register
+ */
+__ASM uint32_t __get_FAULTMASK(void)
+{
+ mrs r0, faultmask
+ bx lr
+}
+
+/**
+ * @brief Set the Fault Mask value
+ *
+ * @param uint32_t faultMask value
+ * @return none
+ *
+ * Set the fault mask register
+ */
+__ASM void __set_FAULTMASK(uint32_t faultMask)
+{
+ msr faultmask, r0
+ bx lr
+}
+
+/**
+ * @brief Return the Control Register value
+ *
+ * @param none
+ * @return uint32_t Control value
+ *
+ * Return the content of the control register
+ */
+__ASM uint32_t __get_CONTROL(void)
+{
+ mrs r0, control
+ bx lr
+}
+
+/**
+ * @brief Set the Control Register value
+ *
+ * @param uint32_t Control value
+ * @return none
+ *
+ * Set the control register
+ */
+__ASM void __set_CONTROL(uint32_t control)
+{
+ msr control, r0
+ bx lr
+}
+
+#endif /* __ARMCC_VERSION */
+
+
+#elif (defined (__ICCARM__)) /*------------------ ICC Compiler -------------------*/
+#pragma diag_suppress=Pe940
+
+/**
+ * @brief Return the Process Stack Pointer
+ *
+ * @param none
+ * @return uint32_t ProcessStackPointer
+ *
+ * Return the actual process stack pointer
+ */
+uint32_t __get_PSP(void)
+{
+ __ASM("mrs r0, psp");
+ __ASM("bx lr");
+}
+
+/**
+ * @brief Set the Process Stack Pointer
+ *
+ * @param uint32_t Process Stack Pointer
+ * @return none
+ *
+ * Assign the value ProcessStackPointer to the MSP
+ * (process stack pointer) Cortex processor register
+ */
+void __set_PSP(uint32_t topOfProcStack)
+{
+ __ASM("msr psp, r0");
+ __ASM("bx lr");
+}
+
+/**
+ * @brief Return the Main Stack Pointer
+ *
+ * @param none
+ * @return uint32_t Main Stack Pointer
+ *
+ * Return the current value of the MSP (main stack pointer)
+ * Cortex processor register
+ */
+uint32_t __get_MSP(void)
+{
+ __ASM("mrs r0, msp");
+ __ASM("bx lr");
+}
+
+/**
+ * @brief Set the Main Stack Pointer
+ *
+ * @param uint32_t Main Stack Pointer
+ * @return none
+ *
+ * Assign the value mainStackPointer to the MSP
+ * (main stack pointer) Cortex processor register
+ */
+void __set_MSP(uint32_t topOfMainStack)
+{
+ __ASM("msr msp, r0");
+ __ASM("bx lr");
+}
+
+/**
+ * @brief Reverse byte order in unsigned short value
+ *
+ * @param uint16_t value to reverse
+ * @return uint32_t reversed value
+ *
+ * Reverse byte order in unsigned short value
+ */
+uint32_t __REV16(uint16_t value)
+{
+ __ASM("rev16 r0, r0");
+ __ASM("bx lr");
+}
+
+/**
+ * @brief Reverse bit order of value
+ *
+ * @param uint32_t value to reverse
+ * @return uint32_t reversed value
+ *
+ * Reverse bit order of value
+ */
+uint32_t __RBIT(uint32_t value)
+{
+ __ASM("rbit r0, r0");
+ __ASM("bx lr");
+}
+
+/**
+ * @brief LDR Exclusive
+ *
+ * @param uint8_t* address
+ * @return uint8_t value of (*address)
+ *
+ * Exclusive LDR command
+ */
+uint8_t __LDREXB(uint8_t *addr)
+{
+ __ASM("ldrexb r0, [r0]");
+ __ASM("bx lr");
+}
+
+/**
+ * @brief LDR Exclusive
+ *
+ * @param uint16_t* address
+ * @return uint16_t value of (*address)
+ *
+ * Exclusive LDR command
+ */
+uint16_t __LDREXH(uint16_t *addr)
+{
+ __ASM("ldrexh r0, [r0]");
+ __ASM("bx lr");
+}
+
+/**
+ * @brief LDR Exclusive
+ *
+ * @param uint32_t* address
+ * @return uint32_t value of (*address)
+ *
+ * Exclusive LDR command
+ */
+uint32_t __LDREXW(uint32_t *addr)
+{
+ __ASM("ldrex r0, [r0]");
+ __ASM("bx lr");
+}
+
+/**
+ * @brief STR Exclusive
+ *
+ * @param uint8_t *address
+ * @param uint8_t value to store
+ * @return uint32_t successful / failed
+ *
+ * Exclusive STR command
+ */
+uint32_t __STREXB(uint8_t value, uint8_t *addr)
+{
+ __ASM("strexb r0, r0, [r1]");
+ __ASM("bx lr");
+}
+
+/**
+ * @brief STR Exclusive
+ *
+ * @param uint16_t *address
+ * @param uint16_t value to store
+ * @return uint32_t successful / failed
+ *
+ * Exclusive STR command
+ */
+uint32_t __STREXH(uint16_t value, uint16_t *addr)
+{
+ __ASM("strexh r0, r0, [r1]");
+ __ASM("bx lr");
+}
+
+/**
+ * @brief STR Exclusive
+ *
+ * @param uint32_t *address
+ * @param uint32_t value to store
+ * @return uint32_t successful / failed
+ *
+ * Exclusive STR command
+ */
+uint32_t __STREXW(uint32_t value, uint32_t *addr)
+{
+ __ASM("strex r0, r0, [r1]");
+ __ASM("bx lr");
+}
+
+#pragma diag_default=Pe940
+
+
+#elif (defined (__GNUC__)) /*------------------ GNU Compiler ---------------------*/
+
+/**
+ * @brief Return the Process Stack Pointer
+ *
+ * @param none
+ * @return uint32_t ProcessStackPointer
+ *
+ * Return the actual process stack pointer
+ */
+uint32_t __get_PSP(void) __attribute__( ( naked ) );
+uint32_t __get_PSP(void)
+{
+ uint32_t result=0;
+
+ __ASM volatile ("MRS %0, psp\n\t"
+ "MOV r0, %0 \n\t"
+ "BX lr \n\t" : "=r" (result) );
+ return(result);
+}
+
+
+/**
+ * @brief Set the Process Stack Pointer
+ *
+ * @param uint32_t Process Stack Pointer
+ * @return none
+ *
+ * Assign the value ProcessStackPointer to the MSP
+ * (process stack pointer) Cortex processor register
+ */
+void __set_PSP(uint32_t topOfProcStack) __attribute__( ( naked ) );
+void __set_PSP(uint32_t topOfProcStack)
+{
+ __ASM volatile ("MSR psp, %0\n\t"
+ "BX lr \n\t" : : "r" (topOfProcStack) );
+}
+
+/**
+ * @brief Return the Main Stack Pointer
+ *
+ * @param none
+ * @return uint32_t Main Stack Pointer
+ *
+ * Return the current value of the MSP (main stack pointer)
+ * Cortex processor register
+ */
+uint32_t __get_MSP(void) __attribute__( ( naked ) );
+uint32_t __get_MSP(void)
+{
+ uint32_t result=0;
+
+ __ASM volatile ("MRS %0, msp\n\t"
+ "MOV r0, %0 \n\t"
+ "BX lr \n\t" : "=r" (result) );
+ return(result);
+}
+
+/**
+ * @brief Set the Main Stack Pointer
+ *
+ * @param uint32_t Main Stack Pointer
+ * @return none
+ *
+ * Assign the value mainStackPointer to the MSP
+ * (main stack pointer) Cortex processor register
+ */
+void __set_MSP(uint32_t topOfMainStack) __attribute__( ( naked ) );
+void __set_MSP(uint32_t topOfMainStack)
+{
+ __ASM volatile ("MSR msp, %0\n\t"
+ "BX lr \n\t" : : "r" (topOfMainStack) );
+}
+
+/**
+ * @brief Return the Base Priority value
+ *
+ * @param none
+ * @return uint32_t BasePriority
+ *
+ * Return the content of the base priority register
+ */
+uint32_t __get_BASEPRI(void)
+{
+ uint32_t result=0;
+
+ __ASM volatile ("MRS %0, basepri_max" : "=r" (result) );
+ return(result);
+}
+
+/**
+ * @brief Set the Base Priority value
+ *
+ * @param uint32_t BasePriority
+ * @return none
+ *
+ * Set the base priority register
+ */
+void __set_BASEPRI(uint32_t value)
+{
+ __ASM volatile ("MSR basepri, %0" : : "r" (value) );
+}
+
+/**
+ * @brief Return the Priority Mask value
+ *
+ * @param none
+ * @return uint32_t PriMask
+ *
+ * Return the state of the priority mask bit from the priority mask
+ * register
+ */
+uint32_t __get_PRIMASK(void)
+{
+ uint32_t result=0;
+
+ __ASM volatile ("MRS %0, primask" : "=r" (result) );
+ return(result);
+}
+
+/**
+ * @brief Set the Priority Mask value
+ *
+ * @param uint32_t PriMask
+ * @return none
+ *
+ * Set the priority mask bit in the priority mask register
+ */
+void __set_PRIMASK(uint32_t priMask)
+{
+ __ASM volatile ("MSR primask, %0" : : "r" (priMask) );
+}
+
+/**
+ * @brief Return the Fault Mask value
+ *
+ * @param none
+ * @return uint32_t FaultMask
+ *
+ * Return the content of the fault mask register
+ */
+uint32_t __get_FAULTMASK(void)
+{
+ uint32_t result=0;
+
+ __ASM volatile ("MRS %0, faultmask" : "=r" (result) );
+ return(result);
+}
+
+/**
+ * @brief Set the Fault Mask value
+ *
+ * @param uint32_t faultMask value
+ * @return none
+ *
+ * Set the fault mask register
+ */
+void __set_FAULTMASK(uint32_t faultMask)
+{
+ __ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) );
+}
+
+/**
+ * @brief Reverse byte order in integer value
+ *
+ * @param uint32_t value to reverse
+ * @return uint32_t reversed value
+ *
+ * Reverse byte order in integer value
+ */
+uint32_t __REV(uint32_t value)
+{
+ uint32_t result=0;
+
+ __ASM volatile ("rev %0, %1" : "=r" (result) : "r" (value) );
+ return(result);
+}
+
+/**
+ * @brief Reverse byte order in unsigned short value
+ *
+ * @param uint16_t value to reverse
+ * @return uint32_t reversed value
+ *
+ * Reverse byte order in unsigned short value
+ */
+uint32_t __REV16(uint16_t value)
+{
+ uint32_t result=0;
+
+ __ASM volatile ("rev16 %0, %1" : "=r" (result) : "r" (value) );
+ return(result);
+}
+
+/**
+ * @brief Reverse byte order in signed short value with sign extension to integer
+ *
+ * @param int32_t value to reverse
+ * @return int32_t reversed value
+ *
+ * Reverse byte order in signed short value with sign extension to integer
+ */
+int32_t __REVSH(int16_t value)
+{
+ uint32_t result=0;
+
+ __ASM volatile ("revsh %0, %1" : "=r" (result) : "r" (value) );
+ return(result);
+}
+
+/**
+ * @brief Reverse bit order of value
+ *
+ * @param uint32_t value to reverse
+ * @return uint32_t reversed value
+ *
+ * Reverse bit order of value
+ */
+uint32_t __RBIT(uint32_t value)
+{
+ uint32_t result=0;
+
+ __ASM volatile ("rbit %0, %1" : "=r" (result) : "r" (value) );
+ return(result);
+}
+
+/**
+ * @brief LDR Exclusive
+ *
+ * @param uint8_t* address
+ * @return uint8_t value of (*address)
+ *
+ * Exclusive LDR command
+ */
+uint8_t __LDREXB(uint8_t *addr)
+{
+ uint8_t result=0;
+
+ __ASM volatile ("ldrexb %0, [%1]" : "=r" (result) : "r" (addr) );
+ return(result);
+}
+
+/**
+ * @brief LDR Exclusive
+ *
+ * @param uint16_t* address
+ * @return uint16_t value of (*address)
+ *
+ * Exclusive LDR command
+ */
+uint16_t __LDREXH(uint16_t *addr)
+{
+ uint16_t result=0;
+
+ __ASM volatile ("ldrexh %0, [%1]" : "=r" (result) : "r" (addr) );
+ return(result);
+}
+
+/**
+ * @brief LDR Exclusive
+ *
+ * @param uint32_t* address
+ * @return uint32_t value of (*address)
+ *
+ * Exclusive LDR command
+ */
+uint32_t __LDREXW(uint32_t *addr)
+{
+ uint32_t result=0;
+
+ __ASM volatile ("ldrex %0, [%1]" : "=r" (result) : "r" (addr) );
+ return(result);
+}
+
+/**
+ * @brief STR Exclusive
+ *
+ * @param uint8_t *address
+ * @param uint8_t value to store
+ * @return uint32_t successful / failed
+ *
+ * Exclusive STR command
+ */
+uint32_t __STREXB(uint8_t value, uint8_t *addr)
+{
+ uint32_t result=0;
+
+ __ASM volatile ("strexb %0, %2, [%1]" : "=r" (result) : "r" (addr), "r" (value) );
+ return(result);
+}
+
+/**
+ * @brief STR Exclusive
+ *
+ * @param uint16_t *address
+ * @param uint16_t value to store
+ * @return uint32_t successful / failed
+ *
+ * Exclusive STR command
+ */
+uint32_t __STREXH(uint16_t value, uint16_t *addr)
+{
+ uint32_t result=0;
+
+ __ASM volatile ("strexh %0, %2, [%1]" : "=r" (result) : "r" (addr), "r" (value) );
+ return(result);
+}
+
+/**
+ * @brief STR Exclusive
+ *
+ * @param uint32_t *address
+ * @param uint32_t value to store
+ * @return uint32_t successful / failed
+ *
+ * Exclusive STR command
+ */
+uint32_t __STREXW(uint32_t value, uint32_t *addr)
+{
+ uint32_t result=0;
+
+ __ASM volatile ("strex %0, %2, [%1]" : "=r" (result) : "r" (addr), "r" (value) );
+ return(result);
+}
+
+/**
+ * @brief Return the Control Register value
+ *
+ * @param none
+ * @return uint32_t Control value
+ *
+ * Return the content of the control register
+ */
+uint32_t __get_CONTROL(void)
+{
+ uint32_t result=0;
+
+ __ASM volatile ("MRS %0, control" : "=r" (result) );
+ return(result);
+}
+
+/**
+ * @brief Set the Control Register value
+ *
+ * @param uint32_t Control value
+ * @return none
+ *
+ * Set the control register
+ */
+void __set_CONTROL(uint32_t control)
+{
+ __ASM volatile ("MSR control, %0" : : "r" (control) );
+}
+
+#elif (defined (__TASKING__)) /*------------------ TASKING Compiler ---------------------*/
+/* TASKING carm specific functions */
+
+/*
+ * The CMSIS functions have been implemented as intrinsics in the compiler.
+ * Please use "carm -?i" to get an up to date list of all instrinsics,
+ * Including the CMSIS ones.
+ */
+
+#endif
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/os/ports/GCC/ARMCM3/cmsis/core_cm3.h b/os/ports/GCC/ARMCM3/cmsis/core_cm3.h
new file mode 100644
index 000000000..eaec52246
--- /dev/null
+++ b/os/ports/GCC/ARMCM3/cmsis/core_cm3.h
@@ -0,0 +1,1374 @@
+/******************************************************************************
+ * @file: core_cm3.h
+ * @purpose: CMSIS Cortex-M3 Core Peripheral Access Layer Header File
+ * @version: V1.20.1 (ChibiOS/RT fixes)
+ * @date: 18. July 2009
+ *----------------------------------------------------------------------------
+ *
+ * Copyright (C) 2009 ARM Limited. All rights reserved.
+ *
+ * ARM Limited (ARM) is supplying this software for use with Cortex-Mx
+ * processor based microcontrollers. This file can be freely distributed
+ * within development tools that are supporting such ARM based processors.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
+ * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
+ * ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
+ * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ * ChibiOS/RT notes and fixes:
+ *
+ * - Lines 790..803, added "void" to the parameters list in order to suppress
+ * a warning (-Wall enabled).
+ ******************************************************************************/
+
+#ifndef __CM3_CORE_H__
+#define __CM3_CORE_H__
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+#define __CM3_CMSIS_VERSION_MAIN (0x01) /*!< [31:16] CMSIS HAL main version */
+#define __CM3_CMSIS_VERSION_SUB (0x20) /*!< [15:0] CMSIS HAL sub version */
+#define __CM3_CMSIS_VERSION ((__CM3_CMSIS_VERSION_MAIN << 16) | __CM3_CMSIS_VERSION_SUB) /*!< CMSIS HAL version number */
+
+#define __CORTEX_M (0x03) /*!< Cortex core */
+
+/**
+ * Lint configuration \n
+ * ----------------------- \n
+ *
+ * The following Lint messages will be suppressed and not shown: \n
+ * \n
+ * --- Error 10: --- \n
+ * register uint32_t __regBasePri __asm("basepri"); \n
+ * Error 10: Expecting ';' \n
+ * \n
+ * --- Error 530: --- \n
+ * return(__regBasePri); \n
+ * Warning 530: Symbol '__regBasePri' (line 264) not initialized \n
+ * \n
+ * --- Error 550: --- \n
+ * __regBasePri = (basePri & 0x1ff); \n
+ * } \n
+ * Warning 550: Symbol '__regBasePri' (line 271) not accessed \n
+ * \n
+ * --- Error 754: --- \n
+ * uint32_t RESERVED0[24]; \n
+ * Info 754: local structure member '<some, not used in the HAL>' (line 109, file ./cm3_core.h) not referenced \n
+ * \n
+ * --- Error 750: --- \n
+ * #define __CM3_CORE_H__ \n
+ * Info 750: local macro '__CM3_CORE_H__' (line 43, file./cm3_core.h) not referenced \n
+ * \n
+ * --- Error 528: --- \n
+ * static __INLINE void NVIC_DisableIRQ(uint32_t IRQn) \n
+ * Warning 528: Symbol 'NVIC_DisableIRQ(unsigned int)' (line 419, file ./cm3_core.h) not referenced \n
+ * \n
+ * --- Error 751: --- \n
+ * } InterruptType_Type; \n
+ * Info 751: local typedef 'InterruptType_Type' (line 170, file ./cm3_core.h) not referenced \n
+ * \n
+ * \n
+ * Note: To re-enable a Message, insert a space before 'lint' * \n
+ *
+ */
+
+/*lint -save */
+/*lint -e10 */
+/*lint -e530 */
+/*lint -e550 */
+/*lint -e754 */
+/*lint -e750 */
+/*lint -e528 */
+/*lint -e751 */
+
+
+#include <stdint.h> /* Include standard types */
+
+#if defined (__ICCARM__)
+ #include <intrinsics.h> /* IAR Intrinsics */
+#endif
+
+
+#ifndef __NVIC_PRIO_BITS
+ #define __NVIC_PRIO_BITS 4 /*!< standard definition for NVIC Priority Bits */
+#endif
+
+
+
+
+/**
+ * IO definitions
+ *
+ * define access restrictions to peripheral registers
+ */
+
+#ifdef __cplusplus
+#define __I volatile /*!< defines 'read only' permissions */
+#else
+#define __I volatile const /*!< defines 'read only' permissions */
+#endif
+#define __O volatile /*!< defines 'write only' permissions */
+#define __IO volatile /*!< defines 'read / write' permissions */
+
+
+
+/*******************************************************************************
+ * Register Abstraction
+ ******************************************************************************/
+
+
+/* System Reset */
+#define NVIC_VECTRESET 0 /*!< Vector Reset Bit */
+#define NVIC_SYSRESETREQ 2 /*!< System Reset Request */
+#define NVIC_AIRCR_VECTKEY (0x5FA << 16) /*!< AIRCR Key for write access */
+#define NVIC_AIRCR_ENDIANESS 15 /*!< Endianess */
+
+/* Core Debug */
+#define CoreDebug_DEMCR_TRCENA (1 << 24) /*!< DEMCR TRCENA enable */
+#define ITM_TCR_ITMENA 1 /*!< ITM enable */
+
+
+
+
+/* memory mapping struct for Nested Vectored Interrupt Controller (NVIC) */
+typedef struct
+{
+ __IO uint32_t ISER[8]; /*!< Interrupt Set Enable Register */
+ uint32_t RESERVED0[24];
+ __IO uint32_t ICER[8]; /*!< Interrupt Clear Enable Register */
+ uint32_t RSERVED1[24];
+ __IO uint32_t ISPR[8]; /*!< Interrupt Set Pending Register */
+ uint32_t RESERVED2[24];
+ __IO uint32_t ICPR[8]; /*!< Interrupt Clear Pending Register */
+ uint32_t RESERVED3[24];
+ __IO uint32_t IABR[8]; /*!< Interrupt Active bit Register */
+ uint32_t RESERVED4[56];
+ __IO uint8_t IP[240]; /*!< Interrupt Priority Register, 8Bit wide */
+ uint32_t RESERVED5[644];
+ __O uint32_t STIR; /*!< Software Trigger Interrupt Register */
+} NVIC_Type;
+
+
+/* memory mapping struct for System Control Block */
+typedef struct
+{
+ __I uint32_t CPUID; /*!< CPU ID Base Register */
+ __IO uint32_t ICSR; /*!< Interrupt Control State Register */
+ __IO uint32_t VTOR; /*!< Vector Table Offset Register */
+ __IO uint32_t AIRCR; /*!< Application Interrupt / Reset Control Register */
+ __IO uint32_t SCR; /*!< System Control Register */
+ __IO uint32_t CCR; /*!< Configuration Control Register */
+ __IO uint8_t SHP[12]; /*!< System Handlers Priority Registers (4-7, 8-11, 12-15) */
+ __IO uint32_t SHCSR; /*!< System Handler Control and State Register */
+ __IO uint32_t CFSR; /*!< Configurable Fault Status Register */
+ __IO uint32_t HFSR; /*!< Hard Fault Status Register */
+ __IO uint32_t DFSR; /*!< Debug Fault Status Register */
+ __IO uint32_t MMFAR; /*!< Mem Manage Address Register */
+ __IO uint32_t BFAR; /*!< Bus Fault Address Register */
+ __IO uint32_t AFSR; /*!< Auxiliary Fault Status Register */
+ __I uint32_t PFR[2]; /*!< Processor Feature Register */
+ __I uint32_t DFR; /*!< Debug Feature Register */
+ __I uint32_t ADR; /*!< Auxiliary Feature Register */
+ __I uint32_t MMFR[4]; /*!< Memory Model Feature Register */
+ __I uint32_t ISAR[5]; /*!< ISA Feature Register */
+} SCB_Type;
+
+
+/* memory mapping struct for SysTick */
+typedef struct
+{
+ __IO uint32_t CTRL; /*!< SysTick Control and Status Register */
+ __IO uint32_t LOAD; /*!< SysTick Reload Value Register */
+ __IO uint32_t VAL; /*!< SysTick Current Value Register */
+ __I uint32_t CALIB; /*!< SysTick Calibration Register */
+} SysTick_Type;
+
+
+/* memory mapping structur for ITM */
+typedef struct
+{
+ __O union
+ {
+ __O uint8_t u8; /*!< ITM Stimulus Port 8-bit */
+ __O uint16_t u16; /*!< ITM Stimulus Port 16-bit */
+ __O uint32_t u32; /*!< ITM Stimulus Port 32-bit */
+ } PORT [32]; /*!< ITM Stimulus Port Registers */
+ uint32_t RESERVED0[864];
+ __IO uint32_t TER; /*!< ITM Trace Enable Register */
+ uint32_t RESERVED1[15];
+ __IO uint32_t TPR; /*!< ITM Trace Privilege Register */
+ uint32_t RESERVED2[15];
+ __IO uint32_t TCR; /*!< ITM Trace Control Register */
+ uint32_t RESERVED3[29];
+ __IO uint32_t IWR; /*!< ITM Integration Write Register */
+ __IO uint32_t IRR; /*!< ITM Integration Read Register */
+ __IO uint32_t IMCR; /*!< ITM Integration Mode Control Register */
+ uint32_t RESERVED4[43];
+ __IO uint32_t LAR; /*!< ITM Lock Access Register */
+ __IO uint32_t LSR; /*!< ITM Lock Status Register */
+ uint32_t RESERVED5[6];
+ __I uint32_t PID4; /*!< ITM Product ID Registers */
+ __I uint32_t PID5;
+ __I uint32_t PID6;
+ __I uint32_t PID7;
+ __I uint32_t PID0;
+ __I uint32_t PID1;
+ __I uint32_t PID2;
+ __I uint32_t PID3;
+ __I uint32_t CID0;
+ __I uint32_t CID1;
+ __I uint32_t CID2;
+ __I uint32_t CID3;
+} ITM_Type;
+
+
+/* memory mapped struct for Interrupt Type */
+typedef struct
+{
+ uint32_t RESERVED0;
+ __I uint32_t ICTR; /*!< Interrupt Control Type Register */
+#if ((defined __CM3_REV) && (__CM3_REV >= 0x200))
+ __IO uint32_t ACTLR; /*!< Auxiliary Control Register */
+#else
+ uint32_t RESERVED1;
+#endif
+} InterruptType_Type;
+
+
+/* Memory Protection Unit */
+#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1)
+typedef struct
+{
+ __I uint32_t TYPE; /*!< MPU Type Register */
+ __IO uint32_t CTRL; /*!< MPU Control Register */
+ __IO uint32_t RNR; /*!< MPU Region RNRber Register */
+ __IO uint32_t RBAR; /*!< MPU Region Base Address Register */
+ __IO uint32_t RASR; /*!< MPU Region Attribute and Size Register */
+ __IO uint32_t RBAR_A1; /*!< MPU Alias 1 Region Base Address Register */
+ __IO uint32_t RASR_A1; /*!< MPU Alias 1 Region Attribute and Size Register */
+ __IO uint32_t RBAR_A2; /*!< MPU Alias 2 Region Base Address Register */
+ __IO uint32_t RASR_A2; /*!< MPU Alias 2 Region Attribute and Size Register */
+ __IO uint32_t RBAR_A3; /*!< MPU Alias 3 Region Base Address Register */
+ __IO uint32_t RASR_A3; /*!< MPU Alias 3 Region Attribute and Size Register */
+} MPU_Type;
+#endif
+
+
+/* Core Debug Register */
+typedef struct
+{
+ __IO uint32_t DHCSR; /*!< Debug Halting Control and Status Register */
+ __O uint32_t DCRSR; /*!< Debug Core Register Selector Register */
+ __IO uint32_t DCRDR; /*!< Debug Core Register Data Register */
+ __IO uint32_t DEMCR; /*!< Debug Exception and Monitor Control Register */
+} CoreDebug_Type;
+
+
+/* Memory mapping of Cortex-M3 Hardware */
+#define SCS_BASE (0xE000E000) /*!< System Control Space Base Address */
+#define ITM_BASE (0xE0000000) /*!< ITM Base Address */
+#define CoreDebug_BASE (0xE000EDF0) /*!< Core Debug Base Address */
+#define SysTick_BASE (SCS_BASE + 0x0010) /*!< SysTick Base Address */
+#define NVIC_BASE (SCS_BASE + 0x0100) /*!< NVIC Base Address */
+#define SCB_BASE (SCS_BASE + 0x0D00) /*!< System Control Block Base Address */
+
+#define InterruptType ((InterruptType_Type *) SCS_BASE) /*!< Interrupt Type Register */
+#define SCB ((SCB_Type *) SCB_BASE) /*!< SCB configuration struct */
+#define SysTick ((SysTick_Type *) SysTick_BASE) /*!< SysTick configuration struct */
+#define NVIC ((NVIC_Type *) NVIC_BASE) /*!< NVIC configuration struct */
+#define ITM ((ITM_Type *) ITM_BASE) /*!< ITM configuration struct */
+#define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE) /*!< Core Debug configuration struct */
+
+#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1)
+ #define MPU_BASE (SCS_BASE + 0x0D90) /*!< Memory Protection Unit */
+ #define MPU ((MPU_Type*) MPU_BASE) /*!< Memory Protection Unit */
+#endif
+
+
+
+/*******************************************************************************
+ * Hardware Abstraction Layer
+ ******************************************************************************/
+
+
+#if defined ( __CC_ARM )
+ #define __ASM __asm /*!< asm keyword for ARM Compiler */
+ #define __INLINE __inline /*!< inline keyword for ARM Compiler */
+
+#elif defined ( __ICCARM__ )
+ #define __ASM __asm /*!< asm keyword for IAR Compiler */
+ #define __INLINE inline /*!< inline keyword for IAR Compiler. Only avaiable in High optimization mode! */
+
+#elif defined ( __GNUC__ )
+ #define __ASM __asm /*!< asm keyword for GNU Compiler */
+ #define __INLINE inline /*!< inline keyword for GNU Compiler */
+
+#elif defined ( __TASKING__ )
+ #define __ASM __asm /*!< asm keyword for TASKING Compiler */
+ #define __INLINE inline /*!< inline keyword for TASKING Compiler */
+
+#endif
+
+
+/* ################### Compiler specific Intrinsics ########################### */
+
+#if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/
+/* ARM armcc specific functions */
+
+#define __enable_fault_irq __enable_fiq
+#define __disable_fault_irq __disable_fiq
+
+#define __NOP __nop
+#define __WFI __wfi
+#define __WFE __wfe
+#define __SEV __sev
+#define __ISB() __isb(0)
+#define __DSB() __dsb(0)
+#define __DMB() __dmb(0)
+#define __REV __rev
+#define __RBIT __rbit
+#define __LDREXB(ptr) ((unsigned char ) __ldrex(ptr))
+#define __LDREXH(ptr) ((unsigned short) __ldrex(ptr))
+#define __LDREXW(ptr) ((unsigned int ) __ldrex(ptr))
+#define __STREXB(value, ptr) __strex(value, ptr)
+#define __STREXH(value, ptr) __strex(value, ptr)
+#define __STREXW(value, ptr) __strex(value, ptr)
+
+
+/* intrinsic unsigned long long __ldrexd(volatile void *ptr) */
+/* intrinsic int __strexd(unsigned long long val, volatile void *ptr) */
+/* intrinsic void __enable_irq(); */
+/* intrinsic void __disable_irq(); */
+
+
+/**
+ * @brief Return the Process Stack Pointer
+ *
+ * @param none
+ * @return uint32_t ProcessStackPointer
+ *
+ * Return the actual process stack pointer
+ */
+extern uint32_t __get_PSP(void);
+
+/**
+ * @brief Set the Process Stack Pointer
+ *
+ * @param uint32_t Process Stack Pointer
+ * @return none
+ *
+ * Assign the value ProcessStackPointer to the MSP
+ * (process stack pointer) Cortex processor register
+ */
+extern void __set_PSP(uint32_t topOfProcStack);
+
+/**
+ * @brief Return the Main Stack Pointer
+ *
+ * @param none
+ * @return uint32_t Main Stack Pointer
+ *
+ * Return the current value of the MSP (main stack pointer)
+ * Cortex processor register
+ */
+extern uint32_t __get_MSP(void);
+
+/**
+ * @brief Set the Main Stack Pointer
+ *
+ * @param uint32_t Main Stack Pointer
+ * @return none
+ *
+ * Assign the value mainStackPointer to the MSP
+ * (main stack pointer) Cortex processor register
+ */
+extern void __set_MSP(uint32_t topOfMainStack);
+
+/**
+ * @brief Reverse byte order in unsigned short value
+ *
+ * @param uint16_t value to reverse
+ * @return uint32_t reversed value
+ *
+ * Reverse byte order in unsigned short value
+ */
+extern uint32_t __REV16(uint16_t value);
+
+/*
+ * @brief Reverse byte order in signed short value with sign extension to integer
+ *
+ * @param int16_t value to reverse
+ * @return int32_t reversed value
+ *
+ * Reverse byte order in signed short value with sign extension to integer
+ */
+extern int32_t __REVSH(int16_t value);
+
+
+#if (__ARMCC_VERSION < 400000)
+
+/**
+ * @brief Remove the exclusive lock created by ldrex
+ *
+ * @param none
+ * @return none
+ *
+ * Removes the exclusive lock which is created by ldrex.
+ */
+extern void __CLREX(void);
+
+/**
+ * @brief Return the Base Priority value
+ *
+ * @param none
+ * @return uint32_t BasePriority
+ *
+ * Return the content of the base priority register
+ */
+extern uint32_t __get_BASEPRI(void);
+
+/**
+ * @brief Set the Base Priority value
+ *
+ * @param uint32_t BasePriority
+ * @return none
+ *
+ * Set the base priority register
+ */
+extern void __set_BASEPRI(uint32_t basePri);
+
+/**
+ * @brief Return the Priority Mask value
+ *
+ * @param none
+ * @return uint32_t PriMask
+ *
+ * Return the state of the priority mask bit from the priority mask
+ * register
+ */
+extern uint32_t __get_PRIMASK(void);
+
+/**
+ * @brief Set the Priority Mask value
+ *
+ * @param uint32_t PriMask
+ * @return none
+ *
+ * Set the priority mask bit in the priority mask register
+ */
+extern void __set_PRIMASK(uint32_t priMask);
+
+/**
+ * @brief Return the Fault Mask value
+ *
+ * @param none
+ * @return uint32_t FaultMask
+ *
+ * Return the content of the fault mask register
+ */
+extern uint32_t __get_FAULTMASK(void);
+
+/**
+ * @brief Set the Fault Mask value
+ *
+ * @param uint32_t faultMask value
+ * @return none
+ *
+ * Set the fault mask register
+ */
+extern void __set_FAULTMASK(uint32_t faultMask);
+
+/**
+ * @brief Return the Control Register value
+ *
+ * @param none
+ * @return uint32_t Control value
+ *
+ * Return the content of the control register
+ */
+extern uint32_t __get_CONTROL(void);
+
+/**
+ * @brief Set the Control Register value
+ *
+ * @param uint32_t Control value
+ * @return none
+ *
+ * Set the control register
+ */
+extern void __set_CONTROL(uint32_t control);
+
+#else /* (__ARMCC_VERSION >= 400000) */
+
+
+/**
+ * @brief Remove the exclusive lock created by ldrex
+ *
+ * @param none
+ * @return none
+ *
+ * Removes the exclusive lock which is created by ldrex.
+ */
+#define __CLREX __clrex
+
+/**
+ * @brief Return the Base Priority value
+ *
+ * @param none
+ * @return uint32_t BasePriority
+ *
+ * Return the content of the base priority register
+ */
+static __INLINE uint32_t __get_BASEPRI(void)
+{
+ register uint32_t __regBasePri __ASM("basepri");
+ return(__regBasePri);
+}
+
+/**
+ * @brief Set the Base Priority value
+ *
+ * @param uint32_t BasePriority
+ * @return none
+ *
+ * Set the base priority register
+ */
+static __INLINE void __set_BASEPRI(uint32_t basePri)
+{
+ register uint32_t __regBasePri __ASM("basepri");
+ __regBasePri = (basePri & 0x1ff);
+}
+
+/**
+ * @brief Return the Priority Mask value
+ *
+ * @param none
+ * @return uint32_t PriMask
+ *
+ * Return the state of the priority mask bit from the priority mask
+ * register
+ */
+static __INLINE uint32_t __get_PRIMASK(void)
+{
+ register uint32_t __regPriMask __ASM("primask");
+ return(__regPriMask);
+}
+
+/**
+ * @brief Set the Priority Mask value
+ *
+ * @param uint32_t PriMask
+ * @return none
+ *
+ * Set the priority mask bit in the priority mask register
+ */
+static __INLINE void __set_PRIMASK(uint32_t priMask)
+{
+ register uint32_t __regPriMask __ASM("primask");
+ __regPriMask = (priMask);
+}
+
+/**
+ * @brief Return the Fault Mask value
+ *
+ * @param none
+ * @return uint32_t FaultMask
+ *
+ * Return the content of the fault mask register
+ */
+static __INLINE uint32_t __get_FAULTMASK(void)
+{
+ register uint32_t __regFaultMask __ASM("faultmask");
+ return(__regFaultMask);
+}
+
+/**
+ * @brief Set the Fault Mask value
+ *
+ * @param uint32_t faultMask value
+ * @return none
+ *
+ * Set the fault mask register
+ */
+static __INLINE void __set_FAULTMASK(uint32_t faultMask)
+{
+ register uint32_t __regFaultMask __ASM("faultmask");
+ __regFaultMask = (faultMask & 1);
+}
+
+/**
+ * @brief Return the Control Register value
+ *
+ * @param none
+ * @return uint32_t Control value
+ *
+ * Return the content of the control register
+ */
+static __INLINE uint32_t __get_CONTROL(void)
+{
+ register uint32_t __regControl __ASM("control");
+ return(__regControl);
+}
+
+/**
+ * @brief Set the Control Register value
+ *
+ * @param uint32_t Control value
+ * @return none
+ *
+ * Set the control register
+ */
+static __INLINE void __set_CONTROL(uint32_t control)
+{
+ register uint32_t __regControl __ASM("control");
+ __regControl = control;
+}
+
+#endif /* __ARMCC_VERSION */
+
+
+
+#elif (defined (__ICCARM__)) /*------------------ ICC Compiler -------------------*/
+/* IAR iccarm specific functions */
+
+#define __enable_irq __enable_interrupt /*!< global Interrupt enable */
+#define __disable_irq __disable_interrupt /*!< global Interrupt disable */
+
+static __INLINE void __enable_fault_irq() { __ASM ("cpsie f"); }
+static __INLINE void __disable_fault_irq() { __ASM ("cpsid f"); }
+
+#define __NOP __no_operation() /*!< no operation intrinsic in IAR Compiler */
+static __INLINE void __WFI() { __ASM ("wfi"); }
+static __INLINE void __WFE() { __ASM ("wfe"); }
+static __INLINE void __SEV() { __ASM ("sev"); }
+static __INLINE void __CLREX() { __ASM ("clrex"); }
+
+/* intrinsic void __ISB(void) */
+/* intrinsic void __DSB(void) */
+/* intrinsic void __DMB(void) */
+/* intrinsic void __set_PRIMASK(); */
+/* intrinsic void __get_PRIMASK(); */
+/* intrinsic void __set_FAULTMASK(); */
+/* intrinsic void __get_FAULTMASK(); */
+/* intrinsic uint32_t __REV(uint32_t value); */
+/* intrinsic uint32_t __REVSH(uint32_t value); */
+/* intrinsic unsigned long __STREX(unsigned long, unsigned long); */
+/* intrinsic unsigned long __LDREX(unsigned long *); */
+
+
+/**
+ * @brief Return the Process Stack Pointer
+ *
+ * @param none
+ * @return uint32_t ProcessStackPointer
+ *
+ * Return the actual process stack pointer
+ */
+extern uint32_t __get_PSP(void);
+
+/**
+ * @brief Set the Process Stack Pointer
+ *
+ * @param uint32_t Process Stack Pointer
+ * @return none
+ *
+ * Assign the value ProcessStackPointer to the MSP
+ * (process stack pointer) Cortex processor register
+ */
+extern void __set_PSP(uint32_t topOfProcStack);
+
+/**
+ * @brief Return the Main Stack Pointer
+ *
+ * @param none
+ * @return uint32_t Main Stack Pointer
+ *
+ * Return the current value of the MSP (main stack pointer)
+ * Cortex processor register
+ */
+extern uint32_t __get_MSP(void);
+
+/**
+ * @brief Set the Main Stack Pointer
+ *
+ * @param uint32_t Main Stack Pointer
+ * @return none
+ *
+ * Assign the value mainStackPointer to the MSP
+ * (main stack pointer) Cortex processor register
+ */
+extern void __set_MSP(uint32_t topOfMainStack);
+
+/**
+ * @brief Reverse byte order in unsigned short value
+ *
+ * @param uint16_t value to reverse
+ * @return uint32_t reversed value
+ *
+ * Reverse byte order in unsigned short value
+ */
+extern uint32_t __REV16(uint16_t value);
+
+/**
+ * @brief Reverse bit order of value
+ *
+ * @param uint32_t value to reverse
+ * @return uint32_t reversed value
+ *
+ * Reverse bit order of value
+ */
+extern uint32_t __RBIT(uint32_t value);
+
+/**
+ * @brief LDR Exclusive
+ *
+ * @param uint8_t* address
+ * @return uint8_t value of (*address)
+ *
+ * Exclusive LDR command
+ */
+extern uint8_t __LDREXB(uint8_t *addr);
+
+/**
+ * @brief LDR Exclusive
+ *
+ * @param uint16_t* address
+ * @return uint16_t value of (*address)
+ *
+ * Exclusive LDR command
+ */
+extern uint16_t __LDREXH(uint16_t *addr);
+
+/**
+ * @brief LDR Exclusive
+ *
+ * @param uint32_t* address
+ * @return uint32_t value of (*address)
+ *
+ * Exclusive LDR command
+ */
+extern uint32_t __LDREXW(uint32_t *addr);
+
+/**
+ * @brief STR Exclusive
+ *
+ * @param uint8_t *address
+ * @param uint8_t value to store
+ * @return uint32_t successful / failed
+ *
+ * Exclusive STR command
+ */
+extern uint32_t __STREXB(uint8_t value, uint8_t *addr);
+
+/**
+ * @brief STR Exclusive
+ *
+ * @param uint16_t *address
+ * @param uint16_t value to store
+ * @return uint32_t successful / failed
+ *
+ * Exclusive STR command
+ */
+extern uint32_t __STREXH(uint16_t value, uint16_t *addr);
+
+/**
+ * @brief STR Exclusive
+ *
+ * @param uint32_t *address
+ * @param uint32_t value to store
+ * @return uint32_t successful / failed
+ *
+ * Exclusive STR command
+ */
+extern uint32_t __STREXW(uint32_t value, uint32_t *addr);
+
+
+
+#elif (defined (__GNUC__)) /*------------------ GNU Compiler ---------------------*/
+/* GNU gcc specific functions */
+
+static __INLINE void __enable_irq(void) { __ASM volatile ("cpsie i"); }
+static __INLINE void __disable_irq(void) { __ASM volatile ("cpsid i"); }
+
+static __INLINE void __enable_fault_irq(void) { __ASM volatile ("cpsie f"); }
+static __INLINE void __disable_fault_irq(void) { __ASM volatile ("cpsid f"); }
+
+static __INLINE void __NOP(void) { __ASM volatile ("nop"); }
+static __INLINE void __WFI(void) { __ASM volatile ("wfi"); }
+static __INLINE void __WFE(void) { __ASM volatile ("wfe"); }
+static __INLINE void __SEV(void) { __ASM volatile ("sev"); }
+static __INLINE void __ISB(void) { __ASM volatile ("isb"); }
+static __INLINE void __DSB(void) { __ASM volatile ("dsb"); }
+static __INLINE void __DMB(void) { __ASM volatile ("dmb"); }
+static __INLINE void __CLREX(void) { __ASM volatile ("clrex"); }
+
+
+/**
+ * @brief Return the Process Stack Pointer
+ *
+ * @param none
+ * @return uint32_t ProcessStackPointer
+ *
+ * Return the actual process stack pointer
+ */
+extern uint32_t __get_PSP(void);
+
+/**
+ * @brief Set the Process Stack Pointer
+ *
+ * @param uint32_t Process Stack Pointer
+ * @return none
+ *
+ * Assign the value ProcessStackPointer to the MSP
+ * (process stack pointer) Cortex processor register
+ */
+extern void __set_PSP(uint32_t topOfProcStack);
+
+/**
+ * @brief Return the Main Stack Pointer
+ *
+ * @param none
+ * @return uint32_t Main Stack Pointer
+ *
+ * Return the current value of the MSP (main stack pointer)
+ * Cortex processor register
+ */
+extern uint32_t __get_MSP(void);
+
+/**
+ * @brief Set the Main Stack Pointer
+ *
+ * @param uint32_t Main Stack Pointer
+ * @return none
+ *
+ * Assign the value mainStackPointer to the MSP
+ * (main stack pointer) Cortex processor register
+ */
+extern void __set_MSP(uint32_t topOfMainStack);
+
+/**
+ * @brief Return the Base Priority value
+ *
+ * @param none
+ * @return uint32_t BasePriority
+ *
+ * Return the content of the base priority register
+ */
+extern uint32_t __get_BASEPRI(void);
+
+/**
+ * @brief Set the Base Priority value
+ *
+ * @param uint32_t BasePriority
+ * @return none
+ *
+ * Set the base priority register
+ */
+extern void __set_BASEPRI(uint32_t basePri);
+
+/**
+ * @brief Return the Priority Mask value
+ *
+ * @param none
+ * @return uint32_t PriMask
+ *
+ * Return the state of the priority mask bit from the priority mask
+ * register
+ */
+extern uint32_t __get_PRIMASK(void);
+
+/**
+ * @brief Set the Priority Mask value
+ *
+ * @param uint32_t PriMask
+ * @return none
+ *
+ * Set the priority mask bit in the priority mask register
+ */
+extern void __set_PRIMASK(uint32_t priMask);
+
+/**
+ * @brief Return the Fault Mask value
+ *
+ * @param none
+ * @return uint32_t FaultMask
+ *
+ * Return the content of the fault mask register
+ */
+extern uint32_t __get_FAULTMASK(void);
+
+/**
+ * @brief Set the Fault Mask value
+ *
+ * @param uint32_t faultMask value
+ * @return none
+ *
+ * Set the fault mask register
+ */
+extern void __set_FAULTMASK(uint32_t faultMask);
+
+/**
+ * @brief Return the Control Register value
+*
+* @param none
+* @return uint32_t Control value
+ *
+ * Return the content of the control register
+ */
+extern uint32_t __get_CONTROL(void);
+
+/**
+ * @brief Set the Control Register value
+ *
+ * @param uint32_t Control value
+ * @return none
+ *
+ * Set the control register
+ */
+extern void __set_CONTROL(uint32_t control);
+
+/**
+ * @brief Reverse byte order in integer value
+ *
+ * @param uint32_t value to reverse
+ * @return uint32_t reversed value
+ *
+ * Reverse byte order in integer value
+ */
+extern uint32_t __REV(uint32_t value);
+
+/**
+ * @brief Reverse byte order in unsigned short value
+ *
+ * @param uint16_t value to reverse
+ * @return uint32_t reversed value
+ *
+ * Reverse byte order in unsigned short value
+ */
+extern uint32_t __REV16(uint16_t value);
+
+/*
+ * Reverse byte order in signed short value with sign extension to integer
+ *
+ * @param int16_t value to reverse
+ * @return int32_t reversed value
+ *
+ * @brief Reverse byte order in signed short value with sign extension to integer
+ */
+extern int32_t __REVSH(int16_t value);
+
+/**
+ * @brief Reverse bit order of value
+ *
+ * @param uint32_t value to reverse
+ * @return uint32_t reversed value
+ *
+ * Reverse bit order of value
+ */
+extern uint32_t __RBIT(uint32_t value);
+
+/**
+ * @brief LDR Exclusive
+ *
+ * @param uint8_t* address
+ * @return uint8_t value of (*address)
+ *
+ * Exclusive LDR command
+ */
+extern uint8_t __LDREXB(uint8_t *addr);
+
+/**
+ * @brief LDR Exclusive
+ *
+ * @param uint16_t* address
+ * @return uint16_t value of (*address)
+ *
+ * Exclusive LDR command
+ */
+extern uint16_t __LDREXH(uint16_t *addr);
+
+/**
+ * @brief LDR Exclusive
+ *
+ * @param uint32_t* address
+ * @return uint32_t value of (*address)
+ *
+ * Exclusive LDR command
+ */
+extern uint32_t __LDREXW(uint32_t *addr);
+
+/**
+ * @brief STR Exclusive
+ *
+ * @param uint8_t *address
+ * @param uint8_t value to store
+ * @return uint32_t successful / failed
+ *
+ * Exclusive STR command
+ */
+extern uint32_t __STREXB(uint8_t value, uint8_t *addr);
+
+/**
+ * @brief STR Exclusive
+ *
+ * @param uint16_t *address
+ * @param uint16_t value to store
+ * @return uint32_t successful / failed
+ *
+ * Exclusive STR command
+ */
+extern uint32_t __STREXH(uint16_t value, uint16_t *addr);
+
+/**
+ * @brief STR Exclusive
+ *
+ * @param uint32_t *address
+ * @param uint32_t value to store
+ * @return uint32_t successful / failed
+ *
+ * Exclusive STR command
+ */
+extern uint32_t __STREXW(uint32_t value, uint32_t *addr);
+
+
+#elif (defined (__TASKING__)) /*------------------ TASKING Compiler ---------------------*/
+/* TASKING carm specific functions */
+
+/*
+ * The CMSIS functions have been implemented as intrinsics in the compiler.
+ * Please use "carm -?i" to get an up to date list of all instrinsics,
+ * Including the CMSIS ones.
+ */
+
+#endif
+
+
+
+/* ########################## NVIC functions #################################### */
+
+
+/**
+ * @brief Set the Priority Grouping in NVIC Interrupt Controller
+ *
+ * @param uint32_t priority_grouping is priority grouping field
+ * @return none
+ *
+ * Set the priority grouping field using the required unlock sequence.
+ * The parameter priority_grouping is assigned to the field
+ * SCB->AIRCR [10:8] PRIGROUP field. Only values from 0..7 are used.
+ * In case of a conflict between priority grouping and available
+ * priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set.
+ */
+static __INLINE void NVIC_SetPriorityGrouping(uint32_t PriorityGroup)
+{
+ uint32_t reg_value;
+ uint32_t PriorityGroupTmp = (PriorityGroup & 0x07); /* only values 0..7 are used */
+
+ reg_value = SCB->AIRCR; /* read old register configuration */
+ reg_value &= ~((0xFFFFU << 16) | (0x0F << 8)); /* clear bits to change */
+ reg_value = ((reg_value | NVIC_AIRCR_VECTKEY | (PriorityGroupTmp << 8))); /* Insert write key and priorty group */
+ SCB->AIRCR = reg_value;
+}
+
+/**
+ * @brief Get the Priority Grouping from NVIC Interrupt Controller
+ *
+ * @param none
+ * @return uint32_t priority grouping field
+ *
+ * Get the priority grouping from NVIC Interrupt Controller.
+ * priority grouping is SCB->AIRCR [10:8] PRIGROUP field.
+ */
+static __INLINE uint32_t NVIC_GetPriorityGrouping(void)
+{
+ return ((SCB->AIRCR >> 8) & 0x07); /* read priority grouping field */
+}
+
+/**
+ * @brief Enable Interrupt in NVIC Interrupt Controller
+ *
+ * @param IRQn_Type IRQn specifies the interrupt number
+ * @return none
+ *
+ * Enable a device specific interupt in the NVIC interrupt controller.
+ * The interrupt number cannot be a negative value.
+ */
+static __INLINE void NVIC_EnableIRQ(IRQn_Type IRQn)
+{
+ NVIC->ISER[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* enable interrupt */
+}
+
+/**
+ * @brief Disable the interrupt line for external interrupt specified
+ *
+ * @param IRQn_Type IRQn is the positive number of the external interrupt
+ * @return none
+ *
+ * Disable a device specific interupt in the NVIC interrupt controller.
+ * The interrupt number cannot be a negative value.
+ */
+static __INLINE void NVIC_DisableIRQ(IRQn_Type IRQn)
+{
+ NVIC->ICER[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* disable interrupt */
+}
+
+/**
+ * @brief Read the interrupt pending bit for a device specific interrupt source
+ *
+ * @param IRQn_Type IRQn is the number of the device specifc interrupt
+ * @return uint32_t 1 if pending interrupt else 0
+ *
+ * Read the pending register in NVIC and return 1 if its status is pending,
+ * otherwise it returns 0
+ */
+static __INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn)
+{
+ return((uint32_t) ((NVIC->ISPR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); /* Return 1 if pending else 0 */
+}
+
+/**
+ * @brief Set the pending bit for an external interrupt
+ *
+ * @param IRQn_Type IRQn is the Number of the interrupt
+ * @return none
+ *
+ * Set the pending bit for the specified interrupt.
+ * The interrupt number cannot be a negative value.
+ */
+static __INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn)
+{
+ NVIC->ISPR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* set interrupt pending */
+}
+
+/**
+ * @brief Clear the pending bit for an external interrupt
+ *
+ * @param IRQn_Type IRQn is the Number of the interrupt
+ * @return none
+ *
+ * Clear the pending bit for the specified interrupt.
+ * The interrupt number cannot be a negative value.
+ */
+static __INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn)
+{
+ NVIC->ICPR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* Clear pending interrupt */
+}
+
+/**
+ * @brief Read the active bit for an external interrupt
+ *
+ * @param IRQn_Type IRQn is the Number of the interrupt
+ * @return uint32_t 1 if active else 0
+ *
+ * Read the active register in NVIC and returns 1 if its status is active,
+ * otherwise it returns 0.
+ */
+static __INLINE uint32_t NVIC_GetActive(IRQn_Type IRQn)
+{
+ return((uint32_t)((NVIC->IABR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); /* Return 1 if active else 0 */
+}
+
+/**
+ * @brief Set the priority for an interrupt
+ *
+ * @param IRQn_Type IRQn is the Number of the interrupt
+ * @param priority is the priority for the interrupt
+ * @return none
+ *
+ * Set the priority for the specified interrupt. The interrupt
+ * number can be positive to specify an external (device specific)
+ * interrupt, or negative to specify an internal (core) interrupt. \n
+ *
+ * Note: The priority cannot be set for every core interrupt.
+ */
+static __INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
+{
+ if(IRQn < 0) {
+ SCB->SHP[((uint32_t)(IRQn) & 0xF)-4] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff); } /* set Priority for Cortex-M3 System Interrupts */
+ else {
+ NVIC->IP[(uint32_t)(IRQn)] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff); } /* set Priority for device specific Interrupts */
+}
+
+/**
+ * @brief Read the priority for an interrupt
+ *
+ * @param IRQn_Type IRQn is the Number of the interrupt
+ * @return uint32_t priority is the priority for the interrupt
+ *
+ * Read the priority for the specified interrupt. The interrupt
+ * number can be positive to specify an external (device specific)
+ * interrupt, or negative to specify an internal (core) interrupt.
+ *
+ * The returned priority value is automatically aligned to the implemented
+ * priority bits of the microcontroller.
+ *
+ * Note: The priority cannot be set for every core interrupt.
+ */
+static __INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn)
+{
+
+ if(IRQn < 0) {
+ return((uint32_t)(SCB->SHP[((uint32_t)(IRQn) & 0xF)-4] >> (8 - __NVIC_PRIO_BITS))); } /* get priority for Cortex-M3 system interrupts */
+ else {
+ return((uint32_t)(NVIC->IP[(uint32_t)(IRQn)] >> (8 - __NVIC_PRIO_BITS))); } /* get priority for device specific interrupts */
+}
+
+
+/**
+ * @brief Encode the priority for an interrupt
+ *
+ * @param uint32_t PriorityGroup is the used priority group
+ * @param uint32_t PreemptPriority is the preemptive priority value (starting from 0)
+ * @param uint32_t SubPriority is the sub priority value (starting from 0)
+ * @return uint32_t the priority for the interrupt
+ *
+ * Encode the priority for an interrupt with the given priority group,
+ * preemptive priority value and sub priority value.
+ * In case of a conflict between priority grouping and available
+ * priority bits (__NVIC_PRIO_BITS) the samllest possible priority group is set.
+ *
+ * The returned priority value can be used for NVIC_SetPriority(...) function
+ */
+static __INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority)
+{
+ uint32_t PriorityGroupTmp = (PriorityGroup & 0x07); /* only values 0..7 are used */
+ uint32_t PreemptPriorityBits;
+ uint32_t SubPriorityBits;
+
+ PreemptPriorityBits = ((7 - PriorityGroupTmp) > __NVIC_PRIO_BITS) ? __NVIC_PRIO_BITS : 7 - PriorityGroupTmp;
+ SubPriorityBits = ((PriorityGroupTmp + __NVIC_PRIO_BITS) < 7) ? 0 : PriorityGroupTmp - 7 + __NVIC_PRIO_BITS;
+
+ return (
+ ((PreemptPriority & ((1 << (PreemptPriorityBits)) - 1)) << SubPriorityBits) |
+ ((SubPriority & ((1 << (SubPriorityBits )) - 1)))
+ );
+}
+
+
+/**
+ * @brief Decode the priority of an interrupt
+ *
+ * @param uint32_t Priority the priority for the interrupt
+ * @param uint32_t PrioGroup is the used priority group
+ * @param uint32_t* pPreemptPrio is the preemptive priority value (starting from 0)
+ * @param uint32_t* pSubPrio is the sub priority value (starting from 0)
+ * @return none
+ *
+ * Decode an interrupt priority value with the given priority group to
+ * preemptive priority value and sub priority value.
+ * In case of a conflict between priority grouping and available
+ * priority bits (__NVIC_PRIO_BITS) the samllest possible priority group is set.
+ *
+ * The priority value can be retrieved with NVIC_GetPriority(...) function
+ */
+static __INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* pPreemptPriority, uint32_t* pSubPriority)
+{
+ uint32_t PriorityGroupTmp = (PriorityGroup & 0x07); /* only values 0..7 are used */
+ uint32_t PreemptPriorityBits;
+ uint32_t SubPriorityBits;
+
+ PreemptPriorityBits = ((7 - PriorityGroupTmp) > __NVIC_PRIO_BITS) ? __NVIC_PRIO_BITS : 7 - PriorityGroupTmp;
+ SubPriorityBits = ((PriorityGroupTmp + __NVIC_PRIO_BITS) < 7) ? 0 : PriorityGroupTmp - 7 + __NVIC_PRIO_BITS;
+
+ *pPreemptPriority = (Priority >> SubPriorityBits) & ((1 << (PreemptPriorityBits)) - 1);
+ *pSubPriority = (Priority ) & ((1 << (SubPriorityBits )) - 1);
+}
+
+
+
+/* ################################## SysTick function ############################################ */
+
+#if (!defined (__Vendor_SysTickConfig)) || (__Vendor_SysTickConfig == 0)
+
+/* SysTick constants */
+#define SYSTICK_ENABLE 0 /* Config-Bit to start or stop the SysTick Timer */
+#define SYSTICK_TICKINT 1 /* Config-Bit to enable or disable the SysTick interrupt */
+#define SYSTICK_CLKSOURCE 2 /* Clocksource has the offset 2 in SysTick Control and Status Register */
+#define SYSTICK_MAXCOUNT ((1<<24) -1) /* SysTick MaxCount */
+
+/**
+ * @brief Initialize and start the SysTick counter and its interrupt.
+ *
+ * @param uint32_t ticks is the number of ticks between two interrupts
+ * @return none
+ *
+ * Initialise the system tick timer and its interrupt and start the
+ * system tick timer / counter in free running mode to generate
+ * periodical interrupts.
+ */
+static __INLINE uint32_t SysTick_Config(uint32_t ticks)
+{
+ if (ticks > SYSTICK_MAXCOUNT) return (1); /* Reload value impossible */
+
+ SysTick->LOAD = (ticks & SYSTICK_MAXCOUNT) - 1; /* set reload register */
+ NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1); /* set Priority for Cortex-M0 System Interrupts */
+ SysTick->VAL = (0x00); /* Load the SysTick Counter Value */
+ SysTick->CTRL = (1 << SYSTICK_CLKSOURCE) | (1<<SYSTICK_ENABLE) | (1<<SYSTICK_TICKINT); /* Enable SysTick IRQ and SysTick Timer */
+ return (0); /* Function successful */
+}
+
+#endif
+
+
+
+
+
+/* ################################## Reset function ############################################ */
+
+/**
+ * @brief Initiate a system reset request.
+ *
+ * @param none
+ * @return none
+ *
+ * Initialize a system reset request to reset the MCU
+ */
+static __INLINE void NVIC_SystemReset(void)
+{
+ SCB->AIRCR = (NVIC_AIRCR_VECTKEY | (SCB->AIRCR & (0x700)) | (1<<NVIC_SYSRESETREQ)); /* Keep priority group unchanged */
+ __DSB(); /* Ensure completion of memory access */
+ while(1); /* wait until reset */
+}
+
+
+/* ################################## Debug Output function ############################################ */
+
+
+/**
+ * @brief Outputs a character via the ITM channel 0
+ *
+ * @param uint32_t character to output
+ * @return uint32_t input character
+ *
+ * The function outputs a character via the ITM channel 0.
+ * The function returns when no debugger is connected that has booked the output.
+ * It is blocking when a debugger is connected, but the previous character send is not transmitted.
+ */
+static __INLINE uint32_t ITM_SendChar (uint32_t ch)
+{
+ if (ch == '\n') ITM_SendChar('\r');
+
+ if ((CoreDebug->DEMCR & CoreDebug_DEMCR_TRCENA) &&
+ (ITM->TCR & ITM_TCR_ITMENA) &&
+ (ITM->TER & (1UL << 0)) )
+ {
+ while (ITM->PORT[0].u32 == 0);
+ ITM->PORT[0].u8 = (uint8_t) ch;
+ }
+ return (ch);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __CM3_CORE_H__ */
+
+/*lint -restore */
diff --git a/os/ports/GCC/ARMCM3/crt0.s b/os/ports/GCC/ARMCM3/crt0.s
new file mode 100644
index 000000000..0c2ab5ab6
--- /dev/null
+++ b/os/ports/GCC/ARMCM3/crt0.s
@@ -0,0 +1,128 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT 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 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT 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, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file ports/ARMCM3/crt0.s
+ * @brief Generic ARM Cortex-M3 startup file for ChibiOS/RT.
+ * @addtogroup ARMCM3_CORE
+ * @{
+ */
+/** @cond never */
+
+.set CONTROL_MODE_PRIVILEGED, 0
+.set CONTROL_MODE_UNPRIVILEGED, 1
+.set CONTROL_USE_MSP, 0
+.set CONTROL_USE_PSP, 2
+
+.text
+.balign 2
+.syntax unified
+.thumb
+
+/*
+ * Reset handler.
+ */
+.thumb_func
+.global ResetHandler
+.weak ResetHandler
+ResetHandler:
+ /* Interrupts globally masked. */
+ cpsid i
+ /*
+ * Stack pointers initialization.
+ */
+ ldr r0, =__ram_end__
+ ldr r1, =__main_stack_size__
+ sub r0, r0, r1
+ /* { r0 = main stack low address } */
+ msr PSP, r0
+ /* Early initialization. */
+ bl hwinit0
+ /*
+ * Data initialization.
+ * NOTE: It assumes that the DATA size is a multiple of 4.
+ */
+ ldr r1, =_textdata
+ ldr r2, =_data
+ ldr r3, =_edata
+dloop:
+ cmp r2, r3
+ ittt lo
+ ldrlo r0, [r1], #4
+ strlo r0, [r2], #4
+ blo dloop
+ /*
+ * BSS initialization.
+ * NOTE: It assumes that the BSS size is a multiple of 4.
+ */
+ movs r0, #0
+ ldr r1, =_bss_start
+ ldr r2, =_bss_end
+bloop:
+ cmp r1, r2
+ itt lo
+ strlo r0, [r1], #4
+ blo bloop
+ /* Switches to the Process Stack. */
+ movs r0, #CONTROL_MODE_PRIVILEGED | CONTROL_USE_PSP
+ msr CONTROL, r0
+ isb
+ /* Late initialization. */
+ bl hwinit1
+ movs r0, #0
+ mov r1, r0
+ bl main
+ b MainExitHandler
+
+/*
+ * Default main exit code, just a loop.
+ * It is a weak symbol, the application code can redefine the behavior.
+ */
+.thumb_func
+.global MainExitHandler
+.weak MainExitHandler
+MainExitHandler:
+.loop: b .loop
+
+/*
+ * Default early initialization code. It is declared weak in order to be
+ * replaced by the real initialization code.
+ * Early initialization is performed just after reset before BSS and DATA
+ * segments initialization.
+ */
+.thumb_func
+.global hwinit0
+.weak hwinit0
+hwinit0:
+ bx lr
+
+/*
+ * Default late initialization code. It is declared weak in order to be
+ * replaced by the real initialization code.
+ * Late initialization is performed after BSS and DATA segments initialization
+ * and before invoking the main() function.
+ */
+.thumb_func
+.global hwinit1
+.weak hwinit1
+hwinit1:
+ bx lr
+
+/** @endcond */
+/** @} */
diff --git a/os/ports/GCC/ARMCM3/nvic.c b/os/ports/GCC/ARMCM3/nvic.c
new file mode 100644
index 000000000..4a11cbb39
--- /dev/null
+++ b/os/ports/GCC/ARMCM3/nvic.c
@@ -0,0 +1,57 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT 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 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT 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, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file ports/ARMCM3/nvic.c
+ * @brief Cortex-M3 NVIC support code.
+ * @addtogroup ARMCM3_NVIC
+ * @{
+ */
+
+#include <ch.h>
+#include <nvic.h>
+
+/**
+ * @brief Sets the priority of an interrupt handler and enables it.
+ *
+ * @param n the interrupt number
+ * @param prio the interrupt priority
+ * @note The parameters are not tested for correctness.
+ */
+void NVICEnableVector(uint32_t n, uint32_t prio) {
+ unsigned sh = (n & 3) << 3;
+
+ NVIC_IPR(n >> 2) = (NVIC_IPR(n >> 2) & ~(0xFF << sh)) | (prio << sh);
+ NVIC_ISER(n >> 5) = 1 << (n & 0x1F);
+}
+
+/**
+ * @brief Changes the priority of a system handler.
+ *
+ * @param handler the system handler number
+ * @param prio the system handler priority
+ * @note The parameters are not tested for correctness.
+ */
+void NVICSetSystemHandlerPriority(uint32_t handler, uint32_t prio) {
+ unsigned sh = (handler & 3) * 8;
+
+ SCB_SHPR(handler >> 2) = (SCB_SHPR(handler >> 2) & ~(0xFF << sh)) | (prio << sh);
+}
+
+/** @} */
diff --git a/os/ports/GCC/ARMCM3/nvic.h b/os/ports/GCC/ARMCM3/nvic.h
new file mode 100644
index 000000000..9d2b79606
--- /dev/null
+++ b/os/ports/GCC/ARMCM3/nvic.h
@@ -0,0 +1,190 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT 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 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT 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, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file ports/ARMCM3/nvic.h
+ * @brief Cortex-M3 NVIC support macros and structures.
+ * @addtogroup ARMCM3_NVIC
+ * @{
+ */
+
+#ifndef _NVIC_H_
+#define _NVIC_H_
+
+/*
+ * System vector constants for @p NVICSetSystemHandlerPriority().
+ */
+#define HANDLER_MEM_MANAGE 0 /**< MEM MANAGE vector id.*/
+#define HANDLER_BUS_FAULT 1 /**< BUS FAULT vector id.*/
+#define HANDLER_USAGE_FAULT 2 /**< USAGE FAULT vector id.*/
+#define HANDLER_RESERVED_3 3
+#define HANDLER_RESERVED_4 4
+#define HANDLER_RESERVED_5 5
+#define HANDLER_RESERVED_6 6
+#define HANDLER_SVCALL 7 /**< SVCALL vector id.*/
+#define HANDLER_DEBUG_MONITOR 8 /**< DEBUG MONITOR vector id.*/
+#define HANDLER_RESERVED_9 9
+#define HANDLER_PENDSV 10 /**< PENDSV vector id.*/
+#define HANDLER_SYSTICK 11 /**< SYS TCK vector id.*/
+
+typedef volatile unsigned char IOREG8; /**< 8 bits I/O register type.*/
+typedef volatile unsigned int IOREG32; /**< 32 bits I/O register type.*/
+
+/**
+ * @brief NVIC ITCR register.
+ */
+#define NVIC_ITCR (*((IOREG32 *)0xE000E004))
+
+/**
+ * @brief NVIC STIR register.
+ */
+#define NVIC_STIR (*((IOREG32 *)0xE000EF00))
+
+/**
+ * @brief Structure representing the SYSTICK I/O space.
+ */
+typedef struct {
+ IOREG32 CSR;
+ IOREG32 RVR;
+ IOREG32 CVR;
+ IOREG32 CBVR;
+} CM3_ST;
+
+/**
+ * @brief SYSTICK peripheral base address.
+ */
+#define STBase ((CM3_ST *)0xE000E010)
+#define ST_CSR (STBase->CSR)
+#define ST_RVR (STBase->RVR)
+#define ST_CVR (STBase->CVR)
+#define ST_CBVR (STBase->CBVR)
+
+#define CSR_ENABLE_MASK (0x1 << 0)
+#define ENABLE_OFF_BITS (0 << 0)
+#define ENABLE_ON_BITS (1 << 0)
+#define CSR_TICKINT_MASK (0x1 << 1)
+#define TICKINT_DISABLED_BITS (0 << 1)
+#define TICKINT_ENABLED_BITS (1 << 1)
+#define CSR_CLKSOURCE_MASK (0x1 << 2)
+#define CLKSOURCE_EXT_BITS (0 << 2)
+#define CLKSOURCE_CORE_BITS (1 << 2)
+#define CSR_COUNTFLAG_MASK (0x1 << 16)
+
+#define RVR_RELOAD_MASK (0xFFFFFF << 0)
+
+#define CVR_CURRENT_MASK (0xFFFFFF << 0)
+
+#define CBVR_TENMS_MASK (0xFFFFFF << 0)
+#define CBVR_SKEW_MASK (0x1 << 30)
+#define CBVR_NOREF_MASK (0x1 << 31)
+
+/**
+ * @brief Structure representing the NVIC I/O space.
+ */
+typedef struct {
+ IOREG32 ISER[8];
+ IOREG32 unused1[24];
+ IOREG32 ICER[8];
+ IOREG32 unused2[24];
+ IOREG32 ISPR[8];
+ IOREG32 unused3[24];
+ IOREG32 ICPR[8];
+ IOREG32 unused4[24];
+ IOREG32 IABR[8];
+ IOREG32 unused5[56];
+ IOREG32 IPR[60];
+} CM3_NVIC;
+
+/**
+ * @brief NVIC peripheral base address.
+ */
+#define NVICBase ((CM3_NVIC *)0xE000E100)
+#define NVIC_ISER(n) (NVICBase->ISER[n])
+#define NVIC_ICER(n) (NVICBase->ICER[n])
+#define NVIC_ISPR(n) (NVICBase->ISPR[n])
+#define NVIC_ICPR(n) (NVICBase->ICPR[n])
+#define NVIC_IABR(n) (NVICBase->IABR[n])
+#define NVIC_IPR(n) (NVICBase->IPR[n])
+
+/**
+ * @brief Structure representing the System Control Block I/O space.
+ */
+typedef struct {
+ IOREG32 CPUID;
+ IOREG32 ICSR;
+ IOREG32 VTOR;
+ IOREG32 AIRCR;
+ IOREG32 SCR;
+ IOREG32 CCR;
+ IOREG32 SHPR[3];
+ IOREG32 SHCSR;
+ IOREG32 CFSR;
+ IOREG32 HFSR;
+ IOREG32 DFSR;
+ IOREG32 MMFAR;
+ IOREG32 BFAR;
+ IOREG32 AFSR;
+} CM3_SCB;
+
+/**
+ * @brief SCB peripheral base address.
+ */
+#define SCBBase ((CM3_SCB *)0xE000ED00)
+#define SCB_CPUID (SCBBase->CPUID)
+#define SCB_ICSR (SCBBase->ICSR)
+#define SCB_VTOR (SCBBase->VTOR)
+#define SCB_AIRCR (SCBBase->AIRCR)
+#define SCB_SCR (SCBBase->SCR)
+#define SCB_CCR (SCBBase->CCR)
+#define SCB_SHPR(n) (SCBBase->SHPR[n])
+#define SCB_SHCSR (SCBBase->SHCSR)
+#define SCB_CFSR (SCBBase->CFSR)
+#define SCB_HFSR (SCBBase->HFSR)
+#define SCB_DFSR (SCBBase->DFSR)
+#define SCB_MMFAR (SCBBase->MMFAR)
+#define SCB_BFAR (SCBBase->BFAR)
+#define SCB_AFSR (SCBBase->AFSR)
+
+#define ICSR_VECTACTIVE_MASK (0x1FF << 0)
+#define ICSR_RETTOBASE (0x1 << 11)
+#define ICSR_VECTPENDING_MASK (0x1FF << 12)
+#define ICSR_ISRPENDING (0x1 << 22)
+#define ICSR_ISRPREEMPT (0x1 << 23)
+#define ICSR_PENDSTCLR (0x1 << 25)
+#define ICSR_PENDSTSET (0x1 << 26)
+#define ICSR_PENDSVCLR (0x1 << 27)
+#define ICSR_PENDSVSET (0x1 << 28)
+#define ICSR_NMIPENDSET (0x1 << 31)
+
+#define AIRCR_VECTKEY 0x05FA0000
+#define AIRCR_PRIGROUP_MASK (0x7 << 8)
+#define AIRCR_PRIGROUP(n) ((n) << 8)
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void NVICEnableVector(uint32_t n, uint32_t prio);
+ void NVICSetSystemHandlerPriority(uint32_t handler, uint32_t prio);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _NVIC_H_ */
+
+/** @} */
diff --git a/os/ports/GCC/ARMCM3/port.dox b/os/ports/GCC/ARMCM3/port.dox
new file mode 100644
index 000000000..db44ab9c5
--- /dev/null
+++ b/os/ports/GCC/ARMCM3/port.dox
@@ -0,0 +1,170 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT 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 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT 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, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @defgroup ARMCM3 ARM Cortex-M3
+ * @details The ARM Cortex-M3 architecture is quite complex for a
+ * microcontroller and some explanations are required about the port choices.
+ *
+ * @section ARMCM3_STATES Mapping of the System States in the ARM Cortex-M3 port
+ * The ChibiOS/RT logical @ref system_states are mapped as follow in the ARM
+ * Cortex-M3 port:
+ * - <b>Init</b>. This state is represented by the startup code and the
+ * initialization code before @p chSysInit() is executed. It has not a
+ * special hardware state associated.
+ * - <b>Normal</b>. This is the state the system has after executing
+ * @p chSysInit(). In this state the ARM Cortex-M3 has the BASEPRI register
+ * set at @p BASEPRI_USER level, interrupts are not masked. The processor
+ * is running in thread-privileged mode.
+ * - <b>Suspended</b>. In this state the interrupt sources are not globally
+ * masked but the BASEPRI register is set to @p BASEPRI_KERNEL thus masking
+ * any interrupt source with lower or equal priority. The processor
+ * is running in thread-privileged mode.
+ * - <b>Disabled</b>. Interrupt sources are globally masked. The processor
+ * is running in thread-privileged mode.
+ * - <b>Sleep</b>. This state is entered with the execution of the specific
+ * instruction @p <b>wfi</b>.
+ * - <b>S-Locked</b>. In this state the interrupt sources are not globally
+ * masked but the BASEPRI register is set to @p BASEPRI_KERNEL thus masking
+ * any interrupt source with lower or equal priority. The processor
+ * is running in thread-privileged mode.
+ * - <b>I-Locked</b>. In this state the interrupt sources are not globally
+ * masked but the BASEPRI register is set to @p BASEPRI_KERNEL thus masking
+ * any interrupt source with lower or equal priority. The processor
+ * is running in exception-privileged mode.
+ * - <b>Serving Regular Interrupt</b>. In this state the interrupt sources are
+ * not globally masked but only interrupts with higher priority can preempt
+ * the current handler. The processor is running in exception-privileged mode.
+ * - <b>Serving Fast Interrupt</b>. It is basically the same of the SRI state
+ * but it is not possible to switch to the I-Locked state because fast
+ * interrupts can preempt the kernel critical zone.
+ * - <b>Serving Non-Maskable Interrupt</b>. The Cortex-M3 has a specific
+ * asynchronous NMI vector and several synchronous fault vectors that can
+ * be considered to be in this category.
+ * - <b>Halted</b>. Implemented as an infinite loop after globally masking all
+ * the maskable interrupt sources. The ARM state is whatever the processor
+ * was running when @p chSysHalt() was invoked.
+ * .
+ * @section ARMCM3_NOTES The ARM Cortex-M3 port notes
+ * The ARM Cortex-M3 port is organized as follow:
+ * - The @p main() function is invoked in thread-privileged mode.
+ * - Each thread has a private process stack, the system has a single main
+ * stack where all the interrupts and exceptions are processed.
+ * - Only the 4 MSb of the priority level are used, the 4 LSb are assumed
+ * to be zero.
+ * - The threads are started in thread-privileged mode with BASEPRI level
+ * 0x00 (disabled).
+ * - The kernel raises its BASEPRI level to @p BASEPRI_KERNEL in order to
+ * protect the kernel data structures.
+ * - Interrupt nesting and the other advanced NVIC features are supported.
+ * - The SVC instruction and vector, with parameter #0, is internally used
+ * for commanded context switching.<br>
+ * It is possible to share the SVC handler at the cost of slower context
+ * switching.
+ * - The PendSV vector is internally used for preemption context switching.
+ * .
+ * @ingroup Ports
+ */
+
+/**
+ * @defgroup ARMCM3_CONF Configuration Options
+ * @brief ARM Cortex-M3 Configuration Options.
+ * @details The ARMCM3 port allows some architecture-specific configurations
+ * settings that can be specified externally, as example on the compiler
+ * command line:
+ * - @p INT_REQUIRED_STACK, this value represent the amount of stack space used
+ * by an interrupt handler between the @p extctx and @p intctx
+ * structures.<br>
+ * In the current implementation this value is guaranteed to be zero so
+ * there is no need to modify this value unless changes are done at the
+ * interrupts handling code.
+ * - @p BASEPRI_USER, this is the @p BASEPRI value for the user threads. The
+ * default value is @p 0 (disabled).<br>
+ * Usually there is no need to change this value, please refer to the
+ * Cortex-M3 technical reference manual for a detailed description.
+ * - @p BASEPRI_KERNEL, this is the @p BASEPRI value for the kernel lock code.
+ * The default value is 0x40.<br>
+ * Code running at higher priority levels must not invoke any OS API.<br>
+ * Usually there is no need to change this value, please refer to the
+ * Cortex-M3 technical reference manual for a detailed description.
+ * - @p ENABLE_WFI_IDLE, if set to @p 1 enables the use of the @p <b>wfi</b>
+ * instruction from within the idle loop. This is defaulted to 0 because
+ * it can create problems with some debuggers. Setting this option to 1
+ * reduces the system power requirements.
+ * .
+ * @ingroup ARMCM3
+ */
+
+/**
+ * @defgroup ARMCM3_CORE Core Port Implementation
+ * @brief ARM Cortex-M3 specific port code, structures and macros.
+ *
+ * @ingroup ARMCM3
+ */
+
+/**
+ * @defgroup ARMCM3_STARTUP Startup Support
+ * @brief ARM Cortex-M3 startup code support.
+ * @details ChibiOS/RT provides its own generic startup file for the ARM
+ * Cortex-M3 port.
+ * Of course it is not mandatory to use it but care should be taken about the
+ * startup phase details.
+ *
+ * <h2>Startup Process</h2>
+ * The startup process, as implemented, is the following:
+ * -# Interrupts are masked globally.
+ * -# The two stacks are initialized by assigning them the sizes defined in the
+ * linker script (usually named @p ch.ld). Stack areas are allocated from
+ * the highest RAM location downward.
+ * -# An early initialization routine @p hwinit0 is invoked, if the symbol is
+ * not defined then an empty default routine is executed (weak symbol).
+ * -# DATA and BSS segments are initialized.
+ * -# The CPU state is switched to Privileged and the PSP stack is used.
+ * -# A late initialization routine @p hwinit1 is invoked, if the symbol not
+ * defined then an empty default routine is executed (weak symbol).<br>
+ * This late initialization function is also the proper place for a
+ * @a bootloader, if your application requires one.
+ * -# The @p main() function is invoked with the parameters @p argc and @p argv
+ * set to zero.
+ * -# Should the @p main() function return a branch is performed to the weak
+ * symbol MainExitHandler. The default code is an endless empty loop.
+ * .
+ * <h2>Expected linker symbols</h2>
+ * The startup code starts at the symbol @p ResetHandler and expects the
+ * following symbols to be defined in the linker script:
+ * - @p __ram_end__ RAM end location +1.
+ * - @p __main_stack_size__ Exception stack size.
+ * - @p __process_stack_size__ Process stack size. This is the stack area used
+ * by the @p main() function.
+ * - @p _textdata address of the data segment source read only data.
+ * - @p _data data segment start location.
+ * - @p _edata data segment end location +1.
+ * - @p _bss_start BSS start location.
+ * - @p _bss_end BSS end location +1.
+ * .
+ * @ingroup ARMCM3
+ * @file ports/ARMCM3/crt0.s Startup code.
+ */
+
+/**
+ * @defgroup ARMCM3_NVIC NVIC Support
+ * @brief ARM Cortex-M3 NVIC support.
+ *
+ * @ingroup ARMCM3
+ */
diff --git a/os/ports/GCC/ARMCM3/port.mk b/os/ports/GCC/ARMCM3/port.mk
new file mode 100644
index 000000000..8afb815ef
--- /dev/null
+++ b/os/ports/GCC/ARMCM3/port.mk
@@ -0,0 +1,9 @@
+# List of the ChibiOS/RT Cortex-M3 port files.
+PORTSRC = ../../os/ports/GCC/ARMCM3/chcore.c \
+ ../../os/ports/GCC/ARMCM3/nvic.c \
+ ../../os/ports/GCC/ARMCM3/cmsis/core_cm3.c
+
+PORTASM = ../../os/ports/GCC/ARMCM3/crt0.s
+
+PORTINC = ../../os/ports/GCC/ARMCM3 \
+ ../../os/ports/GCC/ARMCM3/cmsis
diff --git a/os/ports/GCC/AVR/avr_serial.c b/os/ports/GCC/AVR/avr_serial.c
new file mode 100644
index 000000000..b69a43213
--- /dev/null
+++ b/os/ports/GCC/AVR/avr_serial.c
@@ -0,0 +1,185 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT 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 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT 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, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file ports/AVR/avr_serial.c
+ * @brief AVR Serial driver code.
+ * @addtogroup AVR_SERIAL
+ * @{
+ */
+
+#include <ch.h>
+
+#include "avr_serial.h"
+
+static void SetError(uint8_t sra, FullDuplexDriver *com) {
+ dflags_t sts = 0;
+
+ if (sra & (1 << DOR))
+ sts |= SD_OVERRUN_ERROR;
+ if (sra & (1 << UPE))
+ sts |= SD_PARITY_ERROR;
+ if (sra & (1 << FE))
+ sts |= SD_FRAMING_ERROR;
+ chSysLockFromIsr();
+ chFDDAddFlagsI(com, sts);
+ chSysUnlockFromIsr();
+}
+
+#if USE_AVR_USART0 || defined(__DOXYGEN__)
+/** @brief USART0 serial driver identifier.*/
+FullDuplexDriver SER1;
+
+static uint8_t ib1[SERIAL_BUFFERS_SIZE];
+static uint8_t ob1[SERIAL_BUFFERS_SIZE];
+
+CH_IRQ_HANDLER(USART0_RX_vect) {
+ uint8_t sra;
+
+ CH_IRQ_PROLOGUE();
+
+ sra = UCSR0A;
+ if (sra & ((1 << DOR) | (1 << UPE) | (1 << FE)))
+ SetError(sra, &SER1);
+ chSysLockFromIsr();
+ chFDDIncomingDataI(&SER1, UDR0);
+ chSysUnlockFromIsr();
+
+ CH_IRQ_EPILOGUE();
+}
+
+CH_IRQ_HANDLER(USART0_UDRE_vect) {
+ msg_t b;
+
+ CH_IRQ_PROLOGUE();
+
+ chSysLockFromIsr();
+ b = chFDDRequestDataI(&SER1);
+ chSysUnlockFromIsr();
+ if (b < Q_OK)
+ UCSR0B &= ~(1 << UDRIE);
+ else
+ UDR0 = b;
+
+ CH_IRQ_EPILOGUE();
+}
+
+static void OutNotify1(void) {
+
+ UCSR0B |= (1 << UDRIE);
+}
+
+/**
+ * @brief USART0 setup.
+ * @details This function must be invoked with interrupts disabled.
+ * @param[in] brr the divider value as calculated by the @p UBRR() macro
+ * @param[in] csrc the value for the @p UCSR0C register
+ * @note Must be invoked with interrupts disabled.
+ * @note Does not reset the I/O queues.
+ */
+void usart0_setup(uint16_t brr, uint8_t csrc) {
+
+ UBRR0L = brr;
+ UBRR0H = brr >> 8;
+ UCSR0A = 0;
+ UCSR0B = (1 << RXEN) | (1 << TXEN) | (1 << RXCIE);
+ UCSR0C = csrc;
+}
+#endif /* USE_AVR_USART0 */
+
+#if USE_AVR_USART1 || defined(__DOXYGEN__)
+/** @brief USART1 serial driver identifier.*/
+FullDuplexDriver SER2;
+
+static uint8_t ib2[SERIAL_BUFFERS_SIZE];
+static uint8_t ob2[SERIAL_BUFFERS_SIZE];
+
+CH_IRQ_HANDLER(USART1_RX_vect) {
+ uint8_t sra;
+
+ CH_IRQ_PROLOGUE();
+
+ sra = UCSR1A;
+ if (sra & ((1 << DOR) | (1 << UPE) | (1 << FE)))
+ SetError(sra, &SER2);
+ chSysLockFromIsr();
+ chFDDIncomingDataI(&SER2, UDR1);
+ chSysUnlockFromIsr();
+
+ CH_IRQ_EPILOGUE();
+}
+
+CH_IRQ_HANDLER(USART1_UDRE_vect) {
+ msg_t b;
+
+ CH_IRQ_PROLOGUE();
+
+ chSysLockFromIsr();
+ b = chFDDRequestDataI(&SER2);
+ chSysUnlockFromIsr();
+ if (b < Q_OK)
+ UCSR1B &= ~(1 << UDRIE);
+ else
+ UDR1 = b;
+
+ CH_IRQ_EPILOGUE();
+}
+
+static void OutNotify2(void) {
+
+ UCSR1B |= (1 << UDRIE);
+}
+
+/**
+ * @brief USART1 setup.
+ * @details This function must be invoked with interrupts disabled.
+ * @param[in] brr the divider value as calculated by the @p UBRR() macro
+ * @param[in] csrc the value for the @p UCSR1C register
+ * @note Must be invoked with interrupts disabled.
+ * @note Does not reset the I/O queues.
+ */
+void usart1_setup(uint16_t brr, uint8_t csrc) {
+
+ UBRR1L = brr;
+ UBRR1H = brr >> 8;
+ UCSR1A = 0;
+ UCSR1B = (1 << RXEN) | (1 << TXEN) | (1 << RXCIE);
+ UCSR1C = csrc;
+}
+#endif /* USE_AVR_USART1 */
+
+/**
+ * @brief Serial driver initialization.
+ * @note The serial ports are initialized at @p 38400-8-N-1 by default.
+ */
+void serial_init(void) {
+
+#if USE_AVR_USART0
+ /* I/O queues setup.*/
+ chFDDInit(&SER1, ib1, sizeof ib1, NULL, ob1, sizeof ob1, OutNotify1);
+ usart0_setup(UBRR(DEFAULT_USART_BITRATE), (1 << UCSZ1) | (1 << UCSZ0));
+#endif
+
+#if USE_AVR_USART1
+ chFDDInit(&SER2, ib2, sizeof ib2, NULL, ob2, sizeof ob2, OutNotify2);
+ usart1_setup(UBRR(DEFAULT_USART_BITRATE), (1 << UCSZ1) | (1 << UCSZ0));
+#endif
+}
+
+/** @} */
diff --git a/os/ports/GCC/AVR/avr_serial.h b/os/ports/GCC/AVR/avr_serial.h
new file mode 100644
index 000000000..f97f16e65
--- /dev/null
+++ b/os/ports/GCC/AVR/avr_serial.h
@@ -0,0 +1,92 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT 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 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT 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, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file ports/AVR/avr_serial.h
+ * @brief AVR Serial driver macros and structures.
+ * @addtogroup AVR_SERIAL
+ * @{
+ */
+
+#ifndef _AVR_SERIAL_H_
+#define _AVR_SERIAL_H_
+
+/**
+ * @brief Serial buffers size.
+ * @details Configuration parameter, you can change the depth of the queue
+ * buffers depending on the requirements of your application.
+ * @note The default is 32 bytes for both the transmission and receive buffers.
+ */
+#if !defined(SERIAL_BUFFERS_SIZE) || defined(__DOXYGEN__)
+#define SERIAL_BUFFERS_SIZE 32
+#endif
+
+/**
+ * @brief Default bit rate.
+ * @details Configuration parameter, at startup the UARTs are configured at
+ * this speed.
+ * @note It is possible to use @p SetUART() in order to change the working
+ * parameters at runtime.
+ */
+#if !defined(DEFAULT_USART_BITRATE) || defined(__DOXYGEN__)
+#define DEFAULT_USART_BITRATE 38400
+#endif
+
+
+/**
+ * @brief USART0 driver enable switch.
+ * @details If set to @p TRUE the support for USART0 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(USE_AVR_USART0) || defined(__DOXYGEN__)
+#define USE_AVR_USART0 FALSE
+#endif
+
+/**
+ * @brief USART1 driver enable switch.
+ * @details If set to @p TRUE the support for USART1 is included.
+ * @note The default is @p TRUE.
+ */
+#if !defined(USE_AVR_USART1) || defined(__DOXYGEN__)
+#define USE_AVR_USART1 TRUE
+#endif
+
+/**
+ * @brief Macro for baud rate computation.
+ * @note Make sure the final baud rate is within tolerance.
+ */
+#define UBRR(b) ((F_CPU / (b << 4)) - 1)
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void serial_init(void);
+ void usart0_setup(uint16_t brr, uint8_t csrc);
+ void usart1_setup(uint16_t brr, uint8_t csrc);
+#ifdef __cplusplus
+}
+#endif
+
+/** @cond never*/
+extern FullDuplexDriver SER1, SER2;
+/** @endcond*/
+
+#endif /* _AVR_SERIAL_H_ */
+
+/** @} */
diff --git a/os/ports/GCC/AVR/chcore.c b/os/ports/GCC/AVR/chcore.c
new file mode 100644
index 000000000..7d39d12c3
--- /dev/null
+++ b/os/ports/GCC/AVR/chcore.c
@@ -0,0 +1,125 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT 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 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT 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, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file ports/AVR/chcore.c
+ * @brief AVR architecture port code.
+ * @addtogroup AVR_CORE
+ * @{
+ */
+
+#include <ch.h>
+
+/**
+ * Performs a context switch between two threads.
+ * @param otp the thread to be switched out
+ * @param ntp the thread to be switched in
+ * @note The function is declared as a weak symbol, it is possible to redefine
+ * it in your application code.
+ */
+/** @cond never */
+__attribute__((naked, weak))
+/** @endcond */
+void port_switch(Thread *otp, Thread *ntp) {
+
+ asm volatile ("push r2");
+ asm volatile ("push r3");
+ asm volatile ("push r4");
+ asm volatile ("push r5");
+ asm volatile ("push r6");
+ asm volatile ("push r7");
+#ifndef CH_CURRP_REGISTER_CACHE
+ asm volatile ("push r8");
+ asm volatile ("push r9");
+#endif
+ asm volatile ("push r10");
+ asm volatile ("push r11");
+ asm volatile ("push r12");
+ asm volatile ("push r13");
+ asm volatile ("push r14");
+ asm volatile ("push r15");
+ asm volatile ("push r16");
+ asm volatile ("push r17");
+ asm volatile ("push r28");
+ asm volatile ("push r29");
+
+ asm volatile ("movw r30, r24");
+ asm volatile ("in r0, 0x3d");
+ asm volatile ("std Z+7, r0");
+ asm volatile ("in r0, 0x3e");
+ asm volatile ("std Z+8, r0");
+
+ asm volatile ("movw r30, r22");
+ asm volatile ("ldd r0, Z+7");
+ asm volatile ("out 0x3d, r0");
+ asm volatile ("ldd r0, Z+8");
+ asm volatile ("out 0x3e, r0");
+
+ asm volatile ("pop r29");
+ asm volatile ("pop r28");
+ asm volatile ("pop r17");
+ asm volatile ("pop r16");
+ asm volatile ("pop r15");
+ asm volatile ("pop r14");
+ asm volatile ("pop r13");
+ asm volatile ("pop r12");
+ asm volatile ("pop r11");
+ asm volatile ("pop r10");
+#ifndef CH_CURRP_REGISTER_CACHE
+ asm volatile ("pop r9");
+ asm volatile ("pop r8");
+#endif
+ asm volatile ("pop r7");
+ asm volatile ("pop r6");
+ asm volatile ("pop r5");
+ asm volatile ("pop r4");
+ asm volatile ("pop r3");
+ asm volatile ("pop r2");
+ asm volatile ("ret");
+}
+
+/**
+ * Disables the interrupts and halts the system.
+ * @note The function is declared as a weak symbol, it is possible to redefine
+ * it in your application code.
+ */
+/** @cond never */
+__attribute__((weak))
+/** @endcond */
+void port_halt(void) {
+
+ port_disable();
+ while (TRUE) {
+ }
+}
+
+/**
+ * Start a thread by invoking its work function.
+ * If the work function returns @p chThdExit() is automatically invoked.
+ */
+void threadstart(void) {
+
+ asm volatile ("sei");
+ asm volatile ("movw r24, r4");
+ asm volatile ("movw r30, r2");
+ asm volatile ("icall");
+ asm volatile ("call chThdExit");
+}
+
+/** @} */
diff --git a/os/ports/GCC/AVR/chcore.h b/os/ports/GCC/AVR/chcore.h
new file mode 100644
index 000000000..c70c5307e
--- /dev/null
+++ b/os/ports/GCC/AVR/chcore.h
@@ -0,0 +1,267 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT 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 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT 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, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file ports/AVR/chcore.h
+ * @brief AVR architecture port macros and structures.
+ * @addtogroup AVR_CORE
+ * @{
+ */
+
+#ifndef _CHCORE_H_
+#define _CHCORE_H_
+
+#include <avr/io.h>
+#include <avr/interrupt.h>
+
+/**
+ * If enabled allows the idle thread to enter a low power mode.
+ */
+#ifndef ENABLE_WFI_IDLE
+#define ENABLE_WFI_IDLE 0
+#endif
+
+/**
+ * Macro defining the AVR architecture.
+ */
+#define CH_ARCHITECTURE_AVR
+
+/**
+ * Name of the implemented architecture.
+ */
+#define CH_ARCHITECTURE_NAME "AVR"
+
+/**
+ * 8 bit stack alignment.
+ */
+typedef uint8_t stkalign_t;
+
+/** @cond never */
+/**
+ * Interrupt saved context.
+ * @note The field @p _next is not part of the context, it represents the
+ * offset of the structure relative to the stack pointer.
+ */
+struct extctx {
+ uint8_t _next;
+ uint8_t r31;
+ uint8_t r30;
+ uint8_t r27;
+ uint8_t r26;
+ uint8_t r25;
+ uint8_t r24;
+ uint8_t r23;
+ uint8_t r22;
+ uint8_t r21;
+ uint8_t r20;
+ uint8_t r19;
+ uint8_t r18;
+ uint8_t sr;
+ uint8_t r1;
+ uint8_t r0;
+ uint16_t pc;
+};
+/** @endcond */
+
+/** @cond never */
+/**
+ * System saved context.
+ * @note The field @p _next is not part of the context, it represents the
+ * offset of the structure relative to the stack pointer.
+ */
+struct intctx {
+ uint8_t _next;
+ uint8_t r29;
+ uint8_t r28;
+ uint8_t r17;
+ uint8_t r16;
+ uint8_t r15;
+ uint8_t r14;
+ uint8_t r13;
+ uint8_t r12;
+ uint8_t r11;
+ uint8_t r10;
+#ifndef CH_CURRP_REGISTER_CACHE
+ uint8_t r9;
+ uint8_t r8;
+#endif
+ uint8_t r7;
+ uint8_t r6;
+ uint8_t r5;
+ uint8_t r4;
+ uint8_t r3;
+ uint8_t r2;
+ uint8_t pcl;
+ uint8_t pch;
+};
+/** @endcond */
+
+/** @cond never */
+/**
+ * In the AVR port this structure just holds a pointer to the @p intctx
+ * structure representing the stack pointer at the time of the context switch.
+ */
+struct context {
+ struct intctx *sp;
+};
+/** @endcond */
+
+/**
+ * Platform dependent part of the @p chThdInit() API.
+ * This code usually setup the context switching frame represented by a
+ * @p intctx structure.
+ */
+#define SETUP_CONTEXT(workspace, wsize, pf, arg) { \
+ tp->p_ctx.sp = (struct intctx*)((uint8_t *)workspace + wsize - \
+ sizeof(struct intctx)); \
+ tp->p_ctx.sp->r2 = (int)pf; \
+ tp->p_ctx.sp->r3 = (int)pf >> 8; \
+ tp->p_ctx.sp->r4 = (int)arg; \
+ tp->p_ctx.sp->r5 = (int)arg >> 8; \
+ tp->p_ctx.sp->pcl = (int)threadstart >> 8; \
+ tp->p_ctx.sp->pch = (int)threadstart; \
+}
+
+/**
+ * The default idle thread implementation requires no extra stack space in
+ * this port.
+ */
+#ifndef IDLE_THREAD_STACK_SIZE
+#define IDLE_THREAD_STACK_SIZE 8
+#endif
+
+/**
+ * Per-thread stack overhead for interrupts servicing, it is used in the
+ * calculation of the correct working area size. In this port the default is
+ * 32 bytes per thread.
+ */
+#ifndef INT_REQUIRED_STACK
+#define INT_REQUIRED_STACK 32
+#endif
+
+/**
+ * Enforces a correct alignment for a stack area size value.
+ */
+#define STACK_ALIGN(n) ((((n) - 1) | (sizeof(stkalign_t) - 1)) + 1)
+
+/**
+ * Computes the thread working area global size.
+ */
+#define THD_WA_SIZE(n) STACK_ALIGN(sizeof(Thread) + \
+ (sizeof(struct intctx) - 1) + \
+ (sizeof(struct extctx) - 1) + \
+ (n) + (INT_REQUIRED_STACK))
+
+/**
+ * Macro used to allocate a thread working area aligned as both position and
+ * size.
+ */
+#define WORKING_AREA(s, n) stkalign_t s[THD_WA_SIZE(n) / sizeof(stkalign_t)];
+
+/**
+ * IRQ prologue code, inserted at the start of all IRQ handlers enabled to
+ * invoke system APIs.
+ * This code tricks the compiler to save all the specified registers by
+ * "touching" them.
+ */
+#define PORT_IRQ_PROLOGUE() { \
+ asm ("" : : : "r18", "r19", "r20", "r21", "r22", "r23", "r24", \
+ "r25", "r26", "r27", "r30", "r31"); \
+}
+
+/**
+ * IRQ epilogue code, inserted at the end of all IRQ handlers enabled to
+ * invoke system APIs.
+ */
+#define PORT_IRQ_EPILOGUE() { \
+ if (chSchRescRequiredI()) \
+ chSchDoRescheduleI(); \
+}
+
+/**
+ * IRQ handler function declaration. Note, it just aliases the WinAVR "ISR"
+ * macro.
+ */
+#define PORT_IRQ_HANDLER(id) ISR(id)
+
+/**
+ * This function is empty in this port.
+ */
+#define port_init()
+
+/**
+ * Implemented as global interrupt disable.
+ */
+#define port_lock() asm volatile ("cli")
+
+/**
+ * Implemented as global interrupt enable.
+ */
+#define port_unlock() asm volatile ("sei")
+
+/**
+ * This function is empty in this port.
+ */
+#define port_lock_from_isr()
+
+/**
+ * This function is empty in this port.
+ */
+#define port_unlock_from_isr()
+
+/**
+ * Implemented as global interrupt disable.
+ */
+#define port_disable() asm volatile ("cli")
+
+/**
+ * Same as @p port_disable() in this port, there is no difference between the
+ * two states.
+ */
+#define port_suspend() asm volatile ("cli")
+
+/**
+ * Implemented as global interrupt enable.
+ */
+#define port_enable() asm volatile ("sei")
+
+/**
+ * This port function is implemented as inlined code for performance reasons.
+ */
+#if ENABLE_WFI_IDLE != 0
+#define port_wait_for_interrupt() { \
+ asm volatile ("sleep"); \
+}
+#else
+#define port_wait_for_interrupt()
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void port_switch(Thread *otp, Thread *ntp);
+ void port_halt(void);
+ void threadstart(void);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _CHCORE_H_ */
+
+/** @} */
diff --git a/os/ports/GCC/AVR/chtypes.h b/os/ports/GCC/AVR/chtypes.h
new file mode 100644
index 000000000..e5920746c
--- /dev/null
+++ b/os/ports/GCC/AVR/chtypes.h
@@ -0,0 +1,56 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT 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 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT 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, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file ports/AVR/chtypes.h
+ * @brief AVR architecture port system types.
+ * @addtogroup AVR_CORE
+ * @{
+ */
+
+#ifndef _CHTYPES_H_
+#define _CHTYPES_H_
+
+#define __need_NULL
+#define __need_size_t
+#define __need_ptrdiff_t
+#include <stddef.h>
+
+#if !defined(_STDINT_H) && !defined(__STDINT_H_)
+#include <stdint.h>
+#endif
+
+typedef int8_t bool_t; /**< Fast boolean type. */
+typedef uint8_t tmode_t; /**< Thread flags. */
+typedef uint8_t tstate_t; /**< Thread state. */
+typedef uint8_t tprio_t; /**< Thread priority. */
+typedef int16_t msg_t; /**< Inter-thread message. */
+typedef uint8_t eventid_t; /**< Event Id. */
+typedef uint8_t eventmask_t; /**< Events mask. */
+typedef uint16_t systime_t; /**< System time. */
+typedef int8_t cnt_t; /**< Resources counter. */
+
+#define INLINE inline
+#define PACK_STRUCT_STRUCT __attribute__((packed))
+#define PACK_STRUCT_BEGIN
+#define PACK_STRUCT_END
+
+#endif /* _CHTYPES_H_ */
+
+/** @} */
diff --git a/os/ports/GCC/AVR/port.dox b/os/ports/GCC/AVR/port.dox
new file mode 100644
index 000000000..5343037b1
--- /dev/null
+++ b/os/ports/GCC/AVR/port.dox
@@ -0,0 +1,95 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT 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 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT 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, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @defgroup AVR MegaAVR
+ * @details AVR port details. This section how the ChibiOS/RT features are
+ * implemented on this architecture.
+ *
+ * @section AVR_STATES Mapping of the System States in the AVR port
+ * The ChibiOS/RT logical @ref system_states are mapped as follow in the AVR
+ * port:
+ * - <b>Init</b>. This state is represented by the startup code and the
+ * initialization code before @p chSysInit() is executed. It has not a
+ * special hardware state associated.
+ * - <b>Normal</b>. This is the state the system has after executing
+ * @p chSysInit(). Interrupts are enabled.
+ * - <b>Suspended</b>. Interrupts are disabled.
+ * - <b>Disabled</b>. Interrupts are enabled. This state is equivalent to the
+ * Suspended state because there are no fast interrupts in this architecture.
+ * - <b>Sleep</b>. This state is entered with the execution of the specific
+ * instruction @p <b>sleep</b>.
+ * - <b>S-Locked</b>. Interrupts are disabled.
+ * - <b>I-Locked</b>. This state is equivalent to the SRI state, the
+ * @p chSysLockI() and @p chSysUnlockI() APIs do nothing (still use them in
+ * order to formally change state because this may change).
+ * - <b>Serving Regular Interrupt</b>. Normal interrupt service code.
+ * - <b>Serving Fast Interrupt</b>. Not present in this architecture.
+ * - <b>Serving Non-Maskable Interrupt</b>. Not present in this architecture.
+ * - <b>Halted</b>. Implemented as an infinite loop with interrupts disabled.
+ * .
+ * @section AVR_NOTES The AVR port notes
+ * - The AVR does not have a dedicated interrupt stack, make sure to reserve
+ * enough stack space for interrupts in each thread stack. This can be done
+ * by modifying the @p INT_REQUIRED_STACK macro into
+ * <b>./ports/AVR/chcore.h</b>.
+ * .
+ * @ingroup Ports
+ */
+
+/**
+ * @defgroup AVR_CONF Configuration Options
+ * @brief AVR Configuration Options.
+ * @details The AVR port allows some architecture-specific configurations
+ * settingsthat can be specified externally, as example on the compiler
+ * command line:
+ * - @p INT_REQUIRED_STACK, this value represent the amount of stack space
+ * used by the interrupt handlers.<br>
+ * The default for this value is @p 32, this space is allocated for each
+ * thread so be careful in order to not waste precious RAM space.<br>
+ * The default value is set into <b>./ports/AVR/chcore.h</b>.
+ * .
+ * @ingroup AVR
+ */
+
+/**
+ * @defgroup AVR_CORE AVR Core Implementation
+ * @brief AVR specific port code, structures and macros.
+ *
+ * @ingroup AVR
+ * @file ports/AVR/chtypes.h Port types.
+ * @file ports/AVR/chcore.h Port related structures and macros.
+ * @file ports/AVR/chcore.c Port related code.
+ */
+
+/**
+ * @defgroup AVR_DRIVERS AVR Drivers
+ * @brief Device drivers included in the AVR support.
+ *
+ * @ingroup AVR
+ */
+
+/**
+ * @defgroup AVR_SERIAL USART Support
+ * @brief USART support.
+ * @details The serial driver supports both the AVR USARTs in asynchronous
+ * mode.
+ *
+ * @ingroup AVR_DRIVERS
+ */
diff --git a/os/ports/GCC/AVR/port.mk b/os/ports/GCC/AVR/port.mk
new file mode 100644
index 000000000..63f6fa1a5
--- /dev/null
+++ b/os/ports/GCC/AVR/port.mk
@@ -0,0 +1,6 @@
+# List of the ChibiOS/RT Cortex-M3 port files.
+PORTSRC = ../../os/ports/GCC/AVR/chcore.c
+
+PORTASM =
+
+PORTINC = ../../os/ports/GCC/AVR
diff --git a/os/ports/GCC/MSP430/chcore.c b/os/ports/GCC/MSP430/chcore.c
new file mode 100644
index 000000000..45d52726a
--- /dev/null
+++ b/os/ports/GCC/MSP430/chcore.c
@@ -0,0 +1,90 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT 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 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT 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, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file ports/MSP430/chcore.c
+ * @brief MSP430 architecture port code.
+ * @addtogroup MSP430_CORE
+ * @{
+ */
+
+#include <ch.h>
+
+/**
+ * Performs a context switch between two threads.
+ * @param otp the thread to be switched out
+ * @param ntp the thread to be switched in
+ * @note The function is declared as a weak symbol, it is possible to redefine
+ * it in your application code.
+ */
+/** @cond never */
+__attribute__((naked, weak))
+/** @endcond */
+void port_switch(Thread *otp, Thread *ntp) {
+ register struct intctx *sp asm("r1");
+
+ asm volatile ("push r11 \n\t" \
+ "push r10 \n\t" \
+ "push r9 \n\t" \
+ "push r8 \n\t" \
+ "push r7 \n\t" \
+ "push r6 \n\t" \
+ "push r6 \n\t" \
+ "push r4");
+ otp->p_ctx.sp = sp;
+ sp = ntp->p_ctx.sp;
+ asm volatile ("pop r4 \n\t" \
+ "pop r5 \n\t" \
+ "pop r6 \n\t" \
+ "pop r7 \n\t" \
+ "pop r8 \n\t" \
+ "pop r9 \n\t" \
+ "pop r10 \n\t" \
+ "pop r11 \n\t" \
+ "ret" : : "r" (sp));
+}
+
+/**
+ * Disables the interrupts and halts the system.
+ * @note The function is declared as a weak symbol, it is possible to redefine
+ * it in your application code.
+ */
+/** @cond never */
+__attribute__((weak))
+/** @endcond */
+void port_halt(void) {
+
+ port_disable();
+ while (TRUE) {
+ }
+}
+
+/**
+ * Start a thread by invoking its work function.
+ * If the work function returns @p chThdExit() is automatically invoked.
+ */
+void threadstart(void) {
+
+ asm volatile ("eint \n\t" \
+ "mov r11, r15 \n\t" \
+ "call r10 \n\t" \
+ "call #chThdExit");
+}
+
+/** @} */
diff --git a/os/ports/GCC/MSP430/chcore.h b/os/ports/GCC/MSP430/chcore.h
new file mode 100644
index 000000000..313108cde
--- /dev/null
+++ b/os/ports/GCC/MSP430/chcore.h
@@ -0,0 +1,238 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT 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 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT 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, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file ports/MSP430/chcore.h
+ * @brief MSP430 architecture port macros and structures.
+ * @addtogroup MSP430_CORE
+ * @{
+ */
+
+#ifndef _CHCORE_H_
+#define _CHCORE_H_
+
+#include <iomacros.h>
+#include <msp430/common.h>
+
+/**
+ * If enabled allows the idle thread to enter a low power mode.
+ */
+#ifndef ENABLE_WFI_IDLE
+#define ENABLE_WFI_IDLE 0
+#endif
+
+/**
+ * Macro defining the MSP430 architecture.
+ */
+#define CH_ARCHITECTURE_MSP430
+
+/**
+ * Name of the implemented architecture.
+ */
+#define CH_ARCHITECTURE_NAME "MSP430"
+
+/**
+ * 16 bit stack alignment.
+ */
+typedef uint16_t stkalign_t;
+
+/**
+ * Generic MSP430 register.
+ */
+typedef void *regmsp_t;
+
+/** @cond never */
+/**
+ * Interrupt saved context.
+ */
+struct extctx {
+ regmsp_t r12;
+ regmsp_t r13;
+ regmsp_t r14;
+ regmsp_t r15;
+ regmsp_t sr;
+ regmsp_t pc;
+};
+/** @endcond */
+
+/** @cond never */
+/**
+ * This structure represents the inner stack frame during a context switching.
+ */
+struct intctx {
+ regmsp_t r4;
+ regmsp_t r5;
+ regmsp_t r6;
+ regmsp_t r7;
+ regmsp_t r8;
+ regmsp_t r9;
+ regmsp_t r10;
+ regmsp_t r11;
+ regmsp_t pc;
+};
+/** @endcond */
+
+/** @cond never */
+/**
+ * In the MSP430 port this structure just holds a pointer to the @p intctx
+ * structure representing the stack pointer at the time of the context switch.
+ */
+struct context {
+ struct intctx *sp;
+};
+/** @endcond */
+
+/**
+ * Platform dependent part of the @p chThdInit() API.
+ */
+#define SETUP_CONTEXT(workspace, wsize, pf, arg) { \
+ tp->p_ctx.sp = (struct intctx *)((uint8_t *)workspace + \
+ wsize - \
+ sizeof(struct intctx)); \
+ tp->p_ctx.sp->r10 = pf; \
+ tp->p_ctx.sp->r11 = arg; \
+ tp->p_ctx.sp->pc = threadstart; \
+}
+
+/**
+ * The default idle thread implementation requires no extra stack space in
+ * this port.
+ */
+#ifndef IDLE_THREAD_STACK_SIZE
+#define IDLE_THREAD_STACK_SIZE 0
+#endif
+
+/**
+ * Per-thread stack overhead for interrupts servicing, it is used in the
+ * calculation of the correct working area size. In this port the default is
+ * 32 bytes per thread.
+ */
+#ifndef INT_REQUIRED_STACK
+#define INT_REQUIRED_STACK 32
+#endif
+
+/**
+ * Enforces a correct alignment for a stack area size value.
+ */
+#define STACK_ALIGN(n) ((((n) - 1) | (sizeof(stkalign_t) - 1)) + 1)
+
+/**
+ * Computes the thread working area global size.
+ */
+#define THD_WA_SIZE(n) STACK_ALIGN(sizeof(Thread) + \
+ sizeof(struct intctx) + \
+ sizeof(struct extctx) + \
+ (n) + (INT_REQUIRED_STACK))
+
+/**
+ * Macro used to allocate a thread working area aligned as both position and
+ * size.
+ */
+#define WORKING_AREA(s, n) stkalign_t s[THD_WA_SIZE(n) / sizeof(stkalign_t)];
+
+/**
+ * IRQ prologue code, inserted at the start of all IRQ handlers enabled to
+ * invoke system APIs.
+ */
+#define PORT_IRQ_PROLOGUE()
+
+/**
+ * IRQ epilogue code, inserted at the end of all IRQ handlers enabled to
+ * invoke system APIs.
+ */
+#define PORT_IRQ_EPILOGUE() { \
+ if (chSchRescRequiredI()) \
+ chSchDoRescheduleI(); \
+}
+
+/**
+ * IRQ handler function modifier.
+ */
+#define PORT_IRQ_HANDLER(id) interrupt(id) _vect_##id(void)
+
+/**
+ * This function is empty in this port.
+ */
+#define port_init()
+
+/**
+ * Implemented as global interrupt disable.
+ */
+#define port_lock() asm volatile ("dint")
+
+/**
+ * Implemented as global interrupt enable.
+ */
+#define port_unlock() asm volatile ("eint")
+
+/**
+ * This function is empty in this port.
+ */
+#define port_lock_from_isr()
+
+/**
+ * This function is empty in this port.
+ */
+#define port_unlock_from_isr()
+
+/**
+ * Implemented as global interrupt disable.
+ */
+#define port_disable() asm volatile ("dint")
+
+/**
+ * Same as @p port_disable() in this port, there is no difference between the
+ * two states.
+ */
+#define port_suspend() asm volatile ("dint")
+
+/**
+ * Implemented as global interrupt enable.
+ */
+#define port_enable() asm volatile ("eint")
+
+/**
+ * This port function is implemented as inlined code for performance reasons.
+ * @note The port code does not define a low power mode, this macro has to be
+ * defined externally. The default implementation is a "nop", not a
+ * real low power mode.
+ */
+#if ENABLE_WFI_IDLE != 0
+#ifndef port_wait_for_interrupt
+#define port_wait_for_interrupt() { \
+ asm volatile ("nop"); \
+}
+#endif
+#else
+#define port_wait_for_interrupt()
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void port_switch(Thread *otp, Thread *ntp);
+ void port_halt(void);
+ void threadstart(void);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _CHCORE_H_ */
+
+/** @} */
diff --git a/os/ports/GCC/MSP430/chtypes.h b/os/ports/GCC/MSP430/chtypes.h
new file mode 100644
index 000000000..f8d7c944a
--- /dev/null
+++ b/os/ports/GCC/MSP430/chtypes.h
@@ -0,0 +1,56 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT 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 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT 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, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file ports/MSP430/chtypes.h
+ * @brief MSP430 architecture port system types.
+ * @addtogroup MSP430_CORE
+ * @{
+ */
+
+#ifndef _CHTYPES_H_
+#define _CHTYPES_H_
+
+#define __need_NULL
+#define __need_size_t
+#define __need_ptrdiff_t
+#include <stddef.h>
+
+#if !defined(_STDINT_H) && !defined(__STDINT_H_)
+#include <stdint.h>
+#endif
+
+typedef int16_t bool_t; /**< Fast boolean type. */
+typedef uint8_t tmode_t; /**< Thread flags. */
+typedef uint8_t tstate_t; /**< Thread state. */
+typedef uint16_t tprio_t; /**< Thread priority. */
+typedef int16_t msg_t; /**< Inter-thread message. */
+typedef int16_t eventid_t; /**< Event Id. */
+typedef uint16_t eventmask_t; /**< Events mask. */
+typedef uint16_t systime_t; /**< System time. */
+typedef int16_t cnt_t; /**< Resources counter. */
+
+#define INLINE inline
+#define PACK_STRUCT_STRUCT __attribute__((packed))
+#define PACK_STRUCT_BEGIN
+#define PACK_STRUCT_END
+
+#endif /* _CHTYPES_H_ */
+
+/** @} */
diff --git a/os/ports/GCC/MSP430/msp430_serial.c b/os/ports/GCC/MSP430/msp430_serial.c
new file mode 100644
index 000000000..69351b19d
--- /dev/null
+++ b/os/ports/GCC/MSP430/msp430_serial.c
@@ -0,0 +1,216 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT 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 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT 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, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file ports/MSP430/msp430_serial.c
+ * @brief MSP430 Serial driver code.
+ * @addtogroup MSP430_SERIAL
+ * @{
+ */
+
+#include <ch.h>
+#include <signal.h>
+
+#include "board.h"
+#include "msp430_serial.h"
+
+static void SetError(uint8_t urctl, FullDuplexDriver *com) {
+ dflags_t sts = 0;
+
+ if (urctl & OE)
+ sts |= SD_OVERRUN_ERROR;
+ if (urctl & PE)
+ sts |= SD_PARITY_ERROR;
+ if (urctl & FE)
+ sts |= SD_FRAMING_ERROR;
+ if (urctl & BRK)
+ sts |= SD_BREAK_DETECTED;
+ chSysLockFromIsr();
+ chFDDAddFlagsI(com, sts);
+ chSysUnlockFromIsr();
+}
+
+#if USE_MSP430_USART0 || defined(__DOXYGEN__)
+
+/** @brief USART0 serial driver identifier.*/
+FullDuplexDriver COM1;
+
+static uint8_t ib1[SERIAL_BUFFERS_SIZE];
+static uint8_t ob1[SERIAL_BUFFERS_SIZE];
+
+CH_IRQ_HANDLER(USART0TX_VECTOR) {
+ msg_t b;
+
+ CH_IRQ_PROLOGUE();
+
+ chSysLockFromIsr();
+ b = chFDDRequestDataI(&COM1);
+ chSysUnlockFromIsr();
+ if (b < Q_OK)
+ U0IE &= ~UTXIE0;
+ else
+ U0TXBUF = b;
+
+ CH_IRQ_EPILOGUE();
+}
+
+CH_IRQ_HANDLER(USART0RX_VECTOR) {
+ uint8_t urctl;
+
+ CH_IRQ_PROLOGUE();
+
+ if ((urctl = U0RCTL) & RXERR)
+ SetError(urctl, &COM1);
+ chSysLockFromIsr();
+ chFDDIncomingDataI(&COM1, U0RXBUF);
+ chSysUnlockFromIsr();
+
+ CH_IRQ_EPILOGUE();
+}
+
+static void OutNotify1(void) {
+
+ if (!(U0IE & UTXIE0)) {
+ chSysLockFromIsr();
+ U0TXBUF = (uint8_t)chFDDRequestDataI(&COM1);
+ chSysUnlockFromIsr();
+ U0IE |= UTXIE0;
+ }
+}
+
+/**
+ * @brief USART0 setup.
+ * @details This function must be invoked with interrupts disabled.
+ * @param div The divider value as calculated by the @p UBR() macro.
+ * @param mod The value for the @p U0MCTL register.
+ * @param ctl The value for the @p U0CTL register.
+ * @note Does not reset the I/O queues.
+ */
+void usart0_setup(uint16_t div, uint8_t mod, uint8_t ctl) {
+
+ U0CTL = SWRST; /* Resets the USART, it should already be */
+ /* USART init */
+ U0TCTL = SSEL0 | SSEL1; /* SMCLK as clock source */
+ U0MCTL = mod; /* Modulator */
+ U0BR1 = (uint8_t)(div >> 8); /* Divider high */
+ U0BR0 = (uint8_t)(div >> 0); /* Divider low */
+ /* Clear USART status */
+ (void)U0RXBUF;
+ U0RCTL = 0;
+ /* USART enable */
+ P3SEL |= BV(4) + BV(5); /* I/O pins for USART 0 */
+ U0ME |= UTXE0 + URXE0; /* Enables the USART */
+ U0CTL = ctl & ~SWRST; /* Various settings, clears reset state */
+ U0IE |= URXIE0; /* Enables RX interrupt */
+}
+#endif /* USE_MSP430_USART0 */
+
+#if USE_MSP430_USART1 || defined(__DOXYGEN__)
+
+/** @brief USART1 serial driver identifier.*/
+FullDuplexDriver COM2;
+
+static uint8_t ib2[SERIAL_BUFFERS_SIZE];
+static uint8_t ob2[SERIAL_BUFFERS_SIZE];
+
+CH_IRQ_HANDLER(USART1TX_VECTOR) {
+ msg_t b;
+
+ CH_IRQ_PROLOGUE();
+
+ chSysLockFromIsr();
+ b = chFDDRequestDataI(&COM2);
+ chSysUnlockFromIsr();
+ if (b < Q_OK)
+ U1IE &= ~UTXIE1;
+ else
+ U1TXBUF = b;
+
+ CH_IRQ_EPILOGUE();
+}
+
+CH_IRQ_HANDLER(USART1RX_VECTOR) {
+ uint8_t urctl;
+
+ CH_IRQ_PROLOGUE();
+
+ if ((urctl = U1RCTL) & RXERR)
+ SetError(urctl, &COM2);
+ chSysLockFromIsr();
+ chFDDIncomingDataI(&COM2, U1RXBUF);
+ chSysUnlockFromIsr();
+
+ CH_IRQ_EPILOGUE();
+}
+
+static void OutNotify2(void) {
+
+ if (!(U1IE & UTXIE1)) {
+ U1TXBUF = (uint8_t)chFDDRequestDataI(&COM2);
+ U1IE |= UTXIE1;
+ }
+}
+
+/**
+ * @brief USART1 setup.
+ * @details This function must be invoked with interrupts disabled.
+ * @param[in] div the divider value as calculated by the @p UBR() macro
+ * @param[in] mod the value for the @p U1MCTL register
+ * @param[in] ctl the value for the @p U1CTL register.
+ * @note Must be invoked with interrupts disabled.
+ * @note Does not reset the I/O queues.
+ */
+void usart1_setup(uint16_t div, uint8_t mod, uint8_t ctl) {
+
+ U1CTL = SWRST; /* Resets the USART, it should already be */
+ /* USART init */
+ U1TCTL = SSEL0 | SSEL1; /* SMCLK as clock source */
+ U1MCTL = mod; /* Modulator */
+ U1BR1 = (uint8_t)(div >> 8); /* Divider high */
+ U1BR0 = (uint8_t)(div >> 0); /* Divider low */
+ /* Clear USART status */
+ (void)U0RXBUF;
+ U1RCTL = 0;
+ /* USART enable */
+ P3SEL |= BV(6) + BV(7); /* I/O pins for USART 1 */
+ U1ME |= UTXE0 + URXE0; /* Enables the USART */
+ U1CTL = ctl & ~SWRST; /* Various settings, clears reset state */
+ U1IE |= URXIE0; /* Enables RX interrupt */
+}
+#endif
+
+/**
+ * @brief Serial driver initialization.
+ * @note The serial ports are initialized at @p 38400-8-N-1 by default.
+ */
+void serial_init(void) {
+
+ /* I/O queues setup.*/
+#if USE_MSP430_USART0
+ chFDDInit(&COM1, ib1, sizeof ib1, NULL, ob1, sizeof ob1, OutNotify1);
+ usart0_setup(UBR(DEFAULT_USART_BITRATE), 0, CHAR);
+#endif
+
+#if USE_MSP430_USART1
+ chFDDInit(&COM2, ib2, sizeof ib2, NULL, ob2, sizeof ob2, OutNotify2);
+ usart1_setup(UBR(DEFAULT_USART_BITRATE), 0, CHAR);
+#endif
+}
+
+/** @} */
diff --git a/os/ports/GCC/MSP430/msp430_serial.h b/os/ports/GCC/MSP430/msp430_serial.h
new file mode 100644
index 000000000..2195a6869
--- /dev/null
+++ b/os/ports/GCC/MSP430/msp430_serial.h
@@ -0,0 +1,91 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT 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 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT 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, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file ports/MSP430/msp430_serial.h
+ * @brief MSP430 Serial driver macros and structures.
+ * @addtogroup MSP430_SERIAL
+ * @{
+ */
+
+#ifndef _MSP430_SERIAL_H_
+#define _MSP430_SERIAL_H_
+
+/**
+ * @brief Serial buffers size.
+ * @details Configuration parameter, you can change the depth of the queue
+ * buffers depending on the requirements of your application.
+ * @note The default is 32 bytes for both the transmission and receive buffers.
+ */
+#if !defined(SERIAL_BUFFERS_SIZE) || defined(__DOXYGEN__)
+#define SERIAL_BUFFERS_SIZE 32
+#endif
+
+/**
+ * @brief Default bit rate.
+ * @details Configuration parameter, at startup the UARTs are configured at
+ * this speed.
+ * @note It is possible to use @p SetUART() in order to change the working
+ * parameters at runtime.
+ */
+#if !defined(DEFAULT_USART_BITRATE) || defined(__DOXYGEN__)
+#define DEFAULT_USART_BITRATE 38400
+#endif
+
+/**
+ * @brief USART0 driver enable switch.
+ * @details If set to @p TRUE the support for USART0 is included.
+ * @note The default is @p TRUE.
+ */
+#if !defined(USE_MSP430_USART0) || defined(__DOXYGEN__)
+#define USE_MSP430_USART0 TRUE
+#endif
+
+/**
+ * @brief USART1 driver enable switch.
+ * @details If set to @p TRUE the support for USART1 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(USE_MSP430_USART1) || defined(__DOXYGEN__)
+#define USE_MSP430_USART1 FALSE
+#endif
+
+/**
+ * @brief Macro for baud rate computation.
+ * @note Make sure the final baud rate is within tolerance.
+ */
+#define UBR(b) (SMCLK / (b))
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void serial_init(void);
+ void usart0_setup(uint16_t div, uint8_t mod, uint8_t ctl);
+ void usart1_setup(uint16_t div, uint8_t mod, uint8_t ctl);
+#ifdef __cplusplus
+}
+#endif
+
+/** @cond never*/
+extern FullDuplexDriver COM1, COM2;
+/** @endcond*/
+
+#endif /* _MSP430_SERIAL_H_ */
+
+/** @} */
diff --git a/os/ports/GCC/MSP430/pal_lld.c b/os/ports/GCC/MSP430/pal_lld.c
new file mode 100644
index 000000000..c5f59c2e9
--- /dev/null
+++ b/os/ports/GCC/MSP430/pal_lld.c
@@ -0,0 +1,115 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT 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 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT 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, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file ports/MSP430/pal_lld.c
+ * @brief MSP430 Digital I/O low level driver code
+ * @addtogroup MSP430_PAL
+ * @{
+ */
+
+#include <ch.h>
+#include <pal.h>
+
+/**
+ * @brief MSP430 I/O ports configuration.
+ *
+ * @param[in] config the MSP430 ports configuration
+ *
+ * @note The @p PxIFG, @p PxIE and @p PxSEL registers are cleared. @p PxOUT
+ * and @p PxDIR are configured as specified.
+ */
+void _pal_lld_init(const MSP430DIOConfig *config) {
+
+#if defined(__MSP430_HAS_PORT1__) || defined(__MSP430_HAS_PORT1_R__)
+ IOPORT_A->iop_full.ie.reg_p = 0;
+ IOPORT_A->iop_full.ifg.reg_p = 0;
+ IOPORT_A->iop_full.sel.reg_p = 0;
+ IOPORT_A->iop_common.out = config->P1Data.out;
+ IOPORT_A->iop_common.dir = config->P1Data.dir;
+#endif
+
+#if defined(__MSP430_HAS_PORT2__) || defined(__MSP430_HAS_PORT2_R__)
+ IOPORT_B->iop_full.ie.reg_p = 0;
+ IOPORT_B->iop_full.ifg.reg_p = 0;
+ IOPORT_B->iop_full.sel.reg_p = 0;
+ IOPORT_B->iop_common.out = config->P2Data.out;
+ IOPORT_B->iop_common.dir = config->P2Data.dir;
+#endif
+
+#if defined(__MSP430_HAS_PORT3__) || defined(__MSP430_HAS_PORT3_R__)
+ IOPORT_C->iop_simple.sel.reg_p = 0;
+ IOPORT_C->iop_common.out = config->P3Data.out;
+ IOPORT_C->iop_common.dir = config->P3Data.dir;
+#endif
+
+#if defined(__MSP430_HAS_PORT4__) || defined(__MSP430_HAS_PORT4_R__)
+ IOPORT_D->iop_simple.sel.reg_p = 0;
+ IOPORT_D->iop_common.out = config->P4Data.out;
+ IOPORT_D->iop_common.dir = config->P4Data.dir;
+#endif
+
+#if defined(__MSP430_HAS_PORT5__) || defined(__MSP430_HAS_PORT5_R__)
+ IOPORT_E->iop_simple.sel.reg_p = 0;
+ IOPORT_E->iop_common.out = config->P5Data.out;
+ IOPORT_E->iop_common.dir = config->P5Data.dir;
+#endif
+
+#if defined(__MSP430_HAS_PORT6__) || defined(__MSP430_HAS_PORT6_R__)
+ IOPORT_F->iop_simple.sel.reg_p = 0;
+ IOPORT_F->iop_common.out = config->P6Data.out;
+ IOPORT_F->iop_common.dir = config->P6Data.dir;
+#endif
+}
+
+/**
+ * @brief Pads mode setup.
+ * @details This function programs a pads group belonging to the same port
+ * with the specified mode.
+ *
+ * @param[in] port the port identifier
+ * @param[in] mask the group mask
+ * @param[in] mode the mode
+ *
+ * @note This function is not meant to be invoked directly by the application
+ * code.
+ * @note @p PAL_MODE_UNCONNECTED is implemented as output as recommended by
+ * the MSP430x1xx Family User's Guide. Unconnected pads are set to
+ * high logic state by default.
+ * @note This function does not alter the @p PxSEL registers. Alternate
+ * functions setup must be handled by device-specific code.
+ */
+void _pal_lld_setgroupmode(ioportid_t port,
+ ioportmask_t mask,
+ uint_fast8_t mode) {
+
+ switch (mode) {
+ case PAL_MODE_RESET:
+ case PAL_MODE_INPUT:
+ port->iop_common.dir.reg_p &= ~mask;
+ break;
+ case PAL_MODE_UNCONNECTED:
+ port->iop_common.out.reg_p |= mask;
+ case PAL_MODE_OUTPUT_PUSHPULL:
+ port->iop_common.dir.reg_p |= mask;
+ break;
+ }
+}
+
+/** @} */
diff --git a/os/ports/GCC/MSP430/pal_lld.h b/os/ports/GCC/MSP430/pal_lld.h
new file mode 100644
index 000000000..c82b9a80f
--- /dev/null
+++ b/os/ports/GCC/MSP430/pal_lld.h
@@ -0,0 +1,292 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT 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 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT 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, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file ports/MSP430/pal_lld.h
+ * @brief MSP430 Digital I/O low level driver header
+ * @addtogroup MSP430_PAL
+ * @{
+ */
+
+#ifndef _PAL_LLD_H_
+#define _PAL_LLD_H_
+
+#include <msp430x16x.h>
+
+/*===========================================================================*/
+/* Unsupported modes and specific modes */
+/*===========================================================================*/
+
+#undef PAL_MODE_INPUT_PULLUP
+#undef PAL_MODE_INPUT_PULLDOWN
+#undef PAL_MODE_OUTPUT_OPENDRAIN
+
+/*===========================================================================*/
+/* I/O Ports Types and constants. */
+/*===========================================================================*/
+
+/**
+ * @brief Simplified MSP430 I/O port representation.
+ * @details This structure represents the common part of all the MSP430 I/O
+ * ports.
+ */
+struct port_common_t {
+ ioregister_t in;
+ ioregister_t out;
+ ioregister_t dir;
+};
+
+/**
+ * @brief Generic MSP430 I/O port.
+ */
+union __ioport {
+ struct port_common_t iop_common;
+ struct port_simple_t iop_simple;
+ struct port_full_t iop_full;
+};
+
+/**
+ * @brief Setup registers common to all the MSP430 ports.
+ */
+typedef struct {
+ ioregister_t out;
+ ioregister_t dir;
+} msp430_dio_setup_t;
+
+/**
+ * @brief MSP430 I/O ports static initializer.
+ * @details An instance of this structure must be passed to @p palInit() at
+ * system startup time in order to initialized the digital I/O
+ * subsystem. This represents only the initial setup, specific pads
+ * or whole ports can be reprogrammed at later time.
+ */
+typedef struct {
+#if defined(__MSP430_HAS_PORT1__) || \
+ defined(__MSP430_HAS_PORT1_R__) || \
+ defined(__DOXYGEN__)
+ /** @brief Port 1 setup data.*/
+ msp430_dio_setup_t P1Data;
+#endif
+#if defined(__MSP430_HAS_PORT2__) || \
+ defined(__MSP430_HAS_PORT2_R__) || \
+ defined(__DOXYGEN__)
+ /** @brief Port 2 setup data.*/
+ msp430_dio_setup_t P2Data;
+#endif
+#if defined(__MSP430_HAS_PORT3__) || \
+ defined(__MSP430_HAS_PORT3_R__) || \
+ defined(__DOXYGEN__)
+ /** @brief Port 3 setup data.*/
+ msp430_dio_setup_t P3Data;
+#endif
+#if defined(__MSP430_HAS_PORT4__) || \
+ defined(__MSP430_HAS_PORT4_R__) || \
+ defined(__DOXYGEN__)
+ /** @brief Port 4 setup data.*/
+ msp430_dio_setup_t P4Data;
+#endif
+#if defined(__MSP430_HAS_PORT5__) || \
+ defined(__MSP430_HAS_PORT5_R__) || \
+ defined(__DOXYGEN__)
+ /** @brief Port 5 setup data.*/
+ msp430_dio_setup_t P5Data;
+#endif
+#if defined(__MSP430_HAS_PORT6__) || \
+ defined(__MSP430_HAS_PORT6_R__) || \
+ defined(__DOXYGEN__)
+ /** @brief Port 6 setup data.*/
+ msp430_dio_setup_t P6Data;
+#endif
+} MSP430DIOConfig;
+
+/**
+ * @brief Width, in bits, of an I/O port.
+ */
+#define PAL_IOPORTS_WIDTH 8
+
+/**
+ * @brief Whole port mask.
+ * @brief This macro specifies all the valid bits into a port.
+ */
+#define PAL_WHOLE_PORT ((ioportmask_t)0xFF)
+
+/**
+ * @brief Digital I/O port sized unsigned type.
+ */
+typedef uint8_t ioportmask_t;
+
+/**
+ * @brief Port Identifier.
+ * @details This type can be a scalar or some kind of pointer, do not make
+ * any assumption about it, use the provided macros when populating
+ * variables of this type.
+ */
+typedef union __ioport * ioportid_t;
+
+/*===========================================================================*/
+/* I/O Ports Identifiers. */
+/*===========================================================================*/
+
+/**
+ * @brief I/O port A identifier.
+ * @details This port identifier is mapped on the MSP430 port 1 (P1).
+ */
+#if defined(__MSP430_HAS_PORT1__) || \
+ defined(__MSP430_HAS_PORT1_R__) || \
+ defined(__DOXYGEN__)
+#define IOPORT_A ((ioportid_t)0x0020)
+#endif
+
+/**
+ * @brief I/O port B identifier.
+ * @details This port identifier is mapped on the MSP430 port 2 (P2).
+ */
+#if defined(__MSP430_HAS_PORT2__) || \
+ defined(__MSP430_HAS_PORT2_R__) || \
+ defined(__DOXYGEN__)
+#define IOPORT_B ((ioportid_t)0x0028)
+#endif
+
+/**
+ * @brief I/O port C identifier.
+ * @details This port identifier is mapped on the MSP430 port 3 (P3).
+ */
+#if defined(__MSP430_HAS_PORT3__) || \
+ defined(__MSP430_HAS_PORT3_R__) || \
+ defined(__DOXYGEN__)
+#define IOPORT_C ((ioportid_t)0x0018)
+#endif
+
+/**
+ * @brief I/O port D identifier.
+ * @details This port identifier is mapped on the MSP430 port 4 (P4).
+ */
+#if defined(__MSP430_HAS_PORT4__) || \
+ defined(__MSP430_HAS_PORT4_R__) || \
+ defined(__DOXYGEN__)
+#define IOPORT_D ((ioportid_t)0x001c)
+#endif
+
+/**
+ * @brief I/O port E identifier.
+ * @details This port identifier is mapped on the MSP430 port 5 (P5).
+ */
+#if defined(__MSP430_HAS_PORT5__) || \
+ defined(__MSP430_HAS_PORT5_R__) || \
+ defined(__DOXYGEN__)
+#define IOPORT_E ((ioportid_t)0x0030)
+#endif
+
+/**
+ * @brief I/O port F identifier.
+ * @details This port identifier is mapped on the MSP430 port 6 (P6).
+ */
+#if defined(__MSP430_HAS_PORT6__) || \
+ defined(__MSP430_HAS_PORT6_R__) || \
+ defined(__DOXYGEN__)
+#define IOPORT_F ((ioportid_t)0x0034)
+#endif
+
+/*===========================================================================*/
+/* Implementation, some of the following macros could be implemented as */
+/* functions, if so please put them in a file named pal_lld.c. */
+/*===========================================================================*/
+
+/**
+ * @brief Low level PAL subsystem initialization.
+ * @details In MSP430 programs all the ports as input.
+ *
+ * @param[in] config the MSP430 ports configuration
+ */
+#define pal_lld_init(config) _pal_lld_init(config)
+
+/**
+ * @brief Reads the physical I/O port states.
+ * @details This function is implemented by reading the PxIN register, the
+ * implementation has no side effects.
+ *
+ * @param[in] port the port identifier
+ * @return The port bits.
+ *
+ * @note This function is not meant to be invoked directly by the application
+ * code.
+ */
+#define pal_lld_readport(port) ((port)->iop_common.in.reg_p)
+
+/**
+ * @brief Reads the output latch.
+ * @details This function is implemented by reading the PxOUT register, the
+ * implementation has no side effects.
+ *
+ * @param[in] port the port identifier
+ * @return The latched logical states.
+ *
+ * @note This function is not meant to be invoked directly by the application
+ * code.
+ */
+#define pal_lld_readlatch(port) ((port)->iop_common.out.reg_p)
+
+/**
+ * @brief Writes a bits mask on a I/O port.
+ * @details This function is implemented by writing the PxOUT register, the
+ * implementation has no side effects.
+ *
+ * @param[in] port the port identifier
+ * @param[in] bits the bits to be written on the specified port
+ *
+ * @note This function is not meant to be invoked directly by the application
+ * code.
+ */
+#define pal_lld_writeport(port, bits) { \
+ (port)->iop_common.out.reg_p = (bits); \
+}
+
+/**
+ * @brief Pads group mode setup.
+ * @details This function programs a pads group belonging to the same port
+ * with the specified mode.
+ *
+ * @param[in] port the port identifier
+ * @param[in] mask the group mask
+ * @param[in] mode the mode
+ *
+ * @note This function is not meant to be invoked directly by the application
+ * code.
+ * @note @p PAL_MODE_UNCONNECTED is implemented as output as recommended by
+ * the MSP430x1xx Family User's Guide.
+ * @note This function does not alter the @p PxSEL registers. Alternate
+ * functions setup must be handled by device-specific code.
+ */
+#define pal_lld_setgroupmode(port, mask, mode) \
+ _pal_lld_setgroupmode(port, mask, mode)
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void _pal_lld_init(const MSP430DIOConfig *config);
+ void _pal_lld_setgroupmode(ioportid_t port,
+ ioportmask_t mask,
+ uint_fast8_t mode);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _PAL_LLD_H_ */
+
+/** @} */
diff --git a/os/ports/GCC/MSP430/port.dox b/os/ports/GCC/MSP430/port.dox
new file mode 100644
index 000000000..1d0216d3c
--- /dev/null
+++ b/os/ports/GCC/MSP430/port.dox
@@ -0,0 +1,124 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT 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 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT 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, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @defgroup MSP430 MSP430
+ * @details MSP430 port details. This section how the ChibiOS/RT features are
+ * implemented on this architecture.
+ *
+ * @section MSP430_STATES Mapping of the System States in the MSP430 port
+ * The ChibiOS/RT logical @ref system_states are mapped as follow in the MSP430
+ * port:
+ * - <b>Init</b>. This state is represented by the startup code and the
+ * initialization code before @p chSysInit() is executed. It has not a
+ * special hardware state associated.
+ * - <b>Normal</b>. This is the state the system has after executing
+ * @p chSysInit(). Interrupts are enabled.
+ * - <b>Suspended</b>. Interrupts are disabled.
+ * - <b>Disabled</b>. Interrupts are enabled. This state is equivalent to the
+ * Suspended state because there are no fast interrupts in this architecture.
+ * - <b>Sleep</b>. Not yet implemented.
+ * - <b>S-Locked</b>. Interrupts are disabled.
+ * - <b>I-Locked</b>. This state is equivalent to the SRI state, the
+ * @p chSysLockI() and @p chSysUnlockI() APIs do nothing (still use them in
+ * order to formally change state because this may change).
+ * - <b>Serving Regular Interrupt</b>. Normal interrupt service code.
+ * - <b>Serving Fast Interrupt</b>. Not present in this architecture.
+ * - <b>Serving Non-Maskable Interrupt</b>. The MSP430 has several non
+ * maskable interrupt sources that can be associated to this state.
+ * - <b>Halted</b>. Implemented as an infinite loop with interrupts disabled.
+ * .
+ * @section MSP430_NOTES The MSP430 port notes
+ * - The MSP430 does not have a dedicated interrupt stack, make sure to reserve
+ * enough stack space for interrupts in each thread stack. This can be done
+ * by modifying the @p INT_REQUIRED_STACK macro into
+ * <b>./ports/MSP430/chcore.h</b>.
+ * - The state of the hardware multiplier is not saved in the thread context,
+ * make sure to use it in <b>Suspended</b> state (interrupts masked).
+ * - The port code does not define the switch to a low power mode for the
+ * idle thread because the MSP430 has several low power modes. You can
+ * select the proper low power mode for you application by defining the
+ * macro @p port_wait_for_interrupt().
+ * .
+ * @ingroup Ports
+ */
+
+/**
+ * @defgroup MSP430_CONF Configuration Options
+ * @brief MSP430 Configuration Options.
+ * @details The MSP430 port allows some architecture-specific configurations
+ * settings that can be specified externally, as example on the compiler
+ * command line:
+ * - @p INT_REQUIRED_STACK, this value represent the amount of stack space
+ * used by the interrupt handlers.<br>
+ * The default for this value is @p 32, this space is allocated for each
+ * thread so be careful in order to not waste precious RAM space.<br>
+ * The default value is set into <b>./ports/MSP430/chcore.h</b>.
+ * .
+ * @ingroup MSP430
+ */
+
+/**
+ * @defgroup MSP430_CORE Core Port Implementation
+ * @brief MSP430 specific port code, structures and macros.
+ *
+ * @ingroup MSP430
+ */
+
+/**
+ * @defgroup MSP430_DRIVERS MSP430 Drivers
+ * @brief Device drivers included in the MSP430 support.
+ *
+ * @ingroup MSP430
+ */
+
+/**
+ * @defgroup MSP430_PAL I/O Ports Support
+ * @brief I/O Ports peripherals support.
+ * @details This module supports the MSP430 Digital I/O controller. The
+ * controller supports the following features (see @ref PAL):
+ * - 8 bits wide ports.
+ * - Atomic set/reset/toggle functions because special MSP430 instruction set.
+ * - Output latched regardless of the pad setting.
+ * - Direct read of input pads regardless of the pad setting.
+ * .
+ * <h2>Supported Setup Modes</h2>
+ * - @p PAL_MODE_RESET.
+ * - @p PAL_MODE_UNCONNECTED.
+ * - @p PAL_MODE_INPUT.
+ * - @p PAL_MODE_OUTPUT_PUSHPULL.
+ * .
+ * Any attempt to setup an invalid mode is ignored.
+ *
+ * <h2>Suboptimal Behavior</h2>
+ * Some MSP430 I/O ports features are less than optimal:
+ * - Bus/group writing is not atomic.
+ * - Pad/group mode setup is not atomic.
+ * .
+ * @ingroup MSP430_DRIVERS
+ */
+
+/**
+ * @defgroup MSP430_SERIAL USART Support
+ * @brief USART support.
+ * @details The serial driver supports both the MSP430 USARTs in asynchronous
+ * mode.
+ *
+ * @ingroup MSP430_DRIVERS
+ */
diff --git a/os/ports/GCC/MSP430/port.mk b/os/ports/GCC/MSP430/port.mk
new file mode 100644
index 000000000..14fe0d646
--- /dev/null
+++ b/os/ports/GCC/MSP430/port.mk
@@ -0,0 +1,6 @@
+# List of the ChibiOS/RT Cortex-M3 port files.
+PORTSRC = ../../os/ports/GCC/MSP430/chcore.c
+
+PORTASM =
+
+PORTINC = ../../os/ports/GCC/MSP430
diff --git a/os/ports/GCC/MSP430/rules.mk b/os/ports/GCC/MSP430/rules.mk
new file mode 100644
index 000000000..219eef4ac
--- /dev/null
+++ b/os/ports/GCC/MSP430/rules.mk
@@ -0,0 +1,87 @@
+# MSP430 makefile scripts and rules.
+
+# Automatic compiler options
+OPT = $(USE_OPT)
+CPPOPT = $(USE_CPPOPT)
+ifeq ($(USE_CURRP_CACHING),yes)
+ OPT += -ffixed-r7 -DCH_CURRP_REGISTER_CACHE='"r7"'
+endif
+ifeq ($(USE_LINK_GC),yes)
+ OPT += -ffunction-sections -fdata-sections
+endif
+
+# Source files groups
+SRC = $(CSRC)$(CPPSRC)
+
+# Object files groups
+COBJS = $(CSRC:.c=.o)
+CPPOBJS = $(CPPSRC:.cpp=.o)
+ASMOBJS = $(ASMSRC:.s=.o)
+OBJS = $(ASMOBJS) $(COBJS) $(CPPOBJS)
+
+# Paths
+IINCDIR = $(patsubst %,-I%,$(INCDIR) $(DINCDIR) $(UINCDIR))
+LLIBDIR = $(patsubst %,-L%,$(DLIBDIR) $(ULIBDIR))
+
+# Macros
+DEFS = $(DDEFS) $(UDEFS)
+ADEFS = $(DADEFS) $(UADEFS)
+
+# Libs
+LIBS = $(DLIBS) $(ULIBS)
+
+MCFLAGS = -mmcu=$(MCU)
+ODFLAGS = -x --syms
+ASFLAGS = $(MCFLAGS) -Wa,-amhls=$(<:.s=.lst) $(ADEFS)
+CPFLAGS = $(MCFLAGS) $(OPT) $(WARN) -Wa,-alms=$(<:.c=.lst) $(DEFS)
+ifeq ($(LINK_GC),yes)
+ LDFLAGS = $(MCFLAGS) -T$(LDSCRIPT) -Wl,-Map=$(PROJECT).map,--cref,--no-warn-mismatch,--gc-sections $(LLIBDIR)
+else
+ LDFLAGS = $(MCFLAGS) -T$(LDSCRIPT) -Wl,-Map=$(PROJECT).map,--cref,--no-warn-mismatch $(LLIBDIR)
+endif
+
+# Generate dependency information
+CPFLAGS += -MD -MP -MF .dep/$(@F).d
+
+#
+# Makefile rules
+#
+all: $(OBJS) $(PROJECT).elf $(PROJECT).hex $(PROJECT).bin $(PROJECT).dmp
+
+$(CPPOBJS) : %.o : %.cpp
+ @echo
+ $(CPPC) -c $(CPPFLAGS) -I . $(IINCDIR) $< -o $@
+
+$(COBJS) : %.o : %.c
+ @echo
+ $(CC) -c $(CPFLAGS) -I . $(IINCDIR) $< -o $@
+
+$(ASMOBJS) : %.o : %.s
+ @echo
+ $(AS) -c $(ASFLAGS) -I . $(IINCDIR) $< -o $@
+
+%elf: $(OBJS)
+ @echo
+ $(LD) $(OBJS) $(LDFLAGS) $(LIBS) -o $@
+
+%hex: %elf
+ $(HEX) $< $@
+
+%bin: %elf
+ $(BIN) $< $@
+
+%dmp: %elf
+ $(OD) $(ODFLAGS) $< > $@
+
+clean:
+ -rm -f $(OBJS)
+ -rm -f $(CSRC:.c=.lst) $(CPPSRC:.cpp=.lst) $(ASMSRC:.s=.lst)
+ -rm -f $(PROJECT).elf $(PROJECT).dmp $(PROJECT).map $(PROJECT).hex $(PROJECT).bin
+ -rm -fR .dep
+
+#
+# Include the dependency files, should be the last of the makefile
+#
+-include $(shell mkdir .dep 2>/dev/null) $(wildcard .dep/*)
+
+# *** EOF ***
diff --git a/os/ports/GCC/Win32/simcom.c b/os/ports/GCC/Win32/simcom.c
new file mode 100644
index 000000000..1b676b1f7
--- /dev/null
+++ b/os/ports/GCC/Win32/simcom.c
@@ -0,0 +1,227 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT 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 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT 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, see <http://www.gnu.org/licenses/>.
+*/
+
+/*
+ * Win32 COM port simulator (on socket).
+ */
+
+#include <chconf.h>
+
+#include <windows.h>
+#include <stdio.h>
+
+#undef CDECL
+
+#include <ch.h>
+
+#define COM1PORT 29001
+#define COM2PORT 29002
+
+struct simcom {
+
+ uint8_t com_ib[1024];
+ uint8_t com_ob[1024];
+ SOCKET com_listen;
+ SOCKET com_data;
+};
+
+FullDuplexDriver COM1;
+static struct simcom sc1;
+FullDuplexDriver COM2;
+static struct simcom sc2;
+static u_long nb = 1;
+
+static void init(char *name, FullDuplexDriver *sd,
+ struct simcom *sc, unsigned short port) {
+ struct sockaddr_in sad;
+ struct protoent *prtp;
+
+ chFDDInit(sd,
+ sc->com_ib, sizeof(sc->com_ib), NULL,
+ sc->com_ob, sizeof(sc->com_ob), NULL);
+
+ sc->com_listen = INVALID_SOCKET;
+ sc->com_data = INVALID_SOCKET;
+
+ if ((prtp = getprotobyname("tcp")) == NULL) {
+ printf("%s: Error mapping protocol name to protocol number\n", name);
+ goto abort;
+ }
+
+ sc->com_listen = socket(PF_INET, SOCK_STREAM, prtp->p_proto);
+ if (sc->com_listen == INVALID_SOCKET) {
+ printf("%s: Error creating simulator socket\n", name);
+ goto abort;
+ }
+
+ if (ioctlsocket(sc->com_listen, FIONBIO, &nb) != 0) {
+ printf("%s: Unable to setup non blocking mode on socket\n", name);
+ goto abort;
+ }
+
+ memset(&sad, 0, sizeof(sad));
+ sad.sin_family = AF_INET;
+ sad.sin_addr.s_addr = INADDR_ANY;
+ sad.sin_port = htons(port);
+ if (bind(sc->com_listen, (struct sockaddr *)&sad, sizeof(sad))) {
+ printf("%s: Error binding socket\n", name);
+ goto abort;
+ }
+
+ if (listen(sc->com_listen, 1) != 0) {
+ printf("%s: Error binding socket\n", name);
+ goto abort;
+ }
+ printf("Full Duplex Channel %s listening on port %d\n", name, port);
+ return;
+
+abort:
+ if (sc->com_listen != INVALID_SOCKET)
+ closesocket(sc->com_listen);
+ WSACleanup();
+ exit(1);
+}
+
+void InitSimCom1(void) {
+
+ init("COM1", &COM1, &sc1, COM1PORT);
+}
+
+void InitSimCom2(void) {
+
+ init("COM2", &COM2, &sc2, COM2PORT);
+}
+
+static bool_t connint(char *name, FullDuplexDriver *sd, struct simcom *sc) {
+
+ if (sc->com_data == INVALID_SOCKET) {
+ struct sockaddr addr;
+ int addrlen = sizeof(addr);
+
+ if ((sc->com_data = accept(sc->com_listen, &addr, &addrlen)) == INVALID_SOCKET)
+ return FALSE;
+
+ if (ioctlsocket(sc->com_data, FIONBIO, &nb) != 0) {
+ printf("%s: Unable to setup non blocking mode on data socket\n", name);
+ goto abort;
+ }
+ chFDDAddFlagsI(sd, SD_CONNECTED);
+ return TRUE;
+ }
+ return FALSE;
+abort:
+ if (sc->com_listen != INVALID_SOCKET)
+ closesocket(sc->com_listen);
+ if (sc->com_data != INVALID_SOCKET)
+ closesocket(sc->com_data);
+ WSACleanup();
+ exit(1);
+}
+
+bool_t Com1ConnInterruptSimCom(void) {
+
+ return connint("COM1", &COM1, &sc1);
+}
+
+bool_t Com2ConnInterruptSimCom(void) {
+
+ return connint("COM2", &COM2, &sc2);
+}
+
+static bool_t inint(char *name, FullDuplexDriver *sd, struct simcom *sc) {
+
+ if (sc->com_data != INVALID_SOCKET) {
+ int i;
+ uint8_t data[32];
+
+ /*
+ * Input.
+ */
+ int n = recv(sc->com_data, data, sizeof(data), 0);
+ switch (n) {
+ case 0:
+ closesocket(sc->com_data);
+ sc->com_data = INVALID_SOCKET;
+ chFDDAddFlagsI(sd, SD_DISCONNECTED);
+ return FALSE;
+ case SOCKET_ERROR:
+ if (WSAGetLastError() == WSAEWOULDBLOCK)
+ return FALSE;
+ closesocket(sc->com_data);
+ sc->com_data = INVALID_SOCKET;
+ return FALSE;
+ }
+ for (i = 0; i < n; i++)
+ chFDDIncomingDataI(sd, data[i]);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+bool_t Com1InInterruptSimCom(void) {
+
+ return inint("COM1", &COM1, &sc1);
+}
+
+bool_t Com2InInterruptSimCom(void) {
+
+ return inint("COM2", &COM2, &sc2);
+}
+
+static bool_t outint(char *name, FullDuplexDriver *sd, struct simcom *sc) {
+
+ if (sc->com_data != INVALID_SOCKET) {
+ int n;
+ uint8_t data[1];
+
+ /*
+ * Input.
+ */
+ n = chFDDRequestDataI(sd);
+ if (n < 0)
+ return FALSE;
+ data[0] = (uint8_t)n;
+ n = send(sc->com_data, data, sizeof(data), 0);
+ switch (n) {
+ case 0:
+ closesocket(sc->com_data);
+ sc->com_data = INVALID_SOCKET;
+ chFDDAddFlagsI(sd, SD_DISCONNECTED);
+ return FALSE;
+ case SOCKET_ERROR:
+ if (WSAGetLastError() == WSAEWOULDBLOCK)
+ return FALSE;
+ closesocket(sc->com_data);
+ sc->com_data = INVALID_SOCKET;
+ return FALSE;
+ }
+ return TRUE;
+ }
+ return FALSE;
+}
+
+bool_t Com1OutInterruptSimCom(void) {
+
+ return outint("COM1", &COM1, &sc1);
+}
+
+bool_t Com2OutInterruptSimCom(void) {
+
+ return outint("COM2", &COM2, &sc2);
+}
diff --git a/os/ports/GCC/Win32/simio.c b/os/ports/GCC/Win32/simio.c
new file mode 100644
index 000000000..7d72194c0
--- /dev/null
+++ b/os/ports/GCC/Win32/simio.c
@@ -0,0 +1,201 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT 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 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT 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, see <http://www.gnu.org/licenses/>.
+*/
+
+/*
+ * Win32 ISO7816 port simulator (on socket).
+ */
+
+#include <chconf.h>
+
+#include <windows.h>
+#include <stdio.h>
+
+#undef CDECL
+
+#include <ch.h>
+
+#define ISO7816PORT1 29021
+
+typedef struct {
+
+ BYTE8 io_b[16];
+ SOCKET io_listen;
+ SOCKET io_data;
+} sim7816;
+
+HalfDuplexDriver ISO1;
+static sim7816 sim1;
+static u_long nb = 1;
+
+static void init(char *name, HalfDuplexDriver *sd, sim7816 *simp, unsigned short port) {
+
+ struct sockaddr_in sad;
+ struct protoent *prtp;
+
+ chHDDInit(sd, simp->io_b, sizeof(simp->io_b), NULL, NULL);
+
+ simp->io_listen = INVALID_SOCKET;
+ simp->io_data = INVALID_SOCKET;
+
+ if ((prtp = getprotobyname("tcp")) == NULL) {
+ printf("%s: Error mapping protocol name to protocol number\n", name);
+ goto abort;
+ }
+
+ simp->io_listen = socket(PF_INET, SOCK_STREAM, prtp->p_proto);
+ if (simp->io_listen == INVALID_SOCKET) {
+ printf("%s: Error creating simulator socket\n", name);
+ goto abort;
+ }
+
+ if (ioctlsocket(simp->io_listen, FIONBIO, &nb) != 0) {
+ printf("%s: Unable to setup non blocking mode on socket\n", name);
+ goto abort;
+ }
+
+ memset(&sad, 0, sizeof(sad));
+ sad.sin_family = AF_INET;
+ sad.sin_addr.s_addr = INADDR_ANY;
+ sad.sin_port = htons(port);
+ if (bind(simp->io_listen, (struct sockaddr *)&sad, sizeof(sad))) {
+ printf("%s: Error binding socket\n", name);
+ goto abort;
+ }
+
+ if (listen(simp->io_listen, 1) != 0) {
+ printf("%s: Error binding socket\n", name);
+ goto abort;
+ }
+ printf("Half Duplex channel %s listening on port %d\n", name, port);
+ return;
+
+abort:
+ if (simp->io_listen != INVALID_SOCKET)
+ closesocket(simp->io_listen);
+ WSACleanup();
+ exit(1);
+}
+
+void InitSimIso1(void) {
+
+ init("ISO1", &ISO1, &sim1, ISO7816PORT1);
+}
+
+static BOOL connint(char *name, HalfDuplexDriver *sd, sim7816 *simp) {
+
+ if (simp->io_data == INVALID_SOCKET) {
+ struct sockaddr addr;
+ int addrlen = sizeof(addr);
+
+ if ((simp->io_data = accept(simp->io_listen, &addr, &addrlen)) == INVALID_SOCKET)
+ return FALSE;
+
+ if (ioctlsocket(simp->io_data, FIONBIO, &nb) != 0) {
+ printf("%s: Unable to setup non blocking mode on data socket\n", name);
+ goto abort;
+ }
+ chHDDAddFlagsI(sd, SD_CONNECTED);
+ return TRUE;
+ }
+ return FALSE;
+abort:
+ if (simp->io_listen != INVALID_SOCKET)
+ closesocket(simp->io_listen);
+ if (simp->io_data != INVALID_SOCKET)
+ closesocket(simp->io_data);
+ WSACleanup();
+ exit(1);
+}
+
+BOOL Iso1ConnInterrupt(void) {
+
+ return connint("ISO1", &ISO1, &sim1);
+}
+
+static BOOL inint(char *name, HalfDuplexDriver *sd, sim7816 *simp) {
+
+ if (simp->io_data != INVALID_SOCKET) {
+ int i;
+ BYTE8 data[4];
+
+ /*
+ * Input.
+ */
+ int n = recv(simp->io_data, data, sizeof(data), 0);
+ switch (n) {
+ case 0:
+ closesocket(simp->io_data);
+ simp->io_data = INVALID_SOCKET;
+ chHDDAddFlagsI(sd, SD_DISCONNECTED);
+ return FALSE;
+ case SOCKET_ERROR:
+ if (WSAGetLastError() == WSAEWOULDBLOCK)
+ return FALSE;
+ closesocket(simp->io_data);
+ simp->io_data = INVALID_SOCKET;
+ return FALSE;
+ }
+ for (i = 0; i < n; i++)
+ chHDDIncomingDataI(sd, data[i]);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+BOOL Iso1InInterrupt(void) {
+
+ return inint("ISO", &ISO1, &sim1);
+}
+
+static BOOL outint(char *name, HalfDuplexDriver *sd, sim7816 *simp) {
+
+ if (simp->io_data != INVALID_SOCKET) {
+ short n;
+ BYTE8 data[1];
+
+ /*
+ * Input.
+ */
+ n = chHDDRequestDataI(sd);
+ if (n < 0)
+ return FALSE;
+ data[0] = (BYTE8)n;
+ n = send(simp->io_data, data, sizeof(data), 0);
+ switch (n) {
+ case 0:
+ closesocket(simp->io_data);
+ simp->io_data = INVALID_SOCKET;
+ chHDDAddFlagsI(sd, SD_DISCONNECTED);
+ return FALSE;
+ case SOCKET_ERROR:
+ if (WSAGetLastError() == WSAEWOULDBLOCK)
+ return FALSE;
+ closesocket(simp->io_data);
+ simp->io_data = INVALID_SOCKET;
+ return FALSE;
+ }
+ return TRUE;
+ }
+ return FALSE;
+}
+
+BOOL Iso1OutInterrupt(void) {
+
+ return outint("ISO1", &ISO1, &sim1);
+}
diff --git a/os/templates/chconf.h b/os/templates/chconf.h
new file mode 100644
index 000000000..7b7d97cfa
--- /dev/null
+++ b/os/templates/chconf.h
@@ -0,0 +1,388 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT 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 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT 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, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file src/templates/chconf.h
+ * @brief Configuration file template.
+ * @addtogroup Config
+ * @{
+ */
+
+#ifndef _CHCONF_H_
+#define _CHCONF_H_
+
+/*===========================================================================*/
+/* Kernel parameters. */
+/*===========================================================================*/
+
+/**
+ * Frequency of the system timer that drives the system ticks. This also
+ * defines the system tick time unit.
+ */
+#if !defined(CH_FREQUENCY) || defined(__DOXYGEN__)
+#define CH_FREQUENCY 1000
+#endif
+
+/**
+ * This constant is the number of system ticks allowed for the threads before
+ * preemption occurs. This option is only meaningful if the option
+ * @p CH_USE_ROUNDROBIN is also active.
+ */
+#if !defined(CH_TIME_QUANTUM) || defined(__DOXYGEN__)
+#define CH_TIME_QUANTUM 20
+#endif
+
+/**
+ * If enabled then the use of nested @p chSysLock() / @p chSysUnlock()
+ * operations is allowed.<br>
+ * For performance and code size reasons the recommended setting is to leave
+ * this option disabled.<br>
+ * You can use this option if you need to merge ChibiOS/RT with external
+ * libraries that require nested lock/unlock operations.
+ * @note The default is @p FALSE.
+ */
+#if !defined(CH_USE_NESTED_LOCKS) || defined(__DOXYGEN__)
+#define CH_USE_NESTED_LOCKS FALSE
+#endif
+
+/**
+ * If specified then the kernel performs the round robin scheduling algorithm
+ * on threads of equal priority.
+ * @note The default is @p TRUE.
+ */
+#if !defined(CH_USE_ROUNDROBIN) || defined(__DOXYGEN__)
+#define CH_USE_ROUNDROBIN TRUE
+#endif
+
+/**
+ * Number of RAM bytes to use as system heap. If set to zero then the whole
+ * available RAM is used as system heap.
+ * @note In order to use the whole RAM as system heap the linker script must
+ * provide the @p __heap_base__ and @p __heap_end__ symbols.
+ * @note Requires @p CH_USE_HEAP.
+ */
+#if !defined(CH_HEAP_SIZE) || defined(__DOXYGEN__)
+#define CH_HEAP_SIZE 0
+#endif
+
+/*===========================================================================*/
+/* Performance options. */
+/*===========================================================================*/
+
+/**
+ * If specified then time efficient rather than space efficient code is used
+ * when two possible implementations exist.
+ * @note This is not related to the compiler optimization options.
+ * @note The default is @p TRUE.
+ */
+#if !defined(CH_OPTIMIZE_SPEED) || defined(__DOXYGEN__)
+#define CH_OPTIMIZE_SPEED TRUE
+#endif
+
+/**
+ * If enabled defines a CPU register to be used as storage for the global
+ * @p currp variable. Caching this variable in a register can greatly
+ * improve both space and time efficiency of the generated code. Another side
+ * effect is that one less register has to be saved during the context switch
+ * resulting in lower RAM usage and faster code.
+ * @note This option is only usable with the GCC compiler and is only useful
+ * on processors with many registers like ARM cores.
+ * @note If this option is enabled then ALL the libraries linked to the
+ * ChibiOS/RT code <b>must</b> be recompiled with the GCC option @p
+ * -ffixed-@<reg@>.
+ * @note This option must be enabled in the Makefile, it is listed here for
+ * documentation.
+ */
+#if defined(__DOXYGEN__)
+#define CH_CURRP_REGISTER_CACHE "reg"
+#endif
+
+/*===========================================================================*/
+/* Subsystem options. */
+/*===========================================================================*/
+
+/**
+ * If specified then the @p chThdWait() function is included in the kernel.
+ * @note The default is @p TRUE.
+ */
+#if !defined(CH_USE_WAITEXIT) || defined(__DOXYGEN__)
+#define CH_USE_WAITEXIT TRUE
+#endif
+
+/**
+ * If specified then the Semaphores APIs are included in the kernel.
+ * @note The default is @p TRUE.
+ */
+#if !defined(CH_USE_SEMAPHORES) || defined(__DOXYGEN__)
+#define CH_USE_SEMAPHORES TRUE
+#endif
+
+/**
+ * If enabled then the threads are enqueued on semaphores by priority rather
+ * than FIFO order.
+ * @note The default is @p FALSE. Enable this if you have special requirements.
+ * @note Requires @p CH_USE_SEMAPHORES.
+ */
+#if !defined(CH_USE_SEMAPHORES_PRIORITY) || defined(__DOXYGEN__)
+#define CH_USE_SEMAPHORES_PRIORITY FALSE
+#endif
+
+/**
+ * If specified then the Semaphores the @p chSemWaitSignal() API is included
+ * in the kernel.
+ * @note The default is @p TRUE.
+ * @note Requires @p CH_USE_SEMAPHORES.
+ */
+#if !defined(CH_USE_SEMSW) || defined(__DOXYGEN__)
+#define CH_USE_SEMSW TRUE
+#endif
+
+/**
+ * If specified then the Mutexes APIs are included in the kernel.
+ * @note The default is @p TRUE.
+ */
+#if !defined(CH_USE_MUTEXES) || defined(__DOXYGEN__)
+#define CH_USE_MUTEXES TRUE
+#endif
+
+/**
+ * If specified then the Conditional Variables APIs are included in the kernel.
+ * @note The default is @p TRUE.
+ * @note Requires @p CH_USE_MUTEXES.
+ */
+#if !defined(CH_USE_CONDVARS) || defined(__DOXYGEN__)
+#define CH_USE_CONDVARS TRUE
+#endif
+
+/**
+ * If specified then the Conditional Variables APIs are included in the kernel.
+ * @note The default is @p TRUE.
+ * @note Requires @p CH_USE_CONDVARS.
+ */
+#if !defined(CH_USE_CONDVARS_TIMEOUT) || defined(__DOXYGEN__)
+#define CH_USE_CONDVARS_TIMEOUT TRUE
+#endif
+
+/**
+ * If specified then the Event flags APIs are included in the kernel.
+ * @note The default is @p TRUE.
+ */
+#if !defined(CH_USE_EVENTS) || defined(__DOXYGEN__)
+#define CH_USE_EVENTS TRUE
+#endif
+
+/**
+ * If specified then the @p chEvtWaitXXXTimeout() functions are included in
+ * the kernel.
+ * @note The default is @p TRUE.
+ * @note Requires @p CH_USE_EVENTS.
+ */
+#if !defined(CH_USE_EVENTS_TIMEOUT) || defined(__DOXYGEN__)
+#define CH_USE_EVENTS_TIMEOUT TRUE
+#endif
+
+/**
+ * If specified then the Synchronous Messages APIs are included in the kernel.
+ * @note The default is @p TRUE.
+ */
+#if !defined(CH_USE_MESSAGES) || defined(__DOXYGEN__)
+#define CH_USE_MESSAGES TRUE
+#endif
+
+/**
+ * If enabled then messages are served by priority rather than in FIFO order.
+ * @note The default is @p FALSE. Enable this if you have special requirements.
+ * @note Requires @p CH_USE_MESSAGES.
+ */
+#if !defined(CH_USE_MESSAGES_PRIORITY) || defined(__DOXYGEN__)
+#define CH_USE_MESSAGES_PRIORITY FALSE
+#endif
+
+/**
+ * If specified then the Asynchronous Messages (Mailboxes) APIs are included
+ * in the kernel.
+ * @note The default is @p TRUE.
+ * @note Requires @p CH_USE_SEMAPHORES.
+ */
+#if !defined(CH_USE_MAILBOXES) || defined(__DOXYGEN__)
+#define CH_USE_MAILBOXES TRUE
+#endif
+
+/**
+ * If specified then the I/O queues APIs are included in the kernel.
+ * @note The default is @p TRUE.
+ * @note Requires @p CH_USE_SEMAPHORES.
+ */
+#if !defined(CH_USE_QUEUES) || defined(__DOXYGEN__)
+#define CH_USE_QUEUES TRUE
+#endif
+
+/**
+ * If specified then the full duplex serial driver APIs are included in the
+ * kernel.
+ * @note The default is @p TRUE.
+ * @note Requires @p CH_USE_QUEUES and @p CH_USE_EVENTS.
+ */
+#if !defined(CH_USE_SERIAL_FULLDUPLEX) || defined(__DOXYGEN__)
+#define CH_USE_SERIAL_FULLDUPLEX TRUE
+#endif
+
+/**
+ * If specified then the memory heap allocator APIs are included in the kernel.
+ * @note The default is @p TRUE.
+ * @note Requires @p CH_USE_MUTEXES or @p CH_USE_SEMAPHORES.
+ * @note Mutexes are recommended.
+ */
+#if !defined(CH_USE_HEAP) || defined(__DOXYGEN__)
+#define CH_USE_HEAP TRUE
+#endif
+
+/**
+ * If enabled enforces the use of the C-runtime @p malloc() and @p free()
+ * functions as backend for the system heap allocator.
+ * @note The default is @p FALSE.
+ * @note Requires @p CH_USE_HEAP.
+ */
+#if !defined(CH_USE_MALLOC_HEAP) || defined(__DOXYGEN__)
+#define CH_USE_MALLOC_HEAP FALSE
+#endif
+
+/**
+ * If specified then the memory pools allocator APIs are included in the
+ * kernel.
+ * @note The default is @p TRUE.
+ */
+#if !defined(CH_USE_MEMPOOLS) || defined(__DOXYGEN__)
+#define CH_USE_MEMPOOLS TRUE
+#endif
+
+/**
+ * If specified then the dynamic threads creation APIs are included in the
+ * kernel.
+ * @note The default is @p TRUE.
+ * @note Requires @p CH_USE_WAITEXIT.
+ */
+#if !defined(CH_USE_DYNAMIC) || defined(__DOXYGEN__)
+#define CH_USE_DYNAMIC TRUE
+#endif
+
+/*===========================================================================*/
+/* Debug options. */
+/*===========================================================================*/
+
+/**
+ * Debug option, if enabled then the checks on the API functions input
+ * parameters are activated.
+ * @note The default is @p FALSE.
+ */
+#if !defined(CH_DBG_ENABLE_CHECKS) || defined(__DOXYGEN__)
+#define CH_DBG_ENABLE_CHECKS FALSE
+#endif
+
+/**
+ * Debug option, if enabled then all the assertions in the kernel code are
+ * activated. This includes consistency checks inside the kernel, runtime
+ * anomalies and port-defined checks.
+ * @note The default is @p FALSE.
+ */
+#if !defined(CH_DBG_ENABLE_ASSERTS) || defined(__DOXYGEN__)
+#define CH_DBG_ENABLE_ASSERTS FALSE
+#endif
+
+/**
+ * Debug option, if enabled the context switch circular trace buffer is
+ * activated.
+ * @note The default is @p FALSE.
+ */
+#if !defined(CH_DBG_ENABLE_TRACE) || defined(__DOXYGEN__)
+#define CH_DBG_ENABLE_TRACE FALSE
+#endif
+
+/**
+ * Debug option, if enabled a runtime stack check is performed.
+ * @note The stack check is performed in a architecture/port dependent way. It
+ * may not be implemented at all.
+ */
+#if !defined(CH_DBG_ENABLE_STACK_CHECK) || defined(__DOXYGEN__)
+#define CH_DBG_ENABLE_STACK_CHECK FALSE
+#endif
+
+/**
+ * Debug option, if enabled the threads working area is filled with a byte
+ * pattern when a thread is created.
+ */
+#if !defined(CH_DBG_FILL_THREADS) || defined(__DOXYGEN__)
+#define CH_DBG_FILL_THREADS FALSE
+#endif
+
+/**
+ * Debug option, if enabled a field is added to the @p Thread structure that
+ * counts the system ticks occurred while executing the thread.
+ */
+#if !defined(CH_DBG_THREADS_PROFILING) || defined(__DOXYGEN__)
+#define CH_DBG_THREADS_PROFILING TRUE
+#endif
+
+/*===========================================================================*/
+/* Kernel hooks. */
+/*===========================================================================*/
+
+/**
+ * User fields added to the end of the @p Thread structure.
+ */
+#if !defined(THREAD_EXT_FIELDS) || defined(__DOXYGEN__)
+#define THREAD_EXT_FIELDS \
+struct { \
+ /* Add thread custom fields here.*/ \
+};
+#endif
+
+/**
+ * User initialization code added to the @p chThdInit() API.
+ * @note It is invoked from within @p chThdInit().
+ */
+#if !defined(THREAD_EXT_INIT) || defined(__DOXYGEN__)
+#define THREAD_EXT_INIT(tp) { \
+ /* Add thread initialization code here.*/ \
+}
+#endif
+
+/**
+ * User finalization code added to the @p chThdExit() API.
+ * @note It is inserted into lock zone.
+ */
+#if !defined(THREAD_EXT_EXIT) || defined(__DOXYGEN__)
+#define THREAD_EXT_EXIT(tp) { \
+ /* Add thread finalization code here.*/ \
+}
+#endif
+
+/**
+ * Code inserted inside the idle thread loop immediately after an interrupt
+ * resumed execution.
+ */
+#if !defined(IDLE_LOOP_HOOK) || defined(__DOXYGEN__)
+#define IDLE_LOOP_HOOK() { \
+ /* Idle loop code here.*/ \
+}
+#endif
+
+#endif /* _CHCONF_H_ */
+
+/** @} */
diff --git a/os/templates/chcore.c b/os/templates/chcore.c
new file mode 100644
index 000000000..b788d356c
--- /dev/null
+++ b/os/templates/chcore.c
@@ -0,0 +1,133 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT 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 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT 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, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file src/templates/chcore.c
+ * @brief Port related template code.
+ * @addtogroup Core
+ * @{
+ */
+
+#include <ch.h>
+
+/*
+ * This file is a template of the system driver functions provided by a port.
+ * Some of the following functions may be implemented as macros in chcore.h if
+ * the implementer decides that there is an advantage in doing so, as example
+ * because performance concerns.
+ */
+
+/**
+ * @brief Port-related initialization code.
+ *
+ * @note This function is usually empty.
+ */
+void port_init(void){
+}
+
+/**
+ * @brief Kernel-unlock action.
+ * @details Usually this function just disables interrupts but may perform more
+ * actions.
+ */
+void port_lock(void) {
+}
+
+/**
+ * @brief Kernel-unlock action.
+ * @details Usually this function just disables interrupts but may perform more
+ * actions.
+ */
+void port_unlock(void) {
+}
+
+/**
+ * @brief Kernel-lock action from an interrupt handler.
+ * @details This function is invoked before invoking I-class APIs from
+ * interrupt handlers. The implementation is architecture dependent, in its
+ * simplest form it is void.
+ */
+void port_lock_from_isr(void) {
+}
+
+/**
+ * @brief Kernel-unlock action from an interrupt handler.
+ * @details This function is invoked after invoking I-class APIs from interrupt
+ * handlers. The implementation is architecture dependent, in its simplest form
+ * it is void.
+ */
+void port_unlock_from_isr(void) {
+}
+
+/**
+ * @brief Disables all the interrupt sources.
+ *
+ * @note Of course non maskable interrupt sources are not included.
+ */
+void port_disable() {
+}
+
+/**
+ * @brief Disables the interrupt sources that are not supposed to preempt the kernel.
+ */
+void port_suspend(void) {
+}
+
+/**
+ * @brief Enables all the interrupt sources.
+ */
+void port_enable(void) {
+}
+
+/**
+ * @brief Enters an architecture-dependent halt mode.
+ * @details The function is meant to return when an interrupt becomes pending.
+ * The simplest implementation is an empty function but this will not take
+ * advantage of architecture-specific power saving modes.
+ */
+void port_wait_for_interrupt(void) {
+}
+
+/**
+ * @brief Halts the system.
+ * @details This function is invoked by the operating system when an
+ * unrecoverable error is detected (as example because a programming error in
+ * the application code that triggers an assertion while in debug mode).
+ */
+void port_halt(void) {
+
+ port_disable();
+ while (TRUE) {
+ }
+}
+
+/**
+ * @brief Performs a context switch between two threads.
+ * @details This is the most critical code in any port, this function
+ * is responsible for the context switch between 2 threads.
+ *
+ * @param otp the thread to be switched out
+ * @param ntp the thread to be switched in
+ * @note The implementation of this code affects <b>directly</b> the context
+ * switch performance so optimize here as much as you can.
+ */
+void port_switch(Thread *otp, Thread *ntp) {
+}
+
+/** @} */
diff --git a/os/templates/chcore.h b/os/templates/chcore.h
new file mode 100644
index 000000000..c8a0d8222
--- /dev/null
+++ b/os/templates/chcore.h
@@ -0,0 +1,159 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT 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 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT 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, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file src/templates/chcore.h
+ * @brief Port related template macros and structures.
+ * @addtogroup Core
+ * @{
+ */
+
+#ifndef _CHCORE_H_
+#define _CHCORE_H_
+
+/**
+ * Unique macro for the implemented architecture.
+ */
+#define CH_ARCHITECTURE_XXX
+
+/**
+ * Name of the implemented architecture.
+ */
+#define CH_ARCHITECTURE_NAME ""
+
+/**
+ * Base type for stack alignment.
+ * This type is used only for stack alignment reasons thus can be anything from
+ * a char to a double.
+ */
+typedef uint8_t stkalign_t;
+
+/**
+ * @brief Interrupt saved context.
+ * @details This structure represents the stack frame saved during a
+ * preemption-capable interrupt handler.
+ */
+struct extctx {
+};
+
+/**
+ * @brief System saved context.
+ * @details This structure represents the inner stack frame during a context
+ * switching.
+ */
+struct intctx {
+};
+
+/**
+ * @brief Platform dependent part of the @p Thread structure.
+ * @details This structure usually contains just the saved stack pointer
+ * defined as a pointer to a @p intctx structure.
+ */
+struct context {
+ struct intctx *sp;
+};
+
+/**
+ * Platform dependent part of the @p chThdInit() API.
+ * This code usually setup the context switching frame represented by a
+ * @p intctx structure.
+ */
+#define SETUP_CONTEXT(workspace, wsize, pf, arg) { \
+}
+
+/**
+ * Stack size for the system idle thread.
+ * This size depends on the idle thread implementation, usually the idle
+ * thread should take no more space than those reserved
+ * by @p INT_REQUIRED_STACK.
+ */
+#ifndef IDLE_THREAD_STACK_SIZE
+#define IDLE_THREAD_STACK_SIZE 0
+#endif
+
+/**
+ * Per-thread stack overhead for interrupts servicing, it is used in the
+ * calculation of the correct working area size.
+ * This value can be zero on those architecture where there is a separate
+ * interrupt stack and the stack space between @p intctx and @p extctx is
+ * known to be zero.
+ */
+#ifndef INT_REQUIRED_STACK
+#define INT_REQUIRED_STACK 0
+#endif
+
+/**
+ * Enforces a correct alignment for a stack area size value.
+ */
+#define STACK_ALIGN(n) ((((n) - 1) | (sizeof(stkalign_t) - 1)) + 1)
+
+/**
+ * Computes the thread working area global size.
+ */
+#define THD_WA_SIZE(n) STACK_ALIGN(sizeof(Thread) + \
+ sizeof(struct intctx) + \
+ sizeof(struct extctx) + \
+ (n) + (INT_REQUIRED_STACK))
+
+/**
+ * Macro used to allocate a thread working area aligned as both position and
+ * size.
+ */
+#define WORKING_AREA(s, n) stkalign_t s[THD_WA_SIZE(n) / sizeof(stkalign_t)];
+
+/**
+ * IRQ prologue code, inserted at the start of all IRQ handlers enabled to
+ * invoke system APIs.
+ */
+#define PORT_IRQ_PROLOGUE()
+
+/**
+ * IRQ epilogue code, inserted at the end of all IRQ handlers enabled to
+ * invoke system APIs.
+ */
+#define PORT_IRQ_EPILOGUE()
+
+/**
+ * IRQ handler function declaration.
+ * @note @p id can be a function name or a vector number depending on the
+ * port implementation.
+ */
+#define PORT_IRQ_HANDLER(id) void id(void)
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void port_init(void);
+ void port_lock(void);
+ void port_unlock(void);
+ void port_lock_from_isr(void);
+ void port_unlock_from_isr(void);
+ void port_disable(void);
+ void port_suspend(void);
+ void port_enable(void);
+ void port_wait_for_interrupt(void);
+ void port_halt(void);
+ void port_switch(Thread *otp, Thread *ntp);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _CHCORE_H_ */
+
+/** @} */
diff --git a/os/templates/chtypes.h b/os/templates/chtypes.h
new file mode 100644
index 000000000..80884245f
--- /dev/null
+++ b/os/templates/chtypes.h
@@ -0,0 +1,79 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT 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 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT 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, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file src/templates/chtypes.h
+ * @brief System types template.
+ * @addtogroup Types
+ * @{
+ */
+
+#ifndef _CHTYPES_H_
+#define _CHTYPES_H_
+
+#define __need_NULL
+#define __need_size_t
+#include <stddef.h>
+
+#if !defined(_STDINT_H) && !defined(__STDINT_H_)
+#include <stdint.h>
+#endif
+
+/** Signed boolean. */
+typedef int32_t bool_t;
+
+/** Thread mode flags, uint8_t is ok. */
+typedef uint8_t tmode_t;
+
+/** Thread state, uint8_t is ok. */
+typedef uint8_t tstate_t;
+
+/** Priority, use the fastest unsigned type. */
+typedef uint32_t tprio_t;
+
+/** Message, use signed pointer equivalent.*/
+typedef int32_t msg_t;
+
+/** Event Id, use fastest signed.*/
+typedef int32_t eventid_t;
+
+/** Event Mask, recommended fastest unsigned.*/
+typedef uint32_t eventmask_t;
+
+/** System Time, recommended fastest unsigned.*/
+typedef uint32_t systime_t;
+
+/** Counter, recommended fastest signed.*/
+typedef int32_t cnt_t;
+
+/** Inline function modifier. */
+#define INLINE inline
+
+/** Packed structure modifier (within). */
+#define PACK_STRUCT_STRUCT __attribute__((packed))
+
+/** Packed structure modifier (before). */
+#define PACK_STRUCT_BEGIN
+
+/** Packed structure modifier (after). */
+#define PACK_STRUCT_END
+
+#endif /* _CHTYPES_H_ */
+
+/** @} */
diff --git a/os/templates/pal_lld.h b/os/templates/pal_lld.h
new file mode 100644
index 000000000..f594dd143
--- /dev/null
+++ b/os/templates/pal_lld.h
@@ -0,0 +1,322 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT 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 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT 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, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file src/templates/pal_lld.h
+ * @brief PAL subsystem low level driver template
+ * @addtogroup PAL_LLD
+ * @{
+ */
+
+#ifndef _PAL_LLD_H_
+#define _PAL_LLD_H_
+
+/*===========================================================================*/
+/* Unsupported modes and specific modes */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* I/O Ports Types and constants. */
+/*===========================================================================*/
+
+/**
+ * @brief Generic I/O ports static initializer.
+ * @details An instance of this structure must be passed to @p palInit() at
+ * system startup time in order to initialized the digital I/O
+ * subsystem. This represents only the initial setup, specific pads
+ * or whole ports can be reprogrammed at later time.
+ *
+ * @note This structure content is architecture dependent. The nome should be
+ * changed to include the architecture name following this pattern:<br>
+ * - [ARCH][CELL]Config.
+ * .
+ * As example:<br>
+ * - MSP430DIOConfig.
+ * .
+ */
+typedef struct {
+
+} GenericConfig;
+
+/**
+ * @brief Width, in bits, of an I/O port.
+ */
+#define PAL_IOPORTS_WIDTH 32
+
+/**
+ * @brief Whole port mask.
+ * @brief This macro specifies all the valid bits into a port.
+ */
+#define PAL_WHOLE_PORT ((ioportmask_t)0xFFFFFFFF)
+
+/**
+ * @brief Digital I/O port sized unsigned type.
+ */
+typedef uint32_t ioportmask_t;
+
+/**
+ * @brief Port Identifier.
+ * @details This type can be a scalar or some kind of pointer, do not make
+ * any assumption about it, use the provided macros when populating
+ * variables of this type.
+ */
+typedef uint32_t ioportid_t;
+
+/*===========================================================================*/
+/* I/O Ports Identifiers. */
+/*===========================================================================*/
+
+/**
+ * @brief First I/O port identifier.
+ * @details Low level drivers can define multiple ports, it is suggested to
+ * use this naming convention.
+ */
+#define IOPORT_A 0
+
+/*===========================================================================*/
+/* Implementation, some of the following macros could be implemented as */
+/* functions, if so please put them in a file named pal_lld.c. */
+/*===========================================================================*/
+
+/**
+ * @brief Low level PAL subsystem initialization.
+ *
+ * @param[in] config the architecture-dependent ports configuration
+ */
+#define pal_lld_init(config)
+
+/**
+ * @brief Reads the physical I/O port states.
+ *
+ * @param[in] port the port identifier
+ * @return The port bits.
+ *
+ * @note This function is not meant to be invoked directly by the application
+ * code.
+ */
+#define pal_lld_readport(port)
+
+/**
+ * @brief Reads the output latch.
+ * @details The purpose of this function is to read back the latched output
+ * value.
+ *
+ * @param[in] port the port identifier
+ * @return The latched logical states.
+ *
+ * @note This function is not meant to be invoked directly by the application
+ * code.
+ */
+#define pal_lld_readlatch(port)
+
+/**
+ * @brief Writes a bits mask on a I/O port.
+ *
+ * @param[in] port the port identifier
+ * @param[in] bits the bits to be written on the specified port
+ *
+ * @note This function is not meant to be invoked directly by the application
+ * code.
+ */
+#define pal_lld_writeport(port, bits)
+
+/**
+ * @brief Sets a bits mask on a I/O port.
+ *
+ * @param[in] port the port identifier
+ * @param[in] bits the bits to be ORed on the specified port
+ *
+ * @note This function is not meant to be invoked directly by the application
+ * code.
+ * @note The @ref PAL provides a default software implementation of this
+ * functionality, implement this function if can optimize it by using
+ * special hardware functionalities or special coding.
+ */
+#define pal_lld_setport(port, bits)
+
+/**
+ * @brief Clears a bits mask on a I/O port.
+ *
+ * @param[in] port the port identifier
+ * @param[in] bits the bits to be cleared on the specified port
+ *
+ * @note This function is not meant to be invoked directly by the application
+ * code.
+ * @note The @ref PAL provides a default software implementation of this
+ * functionality, implement this function if can optimize it by using
+ * special hardware functionalities or special coding.
+ */
+#define pal_lld_clearport(port, bits)
+
+/**
+ * @brief Toggles a bits mask on a I/O port.
+ *
+ * @param[in] port the port identifier
+ * @param[in] bits the bits to be XORed on the specified port
+ *
+ * @note This function is not meant to be invoked directly by the application
+ * code.
+ * @note The @ref PAL provides a default software implementation of this
+ * functionality, implement this function if can optimize it by using
+ * special hardware functionalities or special coding.
+ */
+#define pal_lld_toggleport(port, bits)
+
+/**
+ * @brief Reads a group of bits.
+ *
+ * @param[in] port the port identifier
+ * @param[in] mask the group mask
+ * @param[in] offset the group bit offset within the port
+ * @return The group logical states.
+ *
+ * @note This function is not meant to be invoked directly by the application
+ * code.
+ * @note The @ref PAL provides a default software implementation of this
+ * functionality, implement this function if can optimize it by using
+ * special hardware functionalities or special coding.
+ */
+#define pal_lld_readgroup(port, mask, offset)
+
+/**
+ * @brief Writes a group of bits.
+ *
+ * @param[in] port the port identifier
+ * @param[in] mask the group mask
+ * @param[in] offset the group bit offset within the port
+ * @param[in] bits the bits to be written. Values exceeding the group width
+ * are masked.
+ *
+ * @note This function is not meant to be invoked directly by the application
+ * code.
+ * @note The @ref PAL provides a default software implementation of this
+ * functionality, implement this function if can optimize it by using
+ * special hardware functionalities or special coding.
+ */
+#define pal_lld_writegroup(port, mask, offset, bits)
+
+/**
+ * @brief Pads group mode setup.
+ * @details This function programs a pads group belonging to the same port
+ * with the specified mode.
+ *
+ * @param[in] port the port identifier
+ * @param[in] mask the group mask
+ * @param[in] mode the mode
+ *
+ * @note This function is not meant to be invoked directly by the application
+ * code.
+ * @note Programming an unknown or unsupported mode is silently ignored.
+ */
+#define pal_lld_setgroupmode(port, mask, mode)
+
+/**
+ * @brief Reads a logical state from an I/O pad.
+ *
+ * @param[in] port the port identifier
+ * @param[in] pad the pad number within the port
+ * @return The logical state.
+ * @retval 0 low logical state.
+ * @retval 1 high logical state.
+ *
+ * @note This function is not meant to be invoked directly by the application
+ * code.
+ * @note The @ref PAL provides a default software implementation of this
+ * functionality, implement this function if can optimize it by using
+ * special hardware functionalities or special coding.
+ */
+#define pal_lld_readpad(port, pad)
+
+/**
+ * @brief Writes a logical state on an output pad.
+ *
+ * @param[in] port the port identifier
+ * @param[in] pad the pad number within the port
+ * @param[out] bit the logical value, the value must be @p 0 or @p 1
+ *
+ * @note This function is not meant to be invoked directly by the application
+ * code.
+ * @note The @ref PAL provides a default software implementation of this
+ * functionality, implement this function if can optimize it by using
+ * special hardware functionalities or special coding.
+ */
+#define pal_lld_writepad(port, pad, bit)
+
+/**
+ * @brief Sets a pad logical state to @p 1.
+ *
+ * @param[in] port the port identifier
+ * @param[in] pad the pad number within the port
+ *
+ * @note This function is not meant to be invoked directly by the application
+ * code.
+ * @note The @ref PAL provides a default software implementation of this
+ * functionality, implement this function if can optimize it by using
+ * special hardware functionalities or special coding.
+ */
+#define pal_lld_setpad(port, pad)
+
+/**
+ * @brief Clears a pad logical state to @p 0.
+ *
+ * @param[in] port the port identifier
+ * @param[in] pad the pad number within the port
+ *
+ * @note This function is not meant to be invoked directly by the application
+ * code.
+ * @note The @ref PAL provides a default software implementation of this
+ * functionality, implement this function if can optimize it by using
+ * special hardware functionalities or special coding.
+ */
+#define pal_lld_clearpad(port, pad)
+
+/**
+ * @brief Toggles a pad logical state.
+ *
+ * @param[in] port the port identifier
+ * @param[in] pad the pad number within the port
+ *
+ * @note This function is not meant to be invoked directly by the application
+ * code.
+ * @note The @ref PAL provides a default software implementation of this
+ * functionality, implement this function if can optimize it by using
+ * special hardware functionalities or special coding.
+ */
+#define pal_lld_togglepad(port, pad)
+
+/**
+ * @brief Pad mode setup.
+ * @details This function programs a pad with the specified mode.
+ *
+ * @param[in] port the port identifier
+ * @param[in] pad the pad number within the port
+ * @param[in] mode the mode
+ *
+ * @note This function is not meant to be invoked directly by the application
+ * code.
+ * @note The @ref PAL provides a default software implementation of this
+ * functionality, implement this function if can optimize it by using
+ * special hardware functionalities or special coding.
+ * @note Programming an unknown or unsupported mode is silently ignored.
+ */
+#define pal_lld_setpadmode(port, pad, mode)
+
+#endif /* _PAL_LLD_H_ */
+
+/** @} */
diff --git a/os/various/ch.cpp b/os/various/ch.cpp
new file mode 100644
index 000000000..6e338630e
--- /dev/null
+++ b/os/various/ch.cpp
@@ -0,0 +1,335 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT 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 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT 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, see <http://www.gnu.org/licenses/>.
+*/
+/**
+ * @file ch.cpp
+ * @brief C++ wrapper code.
+ * @addtogroup CPlusPlusLibrary
+ * @{
+ */
+
+#include <ch.hpp>
+
+namespace chibios_rt {
+
+ /*------------------------------------------------------------------------*
+ * chibios_rt::System *
+ *------------------------------------------------------------------------*/
+ void System::Init(void) {
+
+ chSysInit();
+ }
+
+ void System::Lock(void) {
+
+ chSysLock();
+ }
+
+ void System::Unlock(void) {
+
+ chSysUnlock();
+ }
+
+ systime_t System::GetTime(void) {
+
+ return chTimeNow();
+ }
+
+ /*------------------------------------------------------------------------*
+ * chibios_rt::Timer *
+ *------------------------------------------------------------------------*/
+ void Timer::Set(systime_t time, vtfunc_t vtfunc, void *par) {
+
+ chVTSetI(&timer, time, vtfunc, par);
+ }
+
+ void Timer::Reset() {
+
+ chVTResetI(&timer);
+ }
+
+ bool Timer::IsArmed(void) {
+
+ return chVTIsArmedI(&timer);
+ }
+
+ /*------------------------------------------------------------------------*
+ * chibios_rt::BaseThread *
+ *------------------------------------------------------------------------*/
+ static msg_t thdstart(void *arg) {
+
+ return ((BaseThread *)arg)->Main();
+ }
+
+ BaseThread::BaseThread(void *workspace, size_t wsize, tprio_t prio) {
+
+ thread_ref = chThdCreateStatic(workspace, wsize, prio, thdstart, this);
+ }
+
+ void BaseThread::Exit(msg_t msg) {
+
+ chThdExit(msg);
+ }
+
+#if CH_USE_WAITEXIT
+ msg_t BaseThread::Wait(void) {
+
+ return chThdWait(thread_ref);
+ }
+#endif /* CH_USE_WAITEXIT */
+
+ void BaseThread::SetPriority(tprio_t newprio) {
+
+ chThdSetPriority(newprio);
+ }
+
+ void BaseThread::Resume(void) {
+
+ chThdResume(thread_ref);
+ }
+
+ void BaseThread::Terminate(void) {
+
+ chThdTerminate(thread_ref);
+ }
+
+ void BaseThread::Sleep(systime_t n) {
+
+ chThdSleep(n);
+ }
+
+ void BaseThread::SleepUntil(systime_t time) {
+
+ chThdSleepUntil(time);
+ }
+
+#if CH_USE_MESSAGES
+ msg_t BaseThread::SendMessage(::Thread* tp, msg_t msg) {
+
+ return chMsgSend(tp, msg);
+ }
+
+ msg_t BaseThread::SendMessage(msg_t msg) {
+
+ return chMsgSend(thread_ref, msg);
+ }
+
+ msg_t BaseThread::WaitMessage(void) {
+
+ return chMsgWait();
+ }
+
+ msg_t BaseThread::GetMessage(void) {
+
+ return chMsgGet();
+ }
+
+ void BaseThread::ReleaseMessage(msg_t msg) {
+
+ chMsgRelease(msg);
+ }
+
+ bool BaseThread::IsPendingMessage(void) {
+
+ return chMsgIsPendingI(currp);
+ }
+#endif /* CH_USE_MESSAGES */
+
+ msg_t BaseThread::Main(void) {
+
+ return 0;
+ }
+
+#if CH_USE_SEMAPHORES
+ /*------------------------------------------------------------------------*
+ * chibios_rt::Semaphore *
+ *------------------------------------------------------------------------*/
+ Semaphore::Semaphore(cnt_t n) {
+
+ chSemInit(&sem, n);
+ }
+
+ void Semaphore::Reset(cnt_t n) {
+
+ chSemReset(&sem, n);
+ }
+
+ msg_t Semaphore::Wait(void) {
+
+ return chSemWait(&sem);
+ }
+
+ msg_t Semaphore::WaitTimeout(systime_t time) {
+
+ return chSemWaitTimeout(&sem, time);
+ }
+
+ void Semaphore::Signal(void) {
+
+ chSemSignal(&sem);
+ }
+
+#if CH_USE_SEMSW
+ msg_t Semaphore::SignalWait(Semaphore *ssem, Semaphore *wsem) {
+
+ return chSemSignalWait(&ssem->sem, &wsem->sem);
+ }
+#endif /* CH_USE_SEMSW */
+#endif /* CH_USE_SEMAPHORES */
+
+#if CH_USE_MUTEXES
+ /*------------------------------------------------------------------------*
+ * chibios_rt::Mutex *
+ *------------------------------------------------------------------------*/
+ Mutex::Mutex(void) {
+
+ chMtxInit(&mutex);
+ }
+
+ bool Mutex::TryLock(void) {
+
+ return chMtxTryLock(&mutex);
+ }
+
+ void Mutex::Lock(void) {
+
+ chMtxLock(&mutex);
+ }
+
+ void Mutex::Unlock(void) {
+
+ chMtxUnlock();
+ }
+
+ void UnlockAll(void) {
+
+ chMtxUnlockAll();
+ }
+
+#if CH_USE_CONDVARS
+ /*------------------------------------------------------------------------*
+ * chibios_rt::CondVar *
+ *------------------------------------------------------------------------*/
+ CondVar::CondVar(void) {
+
+ chCondInit(&condvar);
+ }
+
+ void CondVar::Signal(void) {
+
+ chCondSignal(&condvar);
+ }
+
+ void CondVar::Broadcast(void) {
+
+ chCondBroadcast(&condvar);
+ }
+
+ msg_t CondVar::Wait(void) {
+
+ return chCondWait(&condvar);
+ }
+
+#if CH_USE_CONDVARS_TIMEOUT
+ msg_t CondVar::WaitTimeout(systime_t time) {
+
+ return chCondWaitTimeout(&condvar, time);
+ }
+#endif /* CH_USE_CONDVARS_TIMEOUT */
+#endif /* CH_USE_CONDVARS */
+#endif /* CH_USE_MUTEXES */
+
+#if CH_USE_EVENTS
+ /*------------------------------------------------------------------------*
+ * chibios_rt::Event *
+ *------------------------------------------------------------------------*/
+ Event::Event(void) {
+
+ chEvtInit(&event);
+ }
+
+ void Event::Register(EventListener *elp, eventid_t eid) {
+
+ chEvtRegister(&event,elp, eid);
+ }
+
+ void Event::RegisterMask(EventListener *elp, eventmask_t emask) {
+
+ chEvtRegisterMask(&event,elp, emask);
+ }
+
+ void Event::Unregister(EventListener *elp) {
+
+ chEvtUnregister(&event, elp);
+ }
+
+ void Event::Broadcast(void) {
+
+ chEvtBroadcast(&event);
+ }
+
+ eventmask_t Event::Clear(eventmask_t mask) {
+
+ return chEvtClear(mask);
+ }
+
+ eventmask_t Event::Pend(eventmask_t mask) {
+
+ return chEvtPend(mask);
+ }
+
+ void Event::Dispatch(const evhandler_t handlers[], eventmask_t mask) {
+
+ chEvtDispatch(handlers, mask);
+ }
+
+ eventmask_t Event::WaitOne(eventmask_t ewmask) {
+
+ return chEvtWaitOne(ewmask);
+ }
+
+ eventmask_t Event::WaitAny(eventmask_t ewmask) {
+
+ return chEvtWaitAny(ewmask);
+ }
+
+ eventmask_t Event::WaitAll(eventmask_t ewmask) {
+
+ return chEvtWaitAll(ewmask);
+ }
+
+#if CH_USE_EVENTS_TIMEOUT
+ eventmask_t Event::WaitOneTimeout(eventmask_t ewmask, systime_t time) {
+
+ return chEvtWaitOneTimeout(ewmask, time);
+ }
+
+ eventmask_t Event::WaitAnyTimeout(eventmask_t ewmask, systime_t time) {
+
+ return chEvtWaitAnyTimeout(ewmask, time);
+ }
+
+ eventmask_t Event::WaitAllTimeout(eventmask_t ewmask, systime_t time) {
+
+ return chEvtWaitAllTimeout(ewmask, time);
+ }
+#endif /* CH_USE_EVENTS_TIMEOUT */
+#endif /* CH_USE_EVENTS */
+}
+
+/** @} */
diff --git a/os/various/ch.hpp b/os/various/ch.hpp
new file mode 100644
index 000000000..b13e8db6d
--- /dev/null
+++ b/os/various/ch.hpp
@@ -0,0 +1,618 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT 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 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT 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, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file ch.hpp
+ * @brief C++ wrapper classes and definitions.
+ * @addtogroup CPlusPlusLibrary
+ * @{
+ */
+
+#include <ch.h>
+
+#ifndef _CH_HPP_
+#define _CH_HPP_
+
+namespace chibios_rt {
+
+ /**
+ * @brief Class encapsulating the base system functionalities.
+ */
+ class System {
+ public:
+ /**
+ * @brief ChibiOS/RT initialization.
+ * @details The system is initialized, the idle thread is spawned and the
+ * current instruction flow becomes the main thread with priority
+ * @p NORMALPRIO.
+ */
+ static void Init(void);
+
+ /**
+ * @brief Kernel lock.
+ *
+ * @note On some ports it is faster to invoke chSysLock() directly because
+ * inlining.
+ */
+ static void Lock(void);
+
+ /**
+ * @brief Kernel unlock.
+ *
+ * @note On some ports it is faster to invoke chSysUnlock() directly
+ * because inlining.
+ */
+ static void Unlock(void);
+
+ /**
+ * @brief Returns the system time as system ticks.
+ *
+ * @note the system tick time interval is implementation dependent.
+ */
+ static systime_t GetTime(void);
+ };
+
+ /**
+ * @brief Timer class.
+ */
+ class Timer {
+ public:
+ /**
+ * @brief Embedded @p VirtualTimer structure.
+ */
+ struct ::VirtualTimer timer;
+
+ /**
+ * @brief Starts the timer.
+ *
+ * @param time the time in system ticks
+ * @param vtfunc the timer callback function
+ * @param par the parameter for the callback function
+ * @note It must be called with the interrupts disabled.
+ * @note The associated function is invoked by an interrupt handler.
+ */
+ void Set(systime_t time, vtfunc_t vtfunc, void *par);
+
+ /**
+ * @brief Resets the timer.
+ *
+ * @note It must be called with the interrupts disabled.
+ * @note The timer MUST be active when this function is invoked.
+ */
+ void Reset();
+
+ /**
+ * @brief Returns the timer status.
+ *
+ * @retval TRUE The timer is armed.
+ * @retval FALSE The timer already fired its callback.
+ */
+ bool IsArmed(void);
+ };
+
+ /**
+ * @brief Base class for a ChibiOS/RT thread.
+ * @details The thread body is the virtual function @p Main().
+ */
+ class BaseThread {
+ public:
+ /**
+ * @brief Pointer to the system thread.
+ */
+ ::Thread *thread_ref;
+
+ /**
+ * @brief Thread constructor.
+ * @details The thread object is initialized and a system thread is
+ * started.
+ *
+ * @param workspace pointer to the workspace area
+ * @param wsize size of the workspace area
+ * @param prio thread priority
+ */
+ BaseThread(void *workspace, size_t wsize, tprio_t prio);
+
+ /**
+ * @brief Thread exit.
+ *
+ * @param msg the exit message
+ */
+ static void Exit(msg_t msg);
+
+#if CH_USE_WAITEXIT
+ /**
+ * @brief Synchronization on Thread exit.
+ *
+ * @return the exit message from the thread
+ */
+ msg_t Wait(void);
+#endif /* CH_USE_WAITEXIT */
+
+ /**
+ * @brief Resumes the thread.
+ * @details The thread encapsulated into the object is resumed.
+ */
+ void Resume(void);
+
+ /**
+ * @brief Changes the thread priority.
+ *
+ * @param newprio the new priority level
+ */
+ static void SetPriority(tprio_t newprio);
+
+ /**
+ * @brief Requests thread termination.
+ * @details A termination flag is pended on the thread, it is thread
+ * responsibility to detect it and exit.
+ */
+ void Terminate(void);
+
+ /**
+ * @brief Suspends the thread execution for the specified number of
+ * system ticks.
+ *
+ * @param n the number of system ticks
+ */
+ static void Sleep(systime_t n);
+
+ /**
+ * @brief Suspends the thread execution until the specified time arrives.
+ *
+ * @param time the system time
+ */
+ static void SleepUntil(systime_t time);
+
+#if CH_USE_MESSAGES
+ /**
+ * @brief Sends a message to the thread and returns the answer.
+ *
+ * @param tp the target thread
+ * @param msg the sent message
+ * @return The returned message.
+ */
+ static msg_t SendMessage(::Thread *tp, msg_t msg);
+
+ /**
+ * @brief Sends a message to the thread and returns the answer.
+ *
+ * @param msg the sent message
+ * @return The returned message.
+ */
+ msg_t SendMessage(msg_t msg);
+
+ /**
+ * @brief Waits for a message and returns it.
+ *
+ * @return The incoming message.
+ */
+ static msg_t WaitMessage(void);
+
+ /**
+ * @brief Returns an enqueued message or @p NULL.
+ *
+ * @return The incoming message.
+ * @retval NULL No incoming message.
+ */
+ static msg_t GetMessage(void);
+
+ /**
+ * @brief Releases the next message in queue with a reply.
+ *
+ * @param msg the answer message
+ */
+ static void ReleaseMessage(msg_t msg);
+
+ /**
+ * @brief Returns true if there is at least one message in queue.
+ *
+ * @retval TRUE A message is waiting in queue.
+ * @retval FALSE A message is not waiting in queue.
+ */
+ static bool IsPendingMessage(void);
+#endif /* CH_USE_MESSAGES */
+
+ /**
+ * @brief Thread body function.
+ *
+ * @return The exit message.
+ */
+ virtual msg_t Main(void);
+ };
+
+ /**
+ * @brief Enhanced threads template class.
+ * @details This class introduces thread names and static working area
+ * allocation.
+ *
+ * @param N the working area size for the thread class
+ */
+ template <int N>
+ class EnhancedThread : public BaseThread {
+ protected:
+ WORKING_AREA(wa, N); // Thread working area.
+
+ public:
+ /**
+ * @brief The thread name.
+ */
+ const char *name;
+
+ /**
+ * @brief Full constructor.
+ * @details This constructor allows to set a priority level for the new
+ * thread.
+ * @param tname the name to be assigned to the thread
+ * @param prio the priority to be assigned to the thread
+ */
+ EnhancedThread(const char *tname, tprio_t prio) :
+ BaseThread(wa, sizeof wa, prio) {
+
+ name = tname;
+ }
+
+ /**
+ * @brief Simplified constructor.
+ * @details This constructor allows to create a thread by simply
+ * specifying a name. In is assumed @p NORMALPRIO as initial priority.
+ *
+ * @param tname the name to be assigned to the thread
+ */
+ EnhancedThread(const char *tname) :
+ BaseThread(wa, sizeof wa, NORMALPRIO) {
+
+ name = tname;
+ }
+ };
+
+#if CH_USE_SEMAPHORES
+ /**
+ * @brief Class encapsulating a semaphore.
+ */
+ class Semaphore {
+ public:
+ /**
+ * @brief Embedded @p ::Semaphore structure.
+ */
+ struct ::Semaphore sem;
+
+ /**
+ * @brief Semaphore constructor.
+ * @details The embedded @p ::Semaphore structure is initialized.
+ *
+ * @param n the semaphore counter value, must be greater or equal to zero
+ */
+ Semaphore(cnt_t n);
+
+ /**
+ * @brief Resets a semaphore.
+ *
+ * @param n the new semaphore counter value, must be greater or equal to zero
+ */
+ void Reset(cnt_t n);
+
+ /**
+ * @brief Wait operation on the semaphore.
+ *
+ * @retval RDY_OK if the semaphore was signaled or not taken.
+ * @retval RDY_RESET if the semaphore was reset.
+ */
+ msg_t Wait(void);
+
+ /**
+ * @brief Wait operation on the semaphore with timeout.
+ *
+ * @param time the number of ticks before the operation fails
+ * @retval RDY_OK if the semaphore was signaled or not taken.
+ * @retval RDY_RESET if the semaphore was reset.
+ * @retval RDY_TIMEOUT if the semaphore was not signaled or reset within the
+ * specified timeout.
+ */
+ msg_t WaitTimeout(systime_t time);
+
+ /**
+ * @brief Signal operation on the semaphore.
+ * @details The semaphore is signaled, the next thread in queue, if any,
+ * is awakened.
+ */
+ void Signal(void);
+
+#if CH_USE_SEMSW
+ /**
+ * @brief Atomic signal and wait operations.
+ *
+ * @param ssem pointer to a @p Semaphore to be signaled
+ * @param wsem pointer to a @p Semaphore to be wait on
+ * @retval RDY_OK if the semaphore was signaled or not taken.
+ * @retval RDY_RESET if the semaphore was reset.
+ */
+ static msg_t SignalWait(Semaphore *ssem, Semaphore *wsem);
+#endif /* CH_USE_SEMSW */
+ };
+#endif /* CH_USE_SEMAPHORES */
+
+#if CH_USE_MUTEXES
+ /**
+ * @brief Class encapsulating a mutex.
+ */
+ class Mutex {
+ public:
+ /**
+ * @brief Embedded @p ::Mutex structure.
+ */
+ struct ::Mutex mutex;
+
+ /**
+ * @brief Mutex constructor.
+ * @details The embedded @p ::Mutex structure is initialized.
+ */
+ Mutex(void);
+
+ /**
+ * @brief Tries a lock operation on the mutex.
+ * @retval TRUE if the mutex was successfully acquired
+ * @retval FALSE if the lock attempt failed.
+ */
+ bool TryLock(void);
+
+ /**
+ * @brief Locks the mutex.
+ * @details Performs a lock operation on the mutex, if the mutex is
+ * already locked then the thread enters the mutex priority queue and
+ * waits.
+ */
+ void Lock(void);
+
+ /**
+ * @brief Unlocks the mutex.
+ * @details Performs an unlock operation on the mutex, the next waiting
+ * thread, if any, is resumed and locks the mutex.
+ */
+ static void Unlock(void);
+
+ /**
+ * @brief Unlocks all the mutexes owned by the invoking thread.
+ * @details This operation is <b>MUCH MORE</b> efficient than releasing
+ * the mutexes one by one and not just because the call overhead, this
+ * function does not have any overhead related to the priority inheritance
+ * mechanism.
+ */
+ static void UnlockAll(void);
+ };
+
+#if CH_USE_CONDVARS
+ /**
+ * @brief Class encapsulating a conditional variable.
+ */
+ class CondVar {
+ public:
+ /**
+ * @brief Embedded @p ::CondVar structure.
+ */
+ struct ::CondVar condvar;
+
+ /**
+ * @brief CondVar constructor.
+ * @details The embedded @p ::CondVar structure is initialized.
+ */
+ CondVar(void);
+
+ /**
+ * @brief Signals the CondVar.
+ * @details The next thread waiting on the @p CondVar, if any, is awakened.
+ */
+ void Signal(void);
+
+ /**
+ * @brief Broadcasts the CondVar.
+ * @details All the threads waiting on the @p CondVar, if any, are awakened.
+ */
+ void Broadcast(void);
+
+ /**
+ * @brief Waits on the CondVar while releasing the controlling mutex.
+ *
+ * @return The wakep mode.
+ * @retval RDY_OK if the condvar was signaled using chCondSignal().
+ * @retval RDY_RESET if the condvar was signaled using chCondBroadcast().
+ */
+ msg_t Wait(void);
+
+#if CH_USE_CONDVARS_TIMEOUT
+ /**
+ * @brief Waits on the CondVar while releasing the controlling mutex.
+ *
+ * @param time the number of ticks before the operation fails
+ * @return The wakep mode.
+ * @retval RDY_OK if the condvar was signaled using chCondSignal().
+ * @retval RDY_RESET if the condvar was signaled using chCondBroadcast().
+ * @retval RDY_TIMEOUT if the condvar was not signaled within the specified
+ * timeout.
+ */
+ msg_t WaitTimeout(systime_t time);
+#endif /* CH_USE_CONDVARS_TIMEOUT */
+ };
+#endif /* CH_USE_CONDVARS */
+#endif /* CH_USE_MUTEXES */
+
+#if CH_USE_EVENTS
+ /**
+ * @brief Class encapsulating an event source.
+ */
+ class Event {
+ public:
+ /**
+ * @brief Embedded @p ::EventSource structure.
+ */
+ struct ::EventSource event;
+
+ /**
+ * @brief Event constructor.
+ * @details The embedded @p ::EventSource structure is initialized.
+ */
+ Event(void);
+
+ /**
+ * @brief Registers a listener on the event source.
+ *
+ * @param elp pointer to the @p EventListener structure
+ * @param eid numeric identifier assigned to the Event Listener
+ */
+ void Register(EventListener *elp, eventid_t eid);
+
+ /**
+ * @brief Registers an Event Listener on an Event Source.
+ *
+ * @param elp pointer to the @p EventListener structure
+ * @param emask the mask of event flags to be pended to the thread when the
+ * event source is broadcasted
+ * @note Multiple Event Listeners can specify the same bits to be pended.
+ */
+ void RegisterMask(EventListener *elp, eventmask_t emask);
+
+ /**
+ * @brief Unregisters a listener.
+ * @details The specified listeners is no more signaled by the event
+ * source.
+ *
+ * @param elp the listener to be unregistered
+ */
+ void Unregister(EventListener *elp);
+
+ /**
+ * @brief Broadcasts an event.
+ * @details All the listeners registered on the event source are signaled.
+ */
+ void Broadcast(void);
+
+ /**
+ * @brief Clears specified events from the pending events mask.
+ *
+ * @param mask the events to be cleared
+ * @return The pending events that were cleared.
+ */
+ static eventmask_t Clear(eventmask_t mask);
+
+ /**
+ * @brief Makes an events mask pending in the current thread.
+ * @details This functon is @b much faster than using @p Broadcast().
+ *
+ * @param mask the events to be pended
+ * @return The current pending events mask.
+ */
+ static eventmask_t Pend(eventmask_t mask);
+
+ /**
+ * @brief Invokes the event handlers associated with a mask.
+ *
+ * @param mask mask of the events to be dispatched
+ * @param handlers an array of @p evhandler_t. The array must be
+ * have indexes from zero up the higher registered event
+ * identifier.
+ */
+ static void Dispatch(const evhandler_t handlers[], eventmask_t mask);
+
+ /**
+ * @brief Waits for a single event.
+ * @details A pending event among those specified in @p ewmask is selected,
+ * cleared and its mask returned.
+ *
+ * @param ewmask mask of the events that the function should wait for,
+ * @p ALL_EVENTS enables all the events
+ * @return The mask of the lowest id served and cleared event.
+ * @note One and only one event is served in the function, the one with the
+ * lowest event id. The function is meant to be invoked into a loop in
+ * order to serve all the pending events.<br>
+ * This means that Event Listeners with a lower event identifier have
+ * an higher priority.
+ */
+ static eventmask_t WaitOne(eventmask_t ewmask);
+
+ /**
+ * @brief Waits for any of the specified events.
+ * @details The function waits for any event among those specified in
+ * @p ewmask to become pending then the events are cleared and returned.
+ *
+ * @param ewmask mask of the events that the function should wait for,
+ * @p ALL_EVENTS enables all the events
+ * @return The mask of the served and cleared events.
+ */
+ static eventmask_t WaitAny(eventmask_t ewmask);
+
+ /**
+ * @brief Waits for all the specified event flags then clears them.
+ * @details The function waits for all the events specified in @p ewmask
+ * to become pending then the events are cleared and returned.
+ *
+ * @param ewmask mask of the event ids that the function should wait for
+ * @return The mask of the served and cleared events.
+ */
+ static eventmask_t WaitAll(eventmask_t ewmask);
+
+#if CH_USE_EVENTS_TIMEOUT
+ /**
+ * @brief Waits for a single event.
+ * @details A pending event among those specified in @p ewmask is selected,
+ * cleared and its mask returned.
+ * @param ewmask mask of the events that the function should wait for,
+ * @p ALL_EVENTS enables all the events
+ * @param time the number of ticks before the operation timouts
+ * @return The mask of the lowest id served and cleared event.
+ * @retval 0 if the specified timeout expired.
+ * @note One and only one event is served in the function, the one with the
+ * lowest event id. The function is meant to be invoked into a loop in
+ * order to serve all the pending events.<br>
+ * This means that Event Listeners with a lower event identifier have
+ * an higher priority.
+ */
+ static eventmask_t WaitOneTimeout(eventmask_t ewmask, systime_t time);
+
+ /**
+ * @brief Waits for any of the specified events.
+ * @details The function waits for any event among those specified in
+ * @p ewmask to become pending then the events are cleared and returned.
+ *
+ * @param ewmask mask of the events that the function should wait for,
+ * @p ALL_EVENTS enables all the events
+ * @param time the number of ticks before the operation timouts
+ * @return The mask of the served and cleared events.
+ * @retval 0 if the specified timeout expired.
+ */
+ static eventmask_t WaitAnyTimeout(eventmask_t ewmask, systime_t time);
+
+ /**
+ * @brief Waits for all the specified event flags then clears them.
+ * @details The function waits for all the events specified in @p ewmask
+ * to become pending then the events are cleared and returned.
+ *
+ * @param ewmask mask of the event ids that the function should wait for
+ * @param time the number of ticks before the operation timouts
+ * @return The mask of the served and cleared events.
+ * @retval 0 if the specified timeout expired.
+ */
+ static eventmask_t WaitAllTimeout(eventmask_t ewmask, systime_t time);
+
+#endif /* CH_USE_EVENTS_TIMEOUT */
+ };
+#endif /* CH_USE_EVENTS */
+}
+
+#endif /* _CH_HPP_ */
+
+/** @} */
diff --git a/os/various/evtimer.c b/os/various/evtimer.c
new file mode 100644
index 000000000..114a9b3a6
--- /dev/null
+++ b/os/various/evtimer.c
@@ -0,0 +1,70 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT 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 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT 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, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file evtimer.c
+ * @brief Events Generator Timer code.
+ * @addtogroup event_timer
+ * @{
+ */
+
+#include <ch.h>
+
+#include "evtimer.h"
+
+static void tmrcb(void *p) {
+ EvTimer *etp = p;
+
+ chEvtBroadcastI(&etp->et_es);
+ chVTSetI(&etp->et_vt, etp->et_interval, tmrcb, etp);
+}
+
+/**
+ * @brief Starts the timer
+ * @details If the timer was already running then the function has no effect.
+ *
+ * @param etp pointer to an initialized @p EvTimer structure.
+ */
+void evtStart(EvTimer *etp) {
+
+ chSysLock();
+
+ if (!chVTIsArmedI(&etp->et_vt))
+ chVTSetI(&etp->et_vt, etp->et_interval, tmrcb, etp);
+
+ chSysUnlock();
+}
+
+/**
+ * @brief Stops the timer.
+ * @details If the timer was already stopped then the function has no effect.
+ *
+ * @param etp pointer to an initialized @p EvTimer structure.
+ */
+void evtStop(EvTimer *etp) {
+
+ chSysLock();
+
+ if (chVTIsArmedI(&etp->et_vt))
+ chVTResetI(&etp->et_vt);
+
+ chSysUnlock();
+}
+
+/** @} */
diff --git a/os/various/evtimer.h b/os/various/evtimer.h
new file mode 100644
index 000000000..acfc97eb1
--- /dev/null
+++ b/os/various/evtimer.h
@@ -0,0 +1,62 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT 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 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT 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, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file evtimer.h
+ * @brief Events Generator Timer structures and macros.
+ * @addtogroup event_timer
+ * @{
+ */
+
+#ifndef _EVTIMER_H_
+#define _EVTIMER_H_
+
+/**
+ * @brief Event timer structure.
+ */
+typedef struct {
+ VirtualTimer et_vt;
+ EventSource et_es;
+ systime_t et_interval;
+} EvTimer;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void evtStart(EvTimer *etp);
+ void evtStop(EvTimer *etp);
+#ifdef __cplusplus
+}
+#endif
+
+/**
+ * @brief Initializes an @p EvTimer structure.
+ *
+ * @param etp the EvTimer structure to be initialized
+ * @param time the interval in system ticks
+ */
+#define evtInit(etp, time) { \
+ chEvtInit(&(etp)->et_es); \
+ (etp)->et_vt.vt_func = NULL; \
+ (etp)->et_interval = (time); \
+}
+
+#endif /* _EVTIMER_H_ */
+
+/** @} */
diff --git a/readme.txt b/readme.txt
index 6852db3ec..eab5bfbd2 100644
--- a/readme.txt
+++ b/readme.txt
@@ -64,13 +64,14 @@ GNU-Linux-GCC - ChibiOS/RT simulator for x86 Linux systems, it is
*****************************************************************************
*** 1.3.2 ***
+- NEW: Reorganized and rationalized the distribution three.
- NEW: Added standard CMSIS 1.2.0 support to the Cortex-M3 port. The kernel
does not use it (the OS uses its own optimized code) but the functionality
is available to the applications. The CMSIS files were patched in order
to correct some warnings.
- NEW: Updated the STM32 port to use the newest ST firmware library files
(version 3.1.0). Note that now the ST drivers are included in the STM32
- demo.
+ demo directory.
*** 1.3.1 ***
- FIX: Removed mention of an obsolete option from the documentation (bug
diff --git a/test/coverage/Makefile b/test/coverage/Makefile
index 687d73233..a00e5015a 100644
--- a/test/coverage/Makefile
+++ b/test/coverage/Makefile
@@ -57,19 +57,21 @@ UDEFS =
UADEFS =
# Imported source files
-include ../../src/kernel.mk
+include ../../os/kernel/kernel.mk
include ../../test/test.mk
# List C source files here
-SRC = chcore.c main.c simcom.c \
- ${KERNSRC} \
- ${TESTSRC}
+SRC = ${KERNSRC} \
+ ${TESTSRC} \
+ chcore.c \
+ simcom.c \
+ main.c
# List ASM source files here
ASRC =
# List all user directories here
-UINCDIR = ../../src/include ../../test
+UINCDIR = $(KERNINC) $(TESTINC)
# List the user directory to look for the libraries here
ULIBDIR =