summaryrefslogtreecommitdiff
path: root/ucoo/arch
diff options
context:
space:
mode:
Diffstat (limited to 'ucoo/arch')
-rw-r--r--ucoo/arch/Module2
-rw-r--r--ucoo/arch/arch.arm.hh37
-rw-r--r--ucoo/arch/arch.hh16
-rw-r--r--ucoo/arch/arch.host.hh35
-rw-r--r--ucoo/arch/arch.stm32.cc4
-rw-r--r--ucoo/arch/arch.stm32f1.cc13
-rw-r--r--ucoo/arch/arch.stm32f4.cc16
-rw-r--r--ucoo/arch/arch_common.arm.hh4
-rw-r--r--ucoo/arch/arch_common.hh8
-rw-r--r--ucoo/arch/arch_common.host.hh4
-rw-r--r--ucoo/arch/interrupt.arm.hh107
-rw-r--r--ucoo/arch/interrupt.stm32f1.hh104
-rw-r--r--ucoo/arch/interrupt.stm32f4.hh127
-rw-r--r--ucoo/arch/ld/common.ld67
-rw-r--r--ucoo/arch/ld/stm32f1.ld (renamed from ucoo/arch/stm32f1/stm32f1.ld)2
-rw-r--r--ucoo/arch/ld/stm32f4.ld (renamed from ucoo/arch/stm32f4/stm32f4.ld)2
-rw-r--r--ucoo/arch/rcc.stm32.hh36
-rw-r--r--ucoo/arch/rcc.stm32f1.cc134
-rw-r--r--ucoo/arch/rcc.stm32f1.hh143
-rw-r--r--ucoo/arch/rcc.stm32f4.cc125
-rw-r--r--ucoo/arch/rcc.stm32f4.hh193
-rw-r--r--ucoo/arch/reg.hh35
-rw-r--r--ucoo/arch/reg.stm32.hh80
-rw-r--r--ucoo/arch/reg.stm32f1.hh180
-rw-r--r--ucoo/arch/reg.stm32f4.hh347
-rw-r--r--ucoo/arch/vector.arm.cc136
-rw-r--r--ucoo/arch/vector.stm32f1.hh220
-rw-r--r--ucoo/arch/vector.stm32f4.hh307
28 files changed, 2451 insertions, 33 deletions
diff --git a/ucoo/arch/Module b/ucoo/arch/Module
index 9a4989e..625cfd3 100644
--- a/ucoo/arch/Module
+++ b/ucoo/arch/Module
@@ -1,3 +1,5 @@
ucoo_arch_SOURCES := arch.host.cc \
arch.stm32.cc arch.stm32f1.cc arch.stm32f4.cc \
+ rcc.stm32f1.cc rcc.stm32f4.cc \
+ vector.arm.cc \
syscalls.newlib.cc syscalls.cc
diff --git a/ucoo/arch/arch.arm.hh b/ucoo/arch/arch.arm.hh
new file mode 100644
index 0000000..65c835d
--- /dev/null
+++ b/ucoo/arch/arch.arm.hh
@@ -0,0 +1,37 @@
+#ifndef ucoo_arch_arch_arm_hh
+#define ucoo_arch_arch_arm_hh
+// ucoolib - Microcontroller object oriented library. {{{
+//
+// Copyright (C) 2016 Nicolas Schodet
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+//
+// }}}
+
+namespace ucoo {
+
+static inline void
+arch_dsb ()
+{
+ __asm__ __volatile__ ("dsb" : : : "memory");
+}
+
+} // namespace ucoo
+
+#endif // ucoo_arch_arch_arm_hh
diff --git a/ucoo/arch/arch.hh b/ucoo/arch/arch.hh
index e0889bd..2401868 100644
--- a/ucoo/arch/arch.hh
+++ b/ucoo/arch/arch.hh
@@ -24,6 +24,14 @@
//
// }}}
+#if defined (TARGET_arm)
+# include "arch.arm.hh"
+#elif defined (TARGET_host)
+# include "arch.host.hh"
+#else
+# error "not implemented for this target"
+#endif
+
namespace ucoo {
/// Initialise arch, take program arguments.
@@ -34,14 +42,6 @@ arch_init (int argc, const char **argv);
void
arch_reset ();
-#ifdef TARGET_host
-
-/// Retrieve program arguments.
-void
-arch_get_args (int &argc, const char **&argv);
-
-#endif
-
} // namespace ucoo
#endif // ucoo_arch_arch_hh
diff --git a/ucoo/arch/arch.host.hh b/ucoo/arch/arch.host.hh
new file mode 100644
index 0000000..b08864e
--- /dev/null
+++ b/ucoo/arch/arch.host.hh
@@ -0,0 +1,35 @@
+#ifndef ucoo_arch_arch_host_hh
+#define ucoo_arch_arch_host_hh
+// ucoolib - Microcontroller object oriented library. {{{
+//
+// Copyright (C) 2016 Nicolas Schodet
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+//
+// }}}
+
+namespace ucoo {
+
+/// Retrieve program arguments.
+void
+arch_get_args (int &argc, const char **&argv);
+
+} // namespace ucoo
+
+#endif // ucoo_arch_arch_host_hh
diff --git a/ucoo/arch/arch.stm32.cc b/ucoo/arch/arch.stm32.cc
index aa07575..f48f9fc 100644
--- a/ucoo/arch/arch.stm32.cc
+++ b/ucoo/arch/arch.stm32.cc
@@ -24,14 +24,14 @@
#include "ucoo/arch/arch.hh"
#include "ucoo/common.hh"
-#include <libopencm3/cm3/scb.h>
+#include "ucoo/arch/reg.hh"
namespace ucoo {
void
arch_reset ()
{
- SCB_AIRCR = SCB_AIRCR_VECTKEY | SCB_AIRCR_SYSRESETREQ;
+ NVIC_SystemReset ();
}
void
diff --git a/ucoo/arch/arch.stm32f1.cc b/ucoo/arch/arch.stm32f1.cc
index a2d659c..ca6664b 100644
--- a/ucoo/arch/arch.stm32f1.cc
+++ b/ucoo/arch/arch.stm32f1.cc
@@ -22,17 +22,20 @@
//
// }}}
#include "ucoo/arch/arch.hh"
-#include "ucoo/common.hh"
-
-#include <libopencm3/stm32/rcc.h>
+#include "ucoo/arch/rcc.stm32.hh"
namespace ucoo {
void
arch_init (int argc, const char **argv)
{
- rcc_clock_setup_in_hse_12mhz_out_72mhz ();
- rcc_periph_clock_enable (RCC_AFIO);
+ rcc_sys_clock_setup_pll (72000000, 12000000,
+ 1, // prediv1 => 12 MHz / 1 = 12 MHz
+ 6, // pllmul => 12 MHz * 6 = 72 MHz
+ 2, // apb1_pre => 36 MHz
+ 1, // apb2_pre => 72 MHz
+ 6); // adc_pre => 12 MHz
+ rcc_peripheral_clock_enable (Rcc::AFIO);
}
} // namespace ucoo
diff --git a/ucoo/arch/arch.stm32f4.cc b/ucoo/arch/arch.stm32f4.cc
index 74c7306..c569c65 100644
--- a/ucoo/arch/arch.stm32f4.cc
+++ b/ucoo/arch/arch.stm32f4.cc
@@ -22,18 +22,22 @@
//
// }}}
#include "ucoo/arch/arch.hh"
-#include "ucoo/common.hh"
-
-#include <libopencm3/stm32/rcc.h>
+#include "ucoo/arch/rcc.stm32.hh"
namespace ucoo {
void
arch_init (int argc, const char **argv)
{
- rcc_clock_setup_hse_3v3 (&hse_8mhz_3v3[CLOCK_3V3_120MHZ]);
- rcc_ahb_frequency = 120000000;
- rcc_periph_clock_enable (RCC_SYSCFG);
+ rcc_sys_clock_setup_pll (120000000, 8000000,
+ 4, // pllm => 8 MHz / 4 = 2 MHz
+ 120, // plln => 2 MHz * 120 = 240 MHz
+ 2, // pllp => 240 MHz / 2 = 120 MHz
+ 5, // pllq => 240 MHz / 5 = 48 MHz
+ 4, // apb1_pre => 30 MHz
+ 2, // apb2_pre => 60 MHz
+ SupplyRange::V2_7);
+ rcc_peripheral_clock_enable (Rcc::SYSCFG);
}
} // namespace ucoo
diff --git a/ucoo/arch/arch_common.arm.hh b/ucoo/arch/arch_common.arm.hh
index 7b4abfd..b1c7138 100644
--- a/ucoo/arch/arch_common.arm.hh
+++ b/ucoo/arch/arch_common.arm.hh
@@ -29,6 +29,7 @@ namespace ucoo {
/// Type used to save irq state.
typedef unsigned int irq_flags_t;
+/// Lock interrupts and return previous state.
static inline irq_flags_t
irq_lock (void)
{
@@ -40,7 +41,8 @@ irq_lock (void)
return flags;
}
-inline void
+/// Restore interrupts lock state after an irq_lock.
+static inline void
irq_restore (irq_flags_t flags)
{
__asm__ __volatile__ ("msr PRIMASK, %0"
diff --git a/ucoo/arch/arch_common.hh b/ucoo/arch/arch_common.hh
index ac70e62..dd8458c 100644
--- a/ucoo/arch/arch_common.hh
+++ b/ucoo/arch/arch_common.hh
@@ -32,12 +32,4 @@
# error "not implemented for this target"
#endif
-namespace ucoo {
-
-/// Give some time to other tasks when running in a tight loop.
-void
-yield ();
-
-} // namespace ucoo
-
#endif // ucoo_arch_arch_common_hh
diff --git a/ucoo/arch/arch_common.host.hh b/ucoo/arch/arch_common.host.hh
index 0ee2553..7130a0d 100644
--- a/ucoo/arch/arch_common.host.hh
+++ b/ucoo/arch/arch_common.host.hh
@@ -29,6 +29,7 @@ namespace ucoo {
/// Type used to save irq state.
typedef unsigned int irq_flags_t;
+/// Lock interrupts and return previous state.
static inline irq_flags_t
irq_lock (void)
{
@@ -36,7 +37,8 @@ irq_lock (void)
return 0;
}
-inline void
+/// Restore interrupts lock state after an irq_lock.
+static inline void
irq_restore (irq_flags_t)
{
// Nothing on host, there is no interrupts.
diff --git a/ucoo/arch/interrupt.arm.hh b/ucoo/arch/interrupt.arm.hh
new file mode 100644
index 0000000..10ef261
--- /dev/null
+++ b/ucoo/arch/interrupt.arm.hh
@@ -0,0 +1,107 @@
+#ifndef ucoo_arch_interrupt_arm_hh
+#define ucoo_arch_interrupt_arm_hh
+// ucoolib - Microcontroller object oriented library. {{{
+//
+// Copyright (C) 2016 Nicolas Schodet
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+//
+// }}}
+#include "ucoo/arch/reg.hh"
+
+#if defined (TARGET_stm32f4)
+# include "ucoo/arch/interrupt.stm32f4.hh"
+#elif defined (TARGET_stm32f1)
+# include "ucoo/arch/interrupt.stm32f1.hh"
+#else
+# error "not implemented for this target"
+#endif
+
+namespace ucoo {
+
+/// Standard ARM Cortex exceptions.
+enum class Exception
+{
+ RESET = 1,
+ NMI = 2,
+ HARD_FAULT = 3,
+ MEMORY_MANAGEMENT_FAULT = 4,
+ BUS_FAULT = 5,
+ USAGE_FAULT = 6,
+ SV_CALL = 11,
+ PEND_SV = 14,
+ SYSTICK = 15,
+ COUNT
+};
+
+/// Exception vectors are a specialisation of this template.
+template<Exception>
+void
+interrupt ();
+
+/// IRQ vectors are a specialisation of this template.
+template<Irq>
+void
+interrupt ();
+
+/// Enable interrupt source.
+static inline void
+interrupt_enable (Irq irq)
+{
+ const unsigned int n = static_cast<unsigned int> (irq);
+ NVIC->ISER[n / 32] = 1 << (n % 32);
+}
+
+/// Disable interrupt source.
+static inline void
+interrupt_disable (Irq irq)
+{
+ const unsigned int n = static_cast<unsigned int> (irq);
+ NVIC->ICER[n / 32] = 1 << (n % 32);
+}
+
+/// Test if a interrupt source is enabled.
+static inline bool
+interrupt_is_enabled (Irq irq)
+{
+ const unsigned int n = static_cast<unsigned int> (irq);
+ return NVIC->ISER[n / 32] & (1 << (n % 32));
+}
+
+/// Set interrupt priority. Warning: a limited number of MSB bits are used
+/// depending on the hardware implementation.
+static inline void
+interrupt_set_priority (Irq irq, uint8_t priority)
+{
+ const unsigned int n = static_cast<unsigned int> (irq);
+ NVIC->IP[n] = priority;
+}
+
+/// Set exception priority. Warning: a limited number of MSB bits are used
+/// depending on the hardware implementation.
+static inline void
+interrupt_set_priority (Exception ex, uint8_t priority)
+{
+ const unsigned int n = static_cast<unsigned int> (ex);
+ SCB->SHP[n - 4] = priority;
+}
+
+} // namespace ucoo
+
+#endif // ucoo_arch_interrupt_arm_hh
diff --git a/ucoo/arch/interrupt.stm32f1.hh b/ucoo/arch/interrupt.stm32f1.hh
new file mode 100644
index 0000000..74316ce
--- /dev/null
+++ b/ucoo/arch/interrupt.stm32f1.hh
@@ -0,0 +1,104 @@
+#ifndef ucoo_arch_interrupt_stm32f1_hh
+#define ucoo_arch_interrupt_stm32f1_hh
+// ucoolib - Microcontroller object oriented library. {{{
+//
+// Copyright (C) 2016 Nicolas Schodet
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+//
+// }}}
+
+namespace ucoo {
+
+enum class Irq
+{
+ WWDG,
+ PVD,
+ TAMPER,
+ RTC,
+ FLASH,
+ RCC,
+ EXTI0,
+ EXTI1,
+ EXTI2,
+ EXTI3,
+ EXTI4,
+ DMA1_Channel1,
+ DMA1_Channel2,
+ DMA1_Channel3,
+ DMA1_Channel4,
+ DMA1_Channel5,
+ DMA1_Channel6,
+ DMA1_Channel7,
+ ADC1_2,
+ CAN1_TX,
+ CAN1_RX0,
+ CAN1_RX1,
+ CAN1_SCE,
+ EXTI9_5,
+ TIM1_BRK,
+ TIM1_UP,
+ TIM1_TRG_COM,
+ TIM1_CC,
+ TIM2,
+ TIM3,
+ TIM4,
+ I2C1_EV,
+ I2C1_ER,
+ I2C2_EV,
+ I2C2_ER,
+ SPI1,
+ SPI2,
+ USART1,
+ USART2,
+ USART3,
+ EXTI15_10,
+ RTC_Alarm,
+ OTG_FS_WKUP,
+ RESERVED_43,
+ RESERVED_44,
+ RESERVED_45,
+ RESERVED_46,
+ RESERVED_47,
+ RESERVED_48,
+ RESERVED_49,
+ TIM5,
+ SPI3,
+ UART4,
+ UART5,
+ TIM6,
+ TIM7,
+ DMA2_Channel1,
+ DMA2_Channel2,
+ DMA2_Channel3,
+ DMA2_Channel4,
+ DMA2_Channel5,
+ RESERVED_61,
+ RESERVED_62,
+ CAN2_TX,
+ CAN2_RX0,
+ CAN2_RX1,
+ CAN2_SCE,
+ OTG_FS,
+ COUNT
+};
+
+} // namespace ucoo
+
+#endif // ucoo_arch_interrupt_stm32f1_hh
diff --git a/ucoo/arch/interrupt.stm32f4.hh b/ucoo/arch/interrupt.stm32f4.hh
new file mode 100644
index 0000000..ffd3912
--- /dev/null
+++ b/ucoo/arch/interrupt.stm32f4.hh
@@ -0,0 +1,127 @@
+#ifndef ucoo_arch_interrupt_stm32f4_hh
+#define ucoo_arch_interrupt_stm32f4_hh
+// ucoolib - Microcontroller object oriented library. {{{
+//
+// Copyright (C) 2016 Nicolas Schodet
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+//
+// }}}
+
+namespace ucoo {
+
+enum class Irq
+{
+ WWDG,
+ PVD,
+ TAMP_STAMP,
+ RTC_WKUP,
+ FLASH,
+ RCC,
+ EXTI0,
+ EXTI1,
+ EXTI2,
+ EXTI3,
+ EXTI4,
+ DMA1_Stream0,
+ DMA1_Stream1,
+ DMA1_Stream2,
+ DMA1_Stream3,
+ DMA1_Stream4,
+ DMA1_Stream5,
+ DMA1_Stream6,
+ ADC,
+ CAN1_TX,
+ CAN1_RX0,
+ CAN1_RX1,
+ CAN1_SCE,
+ EXTI9_5,
+ TIM1_BRK_TIM9,
+ TIM1_UP_TIM10,
+ TIM1_TRG_COM_TIM11,
+ TIM1_CC,
+ TIM2,
+ TIM3,
+ TIM4,
+ I2C1_EV,
+ I2C1_ER,
+ I2C2_EV,
+ I2C2_ER,
+ SPI1,
+ SPI2,
+ USART1,
+ USART2,
+ USART3,
+ EXTI15_10,
+ RTC_Alarm,
+ OTG_FS_WKUP,
+ TIM8_BRK_TIM12,
+ TIM8_UP_TIM13,
+ TIM8_TRG_COM_TIM14,
+ TIM8_CC,
+ DMA1_Stream7,
+ FMC,
+ SDIO,
+ TIM5,
+ SPI3,
+ UART4,
+ UART5,
+ TIM6_DAC,
+ TIM7,
+ DMA2_Stream0,
+ DMA2_Stream1,
+ DMA2_Stream2,
+ DMA2_Stream3,
+ DMA2_Stream4,
+ ETH,
+ ETH_WKUP,
+ CAN2_TX,
+ CAN2_RX0,
+ CAN2_RX1,
+ CAN2_SCE,
+ OTG_FS,
+ DMA2_Stream5,
+ DMA2_Stream6,
+ DMA2_Stream7,
+ USART6,
+ I2C3_EV,
+ I2C3_ER,
+ OTG_HS_EP1_OUT,
+ OTG_HS_EP1_IN,
+ OTG_HS_WKUP,
+ OTG_HS,
+ DCMI,
+ CRYP,
+ HASH_RNG,
+ FPU,
+ UART7,
+ UART8,
+ SPI4,
+ SPI5,
+ SPI6,
+ SAI1,
+ LTDC,
+ LTDC_ER,
+ DMA2D,
+ COUNT
+};
+
+} // namespace ucoo
+
+#endif // ucoo_arch_interrupt_stm32f4_hh
diff --git a/ucoo/arch/ld/common.ld b/ucoo/arch/ld/common.ld
new file mode 100644
index 0000000..8b5efb2
--- /dev/null
+++ b/ucoo/arch/ld/common.ld
@@ -0,0 +1,67 @@
+ENTRY(entry)
+
+SECTIONS
+{
+ .text : {
+ KEEP(*(.vectors))
+ *(.text*)
+ . = ALIGN(4);
+ *(.rodata*)
+ . = ALIGN(4);
+ } >rom
+
+ .preinit_array : {
+ . = ALIGN(4);
+ __preinit_array_start = .;
+ KEEP (*(.preinit_array))
+ __preinit_array_end = .;
+ } >rom
+ .init_array : {
+ . = ALIGN(4);
+ __init_array_start = .;
+ KEEP (*(SORT(.init_array.*)))
+ KEEP (*(.init_array))
+ __init_array_end = .;
+ } >rom
+ .fini_array : {
+ . = ALIGN(4);
+ __fini_array_start = .;
+ KEEP (*(.fini_array))
+ KEEP (*(SORT(.fini_array.*)))
+ __fini_array_end = .;
+ } >rom
+
+ .ARM.extab : {
+ *(.ARM.extab*)
+ } >rom
+ .ARM.exidx : {
+ __exidx_start = .;
+ *(.ARM.exidx*)
+ __exidx_end = .;
+ } >rom
+
+ . = ALIGN(4);
+ _etext = .;
+
+ .data : {
+ _data = .;
+ *(.data*)
+ . = ALIGN(4);
+ _edata = .;
+ } >ram AT >rom
+ _data_loadaddr = LOADADDR(.data);
+
+ .bss : {
+ *(.bss*)
+ *(COMMON)
+ . = ALIGN(4);
+ _ebss = .;
+ } >ram
+
+ /DISCARD/ : { *(.eh_frame) }
+
+ . = ALIGN(4);
+ end = .;
+}
+
+PROVIDE(_stack = ORIGIN(ram) + LENGTH(ram));
diff --git a/ucoo/arch/stm32f1/stm32f1.ld b/ucoo/arch/ld/stm32f1.ld
index de413c4..2231ccb 100644
--- a/ucoo/arch/stm32f1/stm32f1.ld
+++ b/ucoo/arch/ld/stm32f1.ld
@@ -3,4 +3,4 @@ MEMORY
rom (rx) : ORIGIN = 0x08000000, LENGTH = 256K
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 64K
}
-INCLUDE libopencm3_stm32f1.ld
+INCLUDE common.ld
diff --git a/ucoo/arch/stm32f4/stm32f4.ld b/ucoo/arch/ld/stm32f4.ld
index ceef7af..f752426 100644
--- a/ucoo/arch/stm32f4/stm32f4.ld
+++ b/ucoo/arch/ld/stm32f4.ld
@@ -3,4 +3,4 @@ MEMORY
rom (rx) : ORIGIN = 0x08000000, LENGTH = 1024K
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 128K
}
-INCLUDE libopencm3_stm32f4.ld
+INCLUDE common.ld
diff --git a/ucoo/arch/rcc.stm32.hh b/ucoo/arch/rcc.stm32.hh
new file mode 100644
index 0000000..ac8f76c
--- /dev/null
+++ b/ucoo/arch/rcc.stm32.hh
@@ -0,0 +1,36 @@
+#ifndef ucoo_arch_rcc_stm32_hh
+#define ucoo_arch_rcc_stm32_hh
+// ucoolib - Microcontroller object oriented library. {{{
+//
+// Copyright (C) 2016 Nicolas Schodet
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+//
+// }}}
+
+#if defined (TARGET_stm32f4)
+# include "rcc.stm32f4.hh"
+#elif defined (TARGET_stm32f1)
+# include "rcc.stm32f1.hh"
+#else
+# error "not implemented for this target"
+#endif
+
+
+#endif // ucoo_arch_rcc_stm32_hh
diff --git a/ucoo/arch/rcc.stm32f1.cc b/ucoo/arch/rcc.stm32f1.cc
new file mode 100644
index 0000000..3b88e9b
--- /dev/null
+++ b/ucoo/arch/rcc.stm32f1.cc
@@ -0,0 +1,134 @@
+// ucoolib - Microcontroller object oriented library. {{{
+//
+// Copyright (C) 2016 Nicolas Schodet
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+//
+// }}}
+#include "ucoo/arch/rcc.stm32f1.hh"
+#include "ucoo/common.hh"
+#include "ucoo/utils/table_lookup.hh"
+
+namespace ucoo {
+
+static const int hsi_freq_hz = 8000000;
+
+int rcc_sys_freq_hz = hsi_freq_hz;
+int rcc_ahb_freq_hz = hsi_freq_hz;
+int rcc_apb1_freq_hz = hsi_freq_hz;
+int rcc_apb2_freq_hz = hsi_freq_hz;
+int rcc_apb1_timer_freq_hz = hsi_freq_hz;
+int rcc_apb2_timer_freq_hz = hsi_freq_hz;
+int rcc_usb_freq_hz = 0;
+
+void
+rcc_sys_clock_setup_pll (int sys_freq_hz, int hse_freq_hz,
+ int prediv1, int pllmul,
+ int apb1_pre, int apb2_pre, int adc_pre)
+{
+ // Switch to HSI as a safe fall back.
+ reg::RCC->CR |= RCC_CR_HSION;
+ while (!(reg::RCC->CR & RCC_CR_HSIRDY))
+ ;
+ reg::RCC->CFGR = (reg::RCC->CFGR & ~RCC_CFGR_SW) | RCC_CFGR_SW_HSI;
+ while ((reg::RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_HSI)
+ ;
+ // Start HSE if needed.
+ uint32_t pllsrc = 0;
+ int pll_in_freq_hz = hsi_freq_hz / 2;
+ if (hse_freq_hz)
+ {
+ pll_in_freq_hz = hse_freq_hz;
+ pllsrc = RCC_CFGR_PLLSRC;
+ reg::RCC->CR |= RCC_CR_HSEON;
+ while (!(reg::RCC->CR & RCC_CR_HSERDY))
+ ;
+ // May divide by 2.
+ assert (prediv1 == 1 || prediv1 == 2);
+ if (prediv1 == 2)
+ {
+ pllsrc |= RCC_CFGR_PLLXTPRE;
+ pll_in_freq_hz /= 2;
+ }
+ }
+ // Change buses and ADC prescalers.
+ static const LookupTable<int, uint32_t> adc_pre_table[] =
+ {
+ { 2, RCC_CFGR_ADCPRE_DIV2 },
+ { 4, RCC_CFGR_ADCPRE_DIV4 },
+ { 6, RCC_CFGR_ADCPRE_DIV6 },
+ { 8, RCC_CFGR_ADCPRE_DIV8 },
+ };
+ static const LookupTable<int, uint32_t> apb1_pre_table[] =
+ {
+ { 1, RCC_CFGR_PPRE1_DIV1 },
+ { 2, RCC_CFGR_PPRE1_DIV2 },
+ { 4, RCC_CFGR_PPRE1_DIV4 },
+ { 8, RCC_CFGR_PPRE1_DIV8 },
+ { 16, RCC_CFGR_PPRE1_DIV16 },
+ };
+ static const LookupTable<int, uint32_t> apb2_pre_table[] =
+ {
+ { 1, RCC_CFGR_PPRE2_DIV1 },
+ { 2, RCC_CFGR_PPRE2_DIV2 },
+ { 4, RCC_CFGR_PPRE2_DIV4 },
+ { 8, RCC_CFGR_PPRE2_DIV8 },
+ { 16, RCC_CFGR_PPRE2_DIV16 },
+ };
+ uint32_t pre = simple_table_lookup (adc_pre_table, adc_pre)
+ | simple_table_lookup (apb1_pre_table, apb1_pre)
+ | simple_table_lookup (apb2_pre_table, apb2_pre);
+ // Start PLL.
+ static const LookupTable<int, uint32_t> pllmul_table[] =
+ {
+ { 4, RCC_CFGR_PLLMULL4 },
+ { 5, RCC_CFGR_PLLMULL5 },
+ { 6, RCC_CFGR_PLLMULL6 },
+ { 7, RCC_CFGR_PLLMULL7 },
+ { 8, RCC_CFGR_PLLMULL8 },
+ { 9, RCC_CFGR_PLLMULL9 },
+ // Other values (2, 3, 10...16 or 6.5 on connectivity line) not
+ // handled.
+ };
+ reg::RCC->CFGR = (reg::RCC->CFGR & ~(
+ RCC_CFGR_PLLMULL | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLSRC
+ | RCC_CFGR_ADCPRE_Msk | RCC_CFGR_PPRE1_Msk | RCC_CFGR_PPRE2_Msk))
+ | pllsrc | pre | simple_table_lookup (pllmul_table, pllmul);
+ reg::RCC->CR |= RCC_CR_PLLON;
+ while (!(reg::RCC->CR & RCC_CR_PLLRDY))
+ ;
+ // Setup flash.
+ int mhz_per_ws = 24;
+ int ws = (sys_freq_hz - 1) / 1000000 / mhz_per_ws;
+ reg::FLASH->ACR = (reg::FLASH->ACR & ~FLASH_ACR_LATENCY) | ws;
+ // Switch to PLL.
+ reg::RCC->CFGR = (reg::RCC->CFGR & ~RCC_CFGR_SW) | RCC_CFGR_SW_PLL;
+ while ((reg::RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_PLL)
+ ;
+ // Update frequencies.
+ assert (pll_in_freq_hz * pllmul == sys_freq_hz);
+ rcc_ahb_freq_hz = rcc_sys_freq_hz = sys_freq_hz;
+ rcc_apb1_freq_hz = sys_freq_hz / apb1_pre;
+ rcc_apb2_freq_hz = sys_freq_hz / apb2_pre;
+ rcc_apb1_timer_freq_hz = rcc_apb1_freq_hz * (apb1_pre == 1 ? 1 : 2);
+ rcc_apb2_timer_freq_hz = rcc_apb2_freq_hz * (apb2_pre == 1 ? 1 : 2);
+ rcc_usb_freq_hz = sys_freq_hz * 2 / 3;
+}
+
+} // namespace ucoo
diff --git a/ucoo/arch/rcc.stm32f1.hh b/ucoo/arch/rcc.stm32f1.hh
new file mode 100644
index 0000000..3896752
--- /dev/null
+++ b/ucoo/arch/rcc.stm32f1.hh
@@ -0,0 +1,143 @@
+#ifndef ucoo_arch_rcc_stm32f1_hh
+#define ucoo_arch_rcc_stm32f1_hh
+// ucoolib - Microcontroller object oriented library. {{{
+//
+// Copyright (C) 2016 Nicolas Schodet
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+//
+// }}}
+#include "ucoo/arch/arch.hh"
+#include "ucoo/arch/reg.hh"
+
+namespace ucoo {
+
+enum class Bus
+{
+ AHB = 0,
+ APB1 = 2,
+ APB2 = 1,
+};
+
+namespace details {
+
+constexpr uint32_t
+rcc_enum (Bus bus, uint32_t bit, int pos = 0)
+{
+ return bit == 1
+ ? (static_cast<uint32_t> (bus) << 5) | pos
+ : rcc_enum (bus, (bit >> 1) | (bit << 31), pos + 1);
+}
+
+} // namespace details
+
+/// Constants to handle reset and clock for each peripheral.
+enum class Rcc
+{
+ DMA1 = details::rcc_enum (Bus::AHB, RCC_AHBENR_DMA1EN),
+ DMA2 = details::rcc_enum (Bus::AHB, RCC_AHBENR_DMA2EN),
+ SRAM = details::rcc_enum (Bus::AHB, RCC_AHBENR_SRAMEN),
+ FLITF = details::rcc_enum (Bus::AHB, RCC_AHBENR_FLITFEN),
+ CRC = details::rcc_enum (Bus::AHB, RCC_AHBENR_CRCEN),
+ OTGFS = details::rcc_enum (Bus::AHB, RCC_AHBENR_OTGFSEN),
+ AFIO = details::rcc_enum (Bus::APB2, RCC_APB2ENR_AFIOEN),
+ GPIOA = details::rcc_enum (Bus::APB2, RCC_APB2ENR_IOPAEN),
+ GPIOB = details::rcc_enum (Bus::APB2, RCC_APB2ENR_IOPBEN),
+ GPIOC = details::rcc_enum (Bus::APB2, RCC_APB2ENR_IOPCEN),
+ GPIOD = details::rcc_enum (Bus::APB2, RCC_APB2ENR_IOPDEN),
+ GPIOE = details::rcc_enum (Bus::APB2, RCC_APB2ENR_IOPEEN),
+ ADC1 = details::rcc_enum (Bus::APB2, RCC_APB2ENR_ADC1EN),
+ ADC2 = details::rcc_enum (Bus::APB2, RCC_APB2ENR_ADC2EN),
+ TIM1 = details::rcc_enum (Bus::APB2, RCC_APB2ENR_TIM1EN),
+ SPI1 = details::rcc_enum (Bus::APB2, RCC_APB2ENR_SPI1EN),
+ USART1 = details::rcc_enum (Bus::APB2, RCC_APB2ENR_USART1EN),
+ TIM2 = details::rcc_enum (Bus::APB1, RCC_APB1ENR_TIM2EN),
+ TIM3 = details::rcc_enum (Bus::APB1, RCC_APB1ENR_TIM3EN),
+ TIM4 = details::rcc_enum (Bus::APB1, RCC_APB1ENR_TIM4EN),
+ TIM5 = details::rcc_enum (Bus::APB1, RCC_APB1ENR_TIM5EN),
+ TIM6 = details::rcc_enum (Bus::APB1, RCC_APB1ENR_TIM6EN),
+ TIM7 = details::rcc_enum (Bus::APB1, RCC_APB1ENR_TIM7EN),
+ WWDG = details::rcc_enum (Bus::APB1, RCC_APB1ENR_WWDGEN),
+ SPI2 = details::rcc_enum (Bus::APB1, RCC_APB1ENR_SPI2EN),
+ SPI3 = details::rcc_enum (Bus::APB1, RCC_APB1ENR_SPI3EN),
+ USART2 = details::rcc_enum (Bus::APB1, RCC_APB1ENR_USART2EN),
+ USART3 = details::rcc_enum (Bus::APB1, RCC_APB1ENR_USART3EN),
+ UART4 = details::rcc_enum (Bus::APB1, RCC_APB1ENR_UART4EN),
+ UART5 = details::rcc_enum (Bus::APB1, RCC_APB1ENR_UART5EN),
+ I2C1 = details::rcc_enum (Bus::APB1, RCC_APB1ENR_I2C1EN),
+ I2C2 = details::rcc_enum (Bus::APB1, RCC_APB1ENR_I2C2EN),
+ CAN1 = details::rcc_enum (Bus::APB1, RCC_APB1ENR_CAN1EN),
+ CAN2 = details::rcc_enum (Bus::APB1, RCC_APB1ENR_CAN2EN),
+ BKP = details::rcc_enum (Bus::APB1, RCC_APB1ENR_BKPEN),
+ PWR = details::rcc_enum (Bus::APB1, RCC_APB1ENR_PWREN),
+ DAC = details::rcc_enum (Bus::APB1, RCC_APB1ENR_DACEN),
+};
+
+/// Enable clock for given peripheral.
+static inline void
+rcc_peripheral_clock_enable (Rcc rcc)
+{
+ int bus_index = static_cast<uint32_t> (rcc) >> 5;
+ int bit_index = static_cast<uint32_t> (rcc) & 0x1f;
+ (&reg::RCC->AHBENR)[bus_index] |= 1 << bit_index;
+ arch_dsb ();
+}
+
+/// Disable clock for given peripheral.
+static inline void
+rcc_peripheral_clock_disable (Rcc rcc)
+{
+ int bus_index = static_cast<uint32_t> (rcc) >> 5;
+ int bit_index = static_cast<uint32_t> (rcc) & 0x1f;
+ (&reg::RCC->AHBENR)[bus_index] &= ~(1 << bit_index);
+ arch_dsb ();
+}
+
+/// Frequency of the main system clock.
+extern int rcc_sys_freq_hz;
+
+/// Frequency of AHB bus.
+extern int rcc_ahb_freq_hz;
+
+/// Frequency of APB1 bus.
+extern int rcc_apb1_freq_hz;
+
+/// Frequency of APB2 bus.
+extern int rcc_apb2_freq_hz;
+
+/// Frequency of timers on APB1 bus.
+extern int rcc_apb1_timer_freq_hz;
+
+/// Frequency of timers on APB2 bus.
+extern int rcc_apb2_timer_freq_hz;
+
+/// Frequency of the USB clock.
+extern int rcc_usb_freq_hz;
+
+/// Setup system clock using PLL, from HSE clock if not 0, else HSI clock.
+/// Also setup flash access. Only support configuration common to all F1
+/// lines.
+void
+rcc_sys_clock_setup_pll (int sys_freq_hz, int hse_freq_hz,
+ int prediv1, int pllmul,
+ int apb1_pre, int apb2_pre, int adc_pre);
+
+} // namespace ucoo
+
+#endif // ucoo_arch_rcc_stm32f1_hh
diff --git a/ucoo/arch/rcc.stm32f4.cc b/ucoo/arch/rcc.stm32f4.cc
new file mode 100644
index 0000000..36e31b6
--- /dev/null
+++ b/ucoo/arch/rcc.stm32f4.cc
@@ -0,0 +1,125 @@
+// ucoolib - Microcontroller object oriented library. {{{
+//
+// Copyright (C) 2016 Nicolas Schodet
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+//
+// }}}
+#include "ucoo/arch/rcc.stm32f4.hh"
+#include "ucoo/common.hh"
+#include "ucoo/utils/table_lookup.hh"
+
+namespace ucoo {
+
+static const int hsi_freq_hz = 16000000;
+
+int rcc_sys_freq_hz = hsi_freq_hz;
+int rcc_ahb_freq_hz = hsi_freq_hz;
+int rcc_apb1_freq_hz = hsi_freq_hz;
+int rcc_apb2_freq_hz = hsi_freq_hz;
+int rcc_apb1_timer_freq_hz = hsi_freq_hz;
+int rcc_apb2_timer_freq_hz = hsi_freq_hz;
+int rcc_pll48_freq_hz = 0;
+
+void
+rcc_sys_clock_setup_pll (int sys_freq_hz, int hse_freq_hz,
+ int pllm, int plln, int pllp, int pllq,
+ int apb1_pre, int apb2_pre,
+ SupplyRange vrange)
+{
+ // Switch to HSI as a safe fall back.
+ reg::RCC->CR |= RCC_CR_HSION;
+ while (!(reg::RCC->CR & RCC_CR_HSIRDY))
+ ;
+ reg::RCC->CFGR = (reg::RCC->CFGR & ~RCC_CFGR_SW) | RCC_CFGR_SW_HSI;
+ while ((reg::RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_HSI)
+ ;
+ // Start HSE if needed.
+ uint32_t pllsrc = RCC_PLLCFGR_PLLSRC_HSI;
+ int pll_in_freq_hz = hsi_freq_hz;
+ if (hse_freq_hz)
+ {
+ pll_in_freq_hz = hse_freq_hz;
+ pllsrc = RCC_PLLCFGR_PLLSRC_HSE;
+ reg::RCC->CR |= RCC_CR_HSEON;
+ while (!(reg::RCC->CR & RCC_CR_HSERDY))
+ ;
+ }
+ // Adapt voltage regulator scale.
+ if (sys_freq_hz <= 120000000)
+ reg::PWR->CR = (reg::PWR->CR & ~PWR_CR_VOS) | PWR_CR_VOS_Scale3;
+ else if (sys_freq_hz <= 144000000)
+ reg::PWR->CR = (reg::PWR->CR & ~PWR_CR_VOS) | PWR_CR_VOS_Scale2;
+ else
+ reg::PWR->CR = (reg::PWR->CR & ~PWR_CR_VOS) | PWR_CR_VOS_Scale1;
+ // Change buses prescalers.
+ uint32_t ppre = 0;
+ static const LookupTable<int, uint32_t> apb1_pre_table[] =
+ {
+ { 1, RCC_CFGR_PPRE1_DIV1 },
+ { 2, RCC_CFGR_PPRE1_DIV2 },
+ { 4, RCC_CFGR_PPRE1_DIV4 },
+ { 8, RCC_CFGR_PPRE1_DIV8 },
+ { 16, RCC_CFGR_PPRE1_DIV16 },
+ };
+ ppre |= simple_table_lookup (apb1_pre_table, apb1_pre);
+ static const LookupTable<int, uint32_t> apb2_pre_table[] =
+ {
+ { 1, RCC_CFGR_PPRE2_DIV1 },
+ { 2, RCC_CFGR_PPRE2_DIV2 },
+ { 4, RCC_CFGR_PPRE2_DIV4 },
+ { 8, RCC_CFGR_PPRE2_DIV8 },
+ { 16, RCC_CFGR_PPRE2_DIV16 },
+ };
+ ppre |= simple_table_lookup (apb2_pre_table, apb2_pre);
+ reg::RCC->CFGR = (reg::RCC->CFGR & ~(RCC_CFGR_PPRE1 | RCC_CFGR_PPRE2))
+ | ppre;
+ // Start PLL.
+ reg::RCC->PLLCFGR = pllsrc
+ | pllm << RCC_PLLCFGR_PLLM_Pos
+ | plln << RCC_PLLCFGR_PLLN_Pos
+ | (pllp / 2 - 1) << RCC_PLLCFGR_PLLP_Pos
+ | pllq << RCC_PLLCFGR_PLLQ_Pos;
+ reg::RCC->CR |= RCC_CR_PLLON;
+ while (!(reg::RCC->CR & RCC_CR_PLLRDY))
+ ;
+ // Setup flash.
+ int mhz_per_ws_per_vrange[] = { 20, 22, 24, 30 };
+ int mhz_per_ws = mhz_per_ws_per_vrange[static_cast<int> (vrange)];
+ int ws = (sys_freq_hz - 1) / 1000000 / mhz_per_ws;
+ reg::FLASH->ACR = ws
+ | FLASH_ACR_ICEN | FLASH_ACR_DCEN
+ | (ws ? FLASH_ACR_PRFTEN : 0); // XXX not for buggy F40x!
+ // Switch to PLL.
+ reg::RCC->CFGR = (reg::RCC->CFGR & ~RCC_CFGR_SW) | RCC_CFGR_SW_PLL;
+ while ((reg::RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_PLL)
+ ;
+ // Disable unused HSI.
+ reg::RCC->CR &= ~RCC_CR_HSION;
+ // Update frequencies.
+ assert (pll_in_freq_hz / pllm * plln / pllp == sys_freq_hz);
+ rcc_ahb_freq_hz = rcc_sys_freq_hz = sys_freq_hz;
+ rcc_apb1_freq_hz = sys_freq_hz / apb1_pre;
+ rcc_apb2_freq_hz = sys_freq_hz / apb2_pre;
+ rcc_apb1_timer_freq_hz = rcc_apb1_freq_hz * (apb1_pre == 1 ? 1 : 2);
+ rcc_apb2_timer_freq_hz = rcc_apb2_freq_hz * (apb2_pre == 1 ? 1 : 2);
+ rcc_pll48_freq_hz = pll_in_freq_hz / pllm * plln / pllq;
+}
+
+} // namespace ucoo
diff --git a/ucoo/arch/rcc.stm32f4.hh b/ucoo/arch/rcc.stm32f4.hh
new file mode 100644
index 0000000..64c46b5
--- /dev/null
+++ b/ucoo/arch/rcc.stm32f4.hh
@@ -0,0 +1,193 @@
+#ifndef ucoo_arch_rcc_stm32f4_hh
+#define ucoo_arch_rcc_stm32f4_hh
+// ucoolib - Microcontroller object oriented library. {{{
+//
+// Copyright (C) 2016 Nicolas Schodet
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+//
+// }}}
+#include "ucoo/arch/arch.hh"
+#include "ucoo/arch/reg.hh"
+
+namespace ucoo {
+
+enum class Bus
+{
+ AHB1 = 0,
+ AHB2 = 1,
+ AHB3 = 2,
+ APB1 = 4,
+ APB2 = 5,
+};
+
+/// Supply range.
+enum class SupplyRange
+{
+ /// 1.8 V to 2.1 V.
+ V1_8,
+ /// 2.1 V to 2.4 V.
+ V2_1,
+ /// 2.4 V to 2.7 V.
+ V2_4,
+ /// 2.7 V to 3.6 V.
+ V2_7,
+};
+
+namespace details {
+
+constexpr uint32_t
+rcc_enum (Bus bus, uint32_t bit, int pos = 0)
+{
+ return bit == 1
+ ? (static_cast<uint32_t> (bus) << 5) | pos
+ : rcc_enum (bus, (bit >> 1) | (bit << 31), pos + 1);
+}
+
+} // namespace details
+
+/// Constants to handle reset and clock for each peripheral.
+enum class Rcc
+{
+ GPIOA = details::rcc_enum (Bus::AHB1, RCC_AHB1ENR_GPIOAEN),
+ GPIOB = details::rcc_enum (Bus::AHB1, RCC_AHB1ENR_GPIOBEN),
+ GPIOC = details::rcc_enum (Bus::AHB1, RCC_AHB1ENR_GPIOCEN),
+ GPIOD = details::rcc_enum (Bus::AHB1, RCC_AHB1ENR_GPIODEN),
+ GPIOE = details::rcc_enum (Bus::AHB1, RCC_AHB1ENR_GPIOEEN),
+ GPIOF = details::rcc_enum (Bus::AHB1, RCC_AHB1ENR_GPIOFEN),
+ GPIOG = details::rcc_enum (Bus::AHB1, RCC_AHB1ENR_GPIOGEN),
+ GPIOH = details::rcc_enum (Bus::AHB1, RCC_AHB1ENR_GPIOHEN),
+ GPIOI = details::rcc_enum (Bus::AHB1, RCC_AHB1ENR_GPIOIEN),
+ GPIOJ = details::rcc_enum (Bus::AHB1, RCC_AHB1ENR_GPIOJEN),
+ GPIOK = details::rcc_enum (Bus::AHB1, RCC_AHB1ENR_GPIOKEN),
+ CRC = details::rcc_enum (Bus::AHB1, RCC_AHB1ENR_CRCEN),
+ BKPSRAM = details::rcc_enum (Bus::AHB1, RCC_AHB1ENR_BKPSRAMEN),
+ CCMDATARAM = details::rcc_enum (Bus::AHB1, RCC_AHB1ENR_CCMDATARAMEN),
+ DMA1 = details::rcc_enum (Bus::AHB1, RCC_AHB1ENR_DMA1EN),
+ DMA2 = details::rcc_enum (Bus::AHB1, RCC_AHB1ENR_DMA2EN),
+ DMA2D = details::rcc_enum (Bus::AHB1, RCC_AHB1ENR_DMA2DEN),
+ ETHMAC = details::rcc_enum (Bus::AHB1, RCC_AHB1ENR_ETHMACEN),
+ ETHMACTX = details::rcc_enum (Bus::AHB1, RCC_AHB1ENR_ETHMACTXEN),
+ ETHMACRX = details::rcc_enum (Bus::AHB1, RCC_AHB1ENR_ETHMACRXEN),
+ ETHMACPTP = details::rcc_enum (Bus::AHB1, RCC_AHB1ENR_ETHMACPTPEN),
+ OTGHS = details::rcc_enum (Bus::AHB1, RCC_AHB1ENR_OTGHSEN),
+ OTGHSULPI = details::rcc_enum (Bus::AHB1, RCC_AHB1ENR_OTGHSULPIEN),
+ DCMI = details::rcc_enum (Bus::AHB2, RCC_AHB2ENR_DCMIEN),
+ CRYP = details::rcc_enum (Bus::AHB2, RCC_AHB2ENR_CRYPEN),
+ HASH = details::rcc_enum (Bus::AHB2, RCC_AHB2ENR_HASHEN),
+ RNG = details::rcc_enum (Bus::AHB2, RCC_AHB2ENR_RNGEN),
+ OTGFS = details::rcc_enum (Bus::AHB2, RCC_AHB2ENR_OTGFSEN),
+ FMC = details::rcc_enum (Bus::AHB3, RCC_AHB3ENR_FMCEN),
+ TIM2 = details::rcc_enum (Bus::APB1, RCC_APB1ENR_TIM2EN),
+ TIM3 = details::rcc_enum (Bus::APB1, RCC_APB1ENR_TIM3EN),
+ TIM4 = details::rcc_enum (Bus::APB1, RCC_APB1ENR_TIM4EN),
+ TIM5 = details::rcc_enum (Bus::APB1, RCC_APB1ENR_TIM5EN),
+ TIM6 = details::rcc_enum (Bus::APB1, RCC_APB1ENR_TIM6EN),
+ TIM7 = details::rcc_enum (Bus::APB1, RCC_APB1ENR_TIM7EN),
+ TIM12 = details::rcc_enum (Bus::APB1, RCC_APB1ENR_TIM12EN),
+ TIM13 = details::rcc_enum (Bus::APB1, RCC_APB1ENR_TIM13EN),
+ TIM14 = details::rcc_enum (Bus::APB1, RCC_APB1ENR_TIM14EN),
+ WWDG = details::rcc_enum (Bus::APB1, RCC_APB1ENR_WWDGEN),
+ SPI2 = details::rcc_enum (Bus::APB1, RCC_APB1ENR_SPI2EN),
+ SPI3 = details::rcc_enum (Bus::APB1, RCC_APB1ENR_SPI3EN),
+ USART2 = details::rcc_enum (Bus::APB1, RCC_APB1ENR_USART2EN),
+ USART3 = details::rcc_enum (Bus::APB1, RCC_APB1ENR_USART3EN),
+ UART4 = details::rcc_enum (Bus::APB1, RCC_APB1ENR_UART4EN),
+ UART5 = details::rcc_enum (Bus::APB1, RCC_APB1ENR_UART5EN),
+ I2C1 = details::rcc_enum (Bus::APB1, RCC_APB1ENR_I2C1EN),
+ I2C2 = details::rcc_enum (Bus::APB1, RCC_APB1ENR_I2C2EN),
+ I2C3 = details::rcc_enum (Bus::APB1, RCC_APB1ENR_I2C3EN),
+ CAN1 = details::rcc_enum (Bus::APB1, RCC_APB1ENR_CAN1EN),
+ CAN2 = details::rcc_enum (Bus::APB1, RCC_APB1ENR_CAN2EN),
+ PWR = details::rcc_enum (Bus::APB1, RCC_APB1ENR_PWREN),
+ DAC = details::rcc_enum (Bus::APB1, RCC_APB1ENR_DACEN),
+ UART7 = details::rcc_enum (Bus::APB1, RCC_APB1ENR_UART7EN),
+ UART8 = details::rcc_enum (Bus::APB1, RCC_APB1ENR_UART8EN),
+ TIM1 = details::rcc_enum (Bus::APB2, RCC_APB2ENR_TIM1EN),
+ TIM8 = details::rcc_enum (Bus::APB2, RCC_APB2ENR_TIM8EN),
+ USART1 = details::rcc_enum (Bus::APB2, RCC_APB2ENR_USART1EN),
+ USART6 = details::rcc_enum (Bus::APB2, RCC_APB2ENR_USART6EN),
+ ADC1 = details::rcc_enum (Bus::APB2, RCC_APB2ENR_ADC1EN),
+ ADC2 = details::rcc_enum (Bus::APB2, RCC_APB2ENR_ADC2EN),
+ ADC3 = details::rcc_enum (Bus::APB2, RCC_APB2ENR_ADC3EN),
+ SDIO = details::rcc_enum (Bus::APB2, RCC_APB2ENR_SDIOEN),
+ SPI1 = details::rcc_enum (Bus::APB2, RCC_APB2ENR_SPI1EN),
+ SPI4 = details::rcc_enum (Bus::APB2, RCC_APB2ENR_SPI4EN),
+ SYSCFG = details::rcc_enum (Bus::APB2, RCC_APB2ENR_SYSCFGEN),
+ TIM9 = details::rcc_enum (Bus::APB2, RCC_APB2ENR_TIM9EN),
+ TIM10 = details::rcc_enum (Bus::APB2, RCC_APB2ENR_TIM10EN),
+ TIM11 = details::rcc_enum (Bus::APB2, RCC_APB2ENR_TIM11EN),
+ SPI5 = details::rcc_enum (Bus::APB2, RCC_APB2ENR_SPI5EN),
+ SPI6 = details::rcc_enum (Bus::APB2, RCC_APB2ENR_SPI6EN),
+ SAI1 = details::rcc_enum (Bus::APB2, RCC_APB2ENR_SAI1EN),
+ LTDC = details::rcc_enum (Bus::APB2, RCC_APB2ENR_LTDCEN),
+};
+
+/// Enable clock for given peripheral.
+static inline void
+rcc_peripheral_clock_enable (Rcc rcc)
+{
+ int bus_index = static_cast<uint32_t> (rcc) >> 5;
+ int bit_index = static_cast<uint32_t> (rcc) & 0x1f;
+ (&reg::RCC->AHB1ENR)[bus_index] |= 1 << bit_index;
+ arch_dsb ();
+}
+
+/// Disable clock for given peripheral.
+static inline void
+rcc_peripheral_clock_disable (Rcc rcc)
+{
+ int bus_index = static_cast<uint32_t> (rcc) >> 5;
+ int bit_index = static_cast<uint32_t> (rcc) & 0x1f;
+ (&reg::RCC->AHB1ENR)[bus_index] &= ~(1 << bit_index);
+ arch_dsb ();
+}
+
+/// Frequency of the main system clock.
+extern int rcc_sys_freq_hz;
+
+/// Frequency of AHB bus.
+extern int rcc_ahb_freq_hz;
+
+/// Frequency of APB1 bus.
+extern int rcc_apb1_freq_hz;
+
+/// Frequency of APB2 bus.
+extern int rcc_apb2_freq_hz;
+
+/// Frequency of timers on APB1 bus.
+extern int rcc_apb1_timer_freq_hz;
+
+/// Frequency of timers on APB2 bus.
+extern int rcc_apb2_timer_freq_hz;
+
+/// Frequency of the should-be-48-MHz clock (used for USB, RNG & SDIO).
+extern int rcc_pll48_freq_hz;
+
+/// Setup system clock using PLL, from HSE clock if not 0, else HSI clock.
+/// Also setup flash access and voltage regulator scale.
+void
+rcc_sys_clock_setup_pll (int sys_freq_hz, int hse_freq_hz,
+ int pllm, int plln, int pllp, int pllq,
+ int apb1_pre, int apb2_pre,
+ SupplyRange vrange);
+
+} // namespace ucoo
+
+#endif // ucoo_arch_rcc_stm32f4_hh
diff --git a/ucoo/arch/reg.hh b/ucoo/arch/reg.hh
new file mode 100644
index 0000000..d913511
--- /dev/null
+++ b/ucoo/arch/reg.hh
@@ -0,0 +1,35 @@
+#ifndef ucoo_arch_reg_hh
+#define ucoo_arch_reg_hh
+// ucoolib - Microcontroller object oriented library. {{{
+//
+// Copyright (C) 2016 Nicolas Schodet
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+//
+// }}}
+
+#if defined (TARGET_stm32f4)
+# include "reg.stm32f4.hh"
+#elif defined (TARGET_stm32f1)
+# include "reg.stm32f1.hh"
+#else
+# error "not implemented for this target"
+#endif
+
+#endif // ucoo_arch_reg_hh
diff --git a/ucoo/arch/reg.stm32.hh b/ucoo/arch/reg.stm32.hh
new file mode 100644
index 0000000..4d46354
--- /dev/null
+++ b/ucoo/arch/reg.stm32.hh
@@ -0,0 +1,80 @@
+#ifndef ucoo_arch_reg_stm32_hh
+#define ucoo_arch_reg_stm32_hh
+// ucoolib - Microcontroller object oriented library. {{{
+//
+// Copyright (C) 2016 Nicolas Schodet
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+//
+// }}}
+
+#define TIM_SMCR_SMS_TM (6 << 0)
+
+#define TIM_SMCR_TS_TI1FP1 (5 << 4)
+#define TIM_SMCR_TS_TI1FP2 (6 << 4)
+
+#define TIM_CCMR1_OC1M_PWM1 (6 << 4)
+#define TIM_CCMR1_OC2M_PWM1 (6 << 12)
+
+#define TIM_CCMR2_OC3M_PWM1 (6 << 4)
+#define TIM_CCMR2_OC4M_PWM1 (6 << 12)
+
+#define USART_CR2_STOP_Bits_1 0
+#define USART_CR2_STOP_Bits_0_5 USART_CR2_STOP_0
+#define USART_CR2_STOP_Bits_2 USART_CR2_STOP_1
+#define USART_CR2_STOP_Bits_1_5 (USART_CR2_STOP_1 | USART_CR2_STOP_0)
+
+#define USB_OTG_GRXSTSP_PKTSTS_GlobalOutNak (1 << 17)
+#define USB_OTG_GRXSTSP_PKTSTS_Out (2 << 17)
+#define USB_OTG_GRXSTSP_PKTSTS_OutCompleted (3 << 17)
+#define USB_OTG_GRXSTSP_PKTSTS_SetupCompleted (4 << 17)
+#define USB_OTG_GRXSTSP_PKTSTS_Setup (6 << 17)
+
+#define FLASH_KEYR_KEY1 0x45670123
+#define FLASH_KEYR_KEY2 0xcdef89ab
+
+namespace ucoo {
+
+struct USB_OTG_FIFOTypeDef
+{
+ __IO uint32_t FIFO;
+ uint32_t reserved[(0x1000 - sizeof (uint32_t)) / 4];
+};
+
+/// USB OTG registers, only define device registers.
+struct USB_OTG_TypeDef
+{
+ USB_OTG_GlobalTypeDef global;
+ uint32_t reserved0[(USB_OTG_DEVICE_BASE - USB_OTG_GLOBAL_BASE
+ - sizeof (USB_OTG_GlobalTypeDef)) / 4];
+ USB_OTG_DeviceTypeDef device;
+ uint32_t reserved1[(USB_OTG_IN_ENDPOINT_BASE - USB_OTG_DEVICE_BASE
+ - sizeof (USB_OTG_DeviceTypeDef)) / 4];
+ USB_OTG_INEndpointTypeDef ep_in[4];
+ uint32_t reserved2[(USB_OTG_OUT_ENDPOINT_BASE - USB_OTG_IN_ENDPOINT_BASE
+ - sizeof (USB_OTG_INEndpointTypeDef[4])) / 4];
+ USB_OTG_OUTEndpointTypeDef ep_out[4];
+ uint32_t reserved3[(USB_OTG_FIFO_BASE - USB_OTG_OUT_ENDPOINT_BASE
+ - sizeof (USB_OTG_OUTEndpointTypeDef[4])) / 4];
+ USB_OTG_FIFOTypeDef fifo[4];
+};
+
+} // namespace ucoo
+
+#endif // ucoo_arch_reg_stm32_hh
diff --git a/ucoo/arch/reg.stm32f1.hh b/ucoo/arch/reg.stm32f1.hh
new file mode 100644
index 0000000..47855cf
--- /dev/null
+++ b/ucoo/arch/reg.stm32f1.hh
@@ -0,0 +1,180 @@
+#ifndef ucoo_arch_reg_stm32f1_hh
+#define ucoo_arch_reg_stm32f1_hh
+// ucoolib - Microcontroller object oriented library. {{{
+//
+// Copyright (C) 2016 Nicolas Schodet
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+//
+// }}}
+#include "ST/STM32F1xx/Include/stm32f105xc.h"
+#include "ucoo/arch/reg.stm32.hh"
+
+#define GPIO_CNF_Input_Analog 0
+#define GPIO_CNF_Input_Float 1
+#define GPIO_CNF_Input_PullUpDown 2
+
+#define GPIO_CNF_Output_PushPull 0
+#define GPIO_CNF_Output_OpenDrain 1
+#define GPIO_CNF_Output_AFPushPull 2
+#define GPIO_CNF_Output_AFOpenDrain 3
+
+#define GPIO_MODE_Input 0
+#define GPIO_MODE_Output_2MHz 1
+#define GPIO_MODE_Output_10MHz 2
+#define GPIO_MODE_Output_50MHz 3
+
+#define DESIG_BASE 0x1ffff7e0
+
+struct DESIG_TypeDef
+{
+ __IO uint16_t FLASH_SIZE;
+ uint16_t reserved1;
+ uint32_t reserved2;
+ __IO uint32_t U_ID[3];
+};
+
+#undef SysTick
+
+#undef TIM2
+#undef TIM3
+#undef TIM4
+#undef TIM5
+#undef TIM6
+#undef TIM7
+#undef RTC
+#undef WWDG
+#undef IWDG
+#undef SPI2
+#undef SPI3
+#undef USART2
+#undef USART3
+#undef UART4
+#undef UART5
+#undef I2C1
+#undef I2C2
+#undef CAN1
+#undef CAN2
+#undef BKP
+#undef PWR
+#undef DAC
+#undef AFIO
+#undef EXTI
+#undef GPIOA
+#undef GPIOB
+#undef GPIOC
+#undef GPIOD
+#undef GPIOE
+#undef ADC1
+#undef ADC2
+#undef ADC12_COMMON
+#undef TIM1
+#undef SPI1
+#undef USART1
+#undef SDIO
+#undef DMA1
+#undef DMA2
+#undef DMA1_Channel1
+#undef DMA1_Channel2
+#undef DMA1_Channel3
+#undef DMA1_Channel4
+#undef DMA1_Channel5
+#undef DMA1_Channel6
+#undef DMA1_Channel7
+#undef DMA2_Channel1
+#undef DMA2_Channel2
+#undef DMA2_Channel3
+#undef DMA2_Channel4
+#undef DMA2_Channel5
+#undef RCC
+#undef CRC
+#undef FLASH
+#undef OB
+#undef DBGMCU
+#undef USB_OTG_FS
+
+namespace ucoo {
+
+namespace reg {
+
+constexpr auto SysTick = reinterpret_cast<SysTick_Type *> (SysTick_BASE);
+
+constexpr auto TIM2 = reinterpret_cast<TIM_TypeDef *> (TIM2_BASE);
+constexpr auto TIM3 = reinterpret_cast<TIM_TypeDef *> (TIM3_BASE);
+constexpr auto TIM4 = reinterpret_cast<TIM_TypeDef *> (TIM4_BASE);
+constexpr auto TIM5 = reinterpret_cast<TIM_TypeDef *> (TIM5_BASE);
+constexpr auto TIM6 = reinterpret_cast<TIM_TypeDef *> (TIM6_BASE);
+constexpr auto TIM7 = reinterpret_cast<TIM_TypeDef *> (TIM7_BASE);
+constexpr auto RTC = reinterpret_cast<RTC_TypeDef *> (RTC_BASE);
+constexpr auto WWDG = reinterpret_cast<WWDG_TypeDef *> (WWDG_BASE);
+constexpr auto IWDG = reinterpret_cast<IWDG_TypeDef *> (IWDG_BASE);
+constexpr auto SPI2 = reinterpret_cast<SPI_TypeDef *> (SPI2_BASE);
+constexpr auto SPI3 = reinterpret_cast<SPI_TypeDef *> (SPI3_BASE);
+constexpr auto USART2 = reinterpret_cast<USART_TypeDef *> (USART2_BASE);
+constexpr auto USART3 = reinterpret_cast<USART_TypeDef *> (USART3_BASE);
+constexpr auto UART4 = reinterpret_cast<USART_TypeDef *> (UART4_BASE);
+constexpr auto UART5 = reinterpret_cast<USART_TypeDef *> (UART5_BASE);
+constexpr auto I2C1 = reinterpret_cast<I2C_TypeDef *> (I2C1_BASE);
+constexpr auto I2C2 = reinterpret_cast<I2C_TypeDef *> (I2C2_BASE);
+constexpr auto CAN1 = reinterpret_cast<CAN_TypeDef *> (CAN1_BASE);
+constexpr auto CAN2 = reinterpret_cast<CAN_TypeDef *> (CAN2_BASE);
+constexpr auto BKP = reinterpret_cast<BKP_TypeDef *> (BKP_BASE);
+constexpr auto PWR = reinterpret_cast<PWR_TypeDef *> (PWR_BASE);
+constexpr auto DAC = reinterpret_cast<DAC_TypeDef *> (DAC_BASE);
+constexpr auto AFIO = reinterpret_cast<AFIO_TypeDef *> (AFIO_BASE);
+constexpr auto EXTI = reinterpret_cast<EXTI_TypeDef *> (EXTI_BASE);
+constexpr auto GPIOA = reinterpret_cast<GPIO_TypeDef *> (GPIOA_BASE);
+constexpr auto GPIOB = reinterpret_cast<GPIO_TypeDef *> (GPIOB_BASE);
+constexpr auto GPIOC = reinterpret_cast<GPIO_TypeDef *> (GPIOC_BASE);
+constexpr auto GPIOD = reinterpret_cast<GPIO_TypeDef *> (GPIOD_BASE);
+constexpr auto GPIOE = reinterpret_cast<GPIO_TypeDef *> (GPIOE_BASE);
+constexpr auto ADC1 = reinterpret_cast<ADC_TypeDef *> (ADC1_BASE);
+constexpr auto ADC2 = reinterpret_cast<ADC_TypeDef *> (ADC2_BASE);
+constexpr auto ADC12_COMMON = reinterpret_cast<ADC_Common_TypeDef *> (ADC1_BASE);
+constexpr auto TIM1 = reinterpret_cast<TIM_TypeDef *> (TIM1_BASE);
+constexpr auto SPI1 = reinterpret_cast<SPI_TypeDef *> (SPI1_BASE);
+constexpr auto USART1 = reinterpret_cast<USART_TypeDef *> (USART1_BASE);
+constexpr auto SDIO = reinterpret_cast<SDIO_TypeDef *> (SDIO_BASE);
+constexpr auto DMA1 = reinterpret_cast<DMA_TypeDef *> (DMA1_BASE);
+constexpr auto DMA2 = reinterpret_cast<DMA_TypeDef *> (DMA2_BASE);
+constexpr auto DMA1_Channel1 = reinterpret_cast<DMA_Channel_TypeDef *> (DMA1_Channel1_BASE);
+constexpr auto DMA1_Channel2 = reinterpret_cast<DMA_Channel_TypeDef *> (DMA1_Channel2_BASE);
+constexpr auto DMA1_Channel3 = reinterpret_cast<DMA_Channel_TypeDef *> (DMA1_Channel3_BASE);
+constexpr auto DMA1_Channel4 = reinterpret_cast<DMA_Channel_TypeDef *> (DMA1_Channel4_BASE);
+constexpr auto DMA1_Channel5 = reinterpret_cast<DMA_Channel_TypeDef *> (DMA1_Channel5_BASE);
+constexpr auto DMA1_Channel6 = reinterpret_cast<DMA_Channel_TypeDef *> (DMA1_Channel6_BASE);
+constexpr auto DMA1_Channel7 = reinterpret_cast<DMA_Channel_TypeDef *> (DMA1_Channel7_BASE);
+constexpr auto DMA2_Channel1 = reinterpret_cast<DMA_Channel_TypeDef *> (DMA2_Channel1_BASE);
+constexpr auto DMA2_Channel2 = reinterpret_cast<DMA_Channel_TypeDef *> (DMA2_Channel2_BASE);
+constexpr auto DMA2_Channel3 = reinterpret_cast<DMA_Channel_TypeDef *> (DMA2_Channel3_BASE);
+constexpr auto DMA2_Channel4 = reinterpret_cast<DMA_Channel_TypeDef *> (DMA2_Channel4_BASE);
+constexpr auto DMA2_Channel5 = reinterpret_cast<DMA_Channel_TypeDef *> (DMA2_Channel5_BASE);
+constexpr auto RCC = reinterpret_cast<RCC_TypeDef *> (RCC_BASE);
+constexpr auto CRC = reinterpret_cast<CRC_TypeDef *> (CRC_BASE);
+constexpr auto FLASH = reinterpret_cast<FLASH_TypeDef *> (FLASH_R_BASE);
+constexpr auto OB = reinterpret_cast<OB_TypeDef *> (OB_BASE);
+constexpr auto DBGMCU = reinterpret_cast<DBGMCU_TypeDef *> (DBGMCU_BASE);
+constexpr auto USB_OTG_FS = reinterpret_cast<USB_OTG_TypeDef *> (USB_OTG_FS_PERIPH_BASE);
+constexpr auto DESIG = reinterpret_cast<DESIG_TypeDef *> (DESIG_BASE);
+
+} // namespace reg
+
+} // namespace ucoo
+
+#endif // ucoo_arch_reg_stm32f1_hh
diff --git a/ucoo/arch/reg.stm32f4.hh b/ucoo/arch/reg.stm32f4.hh
new file mode 100644
index 0000000..31ad39d
--- /dev/null
+++ b/ucoo/arch/reg.stm32f4.hh
@@ -0,0 +1,347 @@
+#ifndef ucoo_arch_reg_stm32f4_hh
+#define ucoo_arch_reg_stm32f4_hh
+// ucoolib - Microcontroller object oriented library. {{{
+//
+// Copyright (C) 2016 Nicolas Schodet
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+//
+// }}}
+// Use a superset of all supported chips.
+#include "ST/STM32F4xx/Include/stm32f439xx.h"
+#include "ucoo/arch/reg.stm32.hh"
+
+#define SCB_CPACR_CP10_Pos 20
+#define SCB_CPACR_CP10_Denied (0 << SCB_CPACR_CP10_Pos)
+#define SCB_CPACR_CP10_Privileged (1 << SCB_CPACR_CP10_Pos)
+#define SCB_CPACR_CP10_Full (3 << SCB_CPACR_CP10_Pos)
+#define SCB_CPACR_CP10_Msk (3 << SCB_CPACR_CP10_Pos)
+
+#define SCB_CPACR_CP11_Pos 22
+#define SCB_CPACR_CP11_Denied (0 << SCB_CPACR_CP11_Pos)
+#define SCB_CPACR_CP11_Privileged (1 << SCB_CPACR_CP11_Pos)
+#define SCB_CPACR_CP11_Full (3 << SCB_CPACR_CP11_Pos)
+#define SCB_CPACR_CP11_Msk (3 << SCB_CPACR_CP11_Pos)
+
+#define PWR_CR_VOS_Scale3 (PWR_CR_VOS_0)
+#define PWR_CR_VOS_Scale2 (PWR_CR_VOS_1)
+#define PWR_CR_VOS_Scale1 (PWR_CR_VOS_1 | PWR_CR_VOS_0)
+
+#define RCC_PLLCFGR_PLLM_Pos 0
+#define RCC_PLLCFGR_PLLN_Pos 6
+#define RCC_PLLCFGR_PLLP_Pos 16
+#define RCC_PLLCFGR_PLLQ_Pos 24
+
+#define GPIO_MODER_Input 0
+#define GPIO_MODER_Output 1
+#define GPIO_MODER_AF 2
+#define GPIO_MODER_Analog 3
+
+#define SPI_CR1_BR_Pos 3
+
+#define USB_OTG_GRXSTSP_BCNT_Pos 4
+#define USB_OTG_GRXSTSP_PKTSTS_Pos 17
+#define USB_OTG_DOEPTSIZ_PKTCNT_Pos 19
+#define USB_OTG_DIEPTSIZ_PKTCNT_Pos 19
+
+#define FLASH_CR_PSIZE_x32 FLASH_CR_PSIZE_1
+
+#define FMC_SDCR_RPIPE_None 0
+#define FMC_SDCR_RPIPE_1Clk FMC_SDCR1_RPIPE_0
+#define FMC_SDCR_RPIPE_2Clk FMC_SDCR1_RPIPE_1
+#define FMC_SDCR_RBURST FMC_SDCR1_RBURST
+#define FMC_SDCR_SDCLK_Disabled 0
+#define FMC_SDCR_SDCLK_2Hclk FMC_SDCR1_SDCLK_1
+#define FMC_SDCR_SDCLK_3Hclk (FMC_SDCR1_SDCLK_1 | FMC_SDCR1_SDCLK_0)
+#define FMC_SDCR_CAS_Pos 7
+#define FMC_SDCR_NB FMC_SDCR1_NB
+#define FMC_SDCR_MWID_8B 0
+#define FMC_SDCR_MWID_16B FMC_SDCR1_MWID_0
+#define FMC_SDCR_MWID_32B FMC_SDCR1_MWID_1
+#define FMC_SDCR_NR_Pos 2
+#define FMC_SDCR_NC_Pos 0
+
+#define FMC_SDTR_TRCD_Pos 24
+#define FMC_SDTR_TRP_Pos 20
+#define FMC_SDTR_TWR_Pos 16
+#define FMC_SDTR_TRC_Pos 12
+#define FMC_SDTR_TRAS_Pos 8
+#define FMC_SDTR_TXSR_Pos 4
+#define FMC_SDTR_TMRD_Pos 0
+
+#define FMC_SDCR_DNC_Mask (FMC_SDCR1_SDCLK | FMC_SDCR1_RPIPE \
+ | FMC_SDCR1_RBURST)
+#define FMC_SDTR_DNC_Mask (FMC_SDTR1_TRP | FMC_SDTR1_TRC)
+
+#define FMC_SDCMR_MODE_Normal 0
+#define FMC_SDCMR_MODE_ClockConfigEna 1
+#define FMC_SDCMR_MODE_Pall 2
+#define FMC_SDCMR_MODE_AutoRefresh 3
+#define FMC_SDCMR_MODE_LoadModeRegister 4
+#define FMC_SDCMR_MODE_SelfRefresh 5
+#define FMC_SDCMR_MODE_PowerDown 6
+
+#define FMC_SDCMR_NRFS_Pos 5
+#define FMC_SDCMR_MRD_Pos 9
+
+#define SDRAM_MODE_BURST_LENGTH_1 0x0000
+#define SDRAM_MODE_BURST_LENGTH_2 0x0001
+#define SDRAM_MODE_BURST_LENGTH_4 0x0002
+#define SDRAM_MODE_BURST_LENGTH_8 0x0004
+#define SDRAM_MODE_BURST_TYPE_SEQUENTIAL 0x0000
+#define SDRAM_MODE_BURST_TYPE_INTERLEAVED 0x0008
+#define SDRAM_MODE_CAS_LATENCY_2 0x0020
+#define SDRAM_MODE_CAS_LATENCY_3 0x0030
+#define SDRAM_MODE_OPERATING_MODE_STANDARD 0x0000
+#define SDRAM_MODE_WRITEBURST_MODE_PROGRAMMED 0x0000
+#define SDRAM_MODE_WRITEBURST_MODE_SINGLE 0x0200
+
+#define FMC_BANK5_BASE 0xc0000000
+#define FMC_BANK6_BASE 0xd0000000
+
+#define DESIG_BASE 0x1fff7a10
+#define DESIG_FLASH_SIZE_BASE 0x1fff7a22
+#define DESIG_UNIQUE_ID_BASE 0x1fff7a10
+
+struct DESIG_TypeDef
+{
+ __IO uint32_t U_ID[3];
+ uint32_t reserved0x1c;
+ uint16_t reserved0x20;
+ __IO uint16_t FLASH_SIZE;
+};
+
+#undef FPU
+#undef SysTick
+
+#undef TIM2
+#undef TIM3
+#undef TIM4
+#undef TIM5
+#undef TIM6
+#undef TIM7
+#undef TIM12
+#undef TIM13
+#undef TIM14
+#undef RTC
+#undef WWDG
+#undef IWDG
+#undef I2S2ext
+#undef SPI2
+#undef SPI3
+#undef I2S3ext
+#undef USART2
+#undef USART3
+#undef UART4
+#undef UART5
+#undef I2C1
+#undef I2C2
+#undef I2C3
+#undef CAN1
+#undef CAN2
+#undef PWR
+#undef DAC
+#undef UART7
+#undef UART8
+#undef TIM1
+#undef TIM8
+#undef USART1
+#undef USART6
+#undef ADC
+#undef ADC1
+#undef ADC2
+#undef ADC3
+#undef SDIO
+#undef SPI1
+#undef SPI4
+#undef SYSCFG
+#undef EXTI
+#undef TIM9
+#undef TIM10
+#undef TIM11
+#undef SPI5
+#undef SPI6
+#undef SAI1
+#undef SAI1_Block_A
+#undef SAI1_Block_B
+#undef LTDC
+#undef LTDC_Layer1
+#undef LTDC_Layer2
+#undef GPIOA
+#undef GPIOB
+#undef GPIOC
+#undef GPIOD
+#undef GPIOE
+#undef GPIOF
+#undef GPIOG
+#undef GPIOH
+#undef GPIOI
+#undef GPIOJ
+#undef GPIOK
+#undef CRC
+#undef RCC
+#undef FLASH
+#undef DMA1
+#undef DMA1_Stream0
+#undef DMA1_Stream1
+#undef DMA1_Stream2
+#undef DMA1_Stream3
+#undef DMA1_Stream4
+#undef DMA1_Stream5
+#undef DMA1_Stream6
+#undef DMA1_Stream7
+#undef DMA2
+#undef DMA2_Stream0
+#undef DMA2_Stream1
+#undef DMA2_Stream2
+#undef DMA2_Stream3
+#undef DMA2_Stream4
+#undef DMA2_Stream5
+#undef DMA2_Stream6
+#undef DMA2_Stream7
+#undef ETH
+#undef DMA2D
+#undef DCMI
+#undef CRYP
+#undef HASH
+#undef HASH_DIGEST
+#undef RNG
+#undef FMC_Bank1
+#undef FMC_Bank1E
+#undef FMC_Bank2_3
+#undef FMC_Bank4
+#undef FMC_Bank5_6
+#undef DBGMCU
+#undef USB_OTG_FS
+#undef USB_OTG_HS
+
+namespace ucoo {
+
+namespace reg {
+
+constexpr auto FPU = reinterpret_cast<FPU_Type *> (FPU_BASE);
+constexpr auto SysTick = reinterpret_cast<SysTick_Type *> (SysTick_BASE);
+
+constexpr auto TIM2 = reinterpret_cast<TIM_TypeDef *> (TIM2_BASE);
+constexpr auto TIM3 = reinterpret_cast<TIM_TypeDef *> (TIM3_BASE);
+constexpr auto TIM4 = reinterpret_cast<TIM_TypeDef *> (TIM4_BASE);
+constexpr auto TIM5 = reinterpret_cast<TIM_TypeDef *> (TIM5_BASE);
+constexpr auto TIM6 = reinterpret_cast<TIM_TypeDef *> (TIM6_BASE);
+constexpr auto TIM7 = reinterpret_cast<TIM_TypeDef *> (TIM7_BASE);
+constexpr auto TIM12 = reinterpret_cast<TIM_TypeDef *> (TIM12_BASE);
+constexpr auto TIM13 = reinterpret_cast<TIM_TypeDef *> (TIM13_BASE);
+constexpr auto TIM14 = reinterpret_cast<TIM_TypeDef *> (TIM14_BASE);
+constexpr auto RTC = reinterpret_cast<RTC_TypeDef *> (RTC_BASE);
+constexpr auto WWDG = reinterpret_cast<WWDG_TypeDef *> (WWDG_BASE);
+constexpr auto IWDG = reinterpret_cast<IWDG_TypeDef *> (IWDG_BASE);
+constexpr auto I2S2ext = reinterpret_cast<SPI_TypeDef *> (I2S2ext_BASE);
+constexpr auto SPI2 = reinterpret_cast<SPI_TypeDef *> (SPI2_BASE);
+constexpr auto SPI3 = reinterpret_cast<SPI_TypeDef *> (SPI3_BASE);
+constexpr auto I2S3ext = reinterpret_cast<SPI_TypeDef *> (I2S3ext_BASE);
+constexpr auto USART2 = reinterpret_cast<USART_TypeDef *> (USART2_BASE);
+constexpr auto USART3 = reinterpret_cast<USART_TypeDef *> (USART3_BASE);
+constexpr auto UART4 = reinterpret_cast<USART_TypeDef *> (UART4_BASE);
+constexpr auto UART5 = reinterpret_cast<USART_TypeDef *> (UART5_BASE);
+constexpr auto I2C1 = reinterpret_cast<I2C_TypeDef *> (I2C1_BASE);
+constexpr auto I2C2 = reinterpret_cast<I2C_TypeDef *> (I2C2_BASE);
+constexpr auto I2C3 = reinterpret_cast<I2C_TypeDef *> (I2C3_BASE);
+constexpr auto CAN1 = reinterpret_cast<CAN_TypeDef *> (CAN1_BASE);
+constexpr auto CAN2 = reinterpret_cast<CAN_TypeDef *> (CAN2_BASE);
+constexpr auto PWR = reinterpret_cast<PWR_TypeDef *> (PWR_BASE);
+constexpr auto DAC = reinterpret_cast<DAC_TypeDef *> (DAC_BASE);
+constexpr auto UART7 = reinterpret_cast<USART_TypeDef *> (UART7_BASE);
+constexpr auto UART8 = reinterpret_cast<USART_TypeDef *> (UART8_BASE);
+constexpr auto TIM1 = reinterpret_cast<TIM_TypeDef *> (TIM1_BASE);
+constexpr auto TIM8 = reinterpret_cast<TIM_TypeDef *> (TIM8_BASE);
+constexpr auto USART1 = reinterpret_cast<USART_TypeDef *> (USART1_BASE);
+constexpr auto USART6 = reinterpret_cast<USART_TypeDef *> (USART6_BASE);
+constexpr auto ADC = reinterpret_cast<ADC_Common_TypeDef *> (ADC_BASE);
+constexpr auto ADC1 = reinterpret_cast<ADC_TypeDef *> (ADC1_BASE);
+constexpr auto ADC2 = reinterpret_cast<ADC_TypeDef *> (ADC2_BASE);
+constexpr auto ADC3 = reinterpret_cast<ADC_TypeDef *> (ADC3_BASE);
+constexpr auto SDIO = reinterpret_cast<SDIO_TypeDef *> (SDIO_BASE);
+constexpr auto SPI1 = reinterpret_cast<SPI_TypeDef *> (SPI1_BASE) ;
+constexpr auto SPI4 = reinterpret_cast<SPI_TypeDef *> (SPI4_BASE);
+constexpr auto SYSCFG = reinterpret_cast<SYSCFG_TypeDef *> (SYSCFG_BASE);
+constexpr auto EXTI = reinterpret_cast<EXTI_TypeDef *> (EXTI_BASE);
+constexpr auto TIM9 = reinterpret_cast<TIM_TypeDef *> (TIM9_BASE);
+constexpr auto TIM10 = reinterpret_cast<TIM_TypeDef *> (TIM10_BASE);
+constexpr auto TIM11 = reinterpret_cast<TIM_TypeDef *> (TIM11_BASE);
+constexpr auto SPI5 = reinterpret_cast<SPI_TypeDef *> (SPI5_BASE);
+constexpr auto SPI6 = reinterpret_cast<SPI_TypeDef *> (SPI6_BASE);
+constexpr auto SAI1 = reinterpret_cast<SAI_TypeDef *> (SAI1_BASE);
+constexpr auto SAI1_Block_A = reinterpret_cast<SAI_Block_TypeDef *> (SAI1_Block_A_BASE);
+constexpr auto SAI1_Block_B = reinterpret_cast<SAI_Block_TypeDef *> (SAI1_Block_B_BASE);
+constexpr auto LTDC = reinterpret_cast<LTDC_TypeDef *> (LTDC_BASE);
+constexpr auto LTDC_Layer1 = reinterpret_cast<LTDC_Layer_TypeDef *> (LTDC_Layer1_BASE);
+constexpr auto LTDC_Layer2 = reinterpret_cast<LTDC_Layer_TypeDef *> (LTDC_Layer2_BASE);
+constexpr auto GPIOA = reinterpret_cast<GPIO_TypeDef *> (GPIOA_BASE);
+constexpr auto GPIOB = reinterpret_cast<GPIO_TypeDef *> (GPIOB_BASE);
+constexpr auto GPIOC = reinterpret_cast<GPIO_TypeDef *> (GPIOC_BASE);
+constexpr auto GPIOD = reinterpret_cast<GPIO_TypeDef *> (GPIOD_BASE);
+constexpr auto GPIOE = reinterpret_cast<GPIO_TypeDef *> (GPIOE_BASE);
+constexpr auto GPIOF = reinterpret_cast<GPIO_TypeDef *> (GPIOF_BASE);
+constexpr auto GPIOG = reinterpret_cast<GPIO_TypeDef *> (GPIOG_BASE);
+constexpr auto GPIOH = reinterpret_cast<GPIO_TypeDef *> (GPIOH_BASE);
+constexpr auto GPIOI = reinterpret_cast<GPIO_TypeDef *> (GPIOI_BASE);
+constexpr auto GPIOJ = reinterpret_cast<GPIO_TypeDef *> (GPIOJ_BASE);
+constexpr auto GPIOK = reinterpret_cast<GPIO_TypeDef *> (GPIOK_BASE);
+constexpr auto CRC = reinterpret_cast<CRC_TypeDef *> (CRC_BASE);
+constexpr auto RCC = reinterpret_cast<RCC_TypeDef *> (RCC_BASE);
+constexpr auto FLASH = reinterpret_cast<FLASH_TypeDef *> (FLASH_R_BASE);
+constexpr auto DMA1 = reinterpret_cast<DMA_TypeDef *> (DMA1_BASE);
+constexpr auto DMA1_Stream0 = reinterpret_cast<DMA_Stream_TypeDef *> (DMA1_Stream0_BASE);
+constexpr auto DMA1_Stream1 = reinterpret_cast<DMA_Stream_TypeDef *> (DMA1_Stream1_BASE);
+constexpr auto DMA1_Stream2 = reinterpret_cast<DMA_Stream_TypeDef *> (DMA1_Stream2_BASE);
+constexpr auto DMA1_Stream3 = reinterpret_cast<DMA_Stream_TypeDef *> (DMA1_Stream3_BASE);
+constexpr auto DMA1_Stream4 = reinterpret_cast<DMA_Stream_TypeDef *> (DMA1_Stream4_BASE);
+constexpr auto DMA1_Stream5 = reinterpret_cast<DMA_Stream_TypeDef *> (DMA1_Stream5_BASE);
+constexpr auto DMA1_Stream6 = reinterpret_cast<DMA_Stream_TypeDef *> (DMA1_Stream6_BASE);
+constexpr auto DMA1_Stream7 = reinterpret_cast<DMA_Stream_TypeDef *> (DMA1_Stream7_BASE);
+constexpr auto DMA2 = reinterpret_cast<DMA_TypeDef *> (DMA2_BASE);
+constexpr auto DMA2_Stream0 = reinterpret_cast<DMA_Stream_TypeDef *> (DMA2_Stream0_BASE);
+constexpr auto DMA2_Stream1 = reinterpret_cast<DMA_Stream_TypeDef *> (DMA2_Stream1_BASE);
+constexpr auto DMA2_Stream2 = reinterpret_cast<DMA_Stream_TypeDef *> (DMA2_Stream2_BASE);
+constexpr auto DMA2_Stream3 = reinterpret_cast<DMA_Stream_TypeDef *> (DMA2_Stream3_BASE);
+constexpr auto DMA2_Stream4 = reinterpret_cast<DMA_Stream_TypeDef *> (DMA2_Stream4_BASE);
+constexpr auto DMA2_Stream5 = reinterpret_cast<DMA_Stream_TypeDef *> (DMA2_Stream5_BASE);
+constexpr auto DMA2_Stream6 = reinterpret_cast<DMA_Stream_TypeDef *> (DMA2_Stream6_BASE);
+constexpr auto DMA2_Stream7 = reinterpret_cast<DMA_Stream_TypeDef *> (DMA2_Stream7_BASE);
+constexpr auto ETH = reinterpret_cast<ETH_TypeDef *> (ETH_BASE) ;
+constexpr auto DMA2D = reinterpret_cast<DMA2D_TypeDef *> (DMA2D_BASE);
+constexpr auto DCMI = reinterpret_cast<DCMI_TypeDef *> (DCMI_BASE);
+constexpr auto CRYP = reinterpret_cast<CRYP_TypeDef *> (CRYP_BASE);
+constexpr auto HASH = reinterpret_cast<HASH_TypeDef *> (HASH_BASE);
+constexpr auto HASH_DIGEST = reinterpret_cast<HASH_DIGEST_TypeDef *> (HASH_DIGEST_BASE);
+constexpr auto RNG = reinterpret_cast<RNG_TypeDef *> (RNG_BASE);
+constexpr auto FMC_Bank1 = reinterpret_cast<FMC_Bank1_TypeDef *> (FMC_Bank1_R_BASE);
+constexpr auto FMC_Bank1E = reinterpret_cast<FMC_Bank1E_TypeDef *> (FMC_Bank1E_R_BASE);
+constexpr auto FMC_Bank2_3 = reinterpret_cast<FMC_Bank2_3_TypeDef *> (FMC_Bank2_3_R_BASE);
+constexpr auto FMC_Bank4 = reinterpret_cast<FMC_Bank4_TypeDef *> (FMC_Bank4_R_BASE);
+constexpr auto FMC_Bank5_6 = reinterpret_cast<FMC_Bank5_6_TypeDef *> (FMC_Bank5_6_R_BASE);
+constexpr auto DBGMCU = reinterpret_cast<DBGMCU_TypeDef *> (DBGMCU_BASE);
+constexpr auto USB_OTG_FS = reinterpret_cast<USB_OTG_TypeDef *> (USB_OTG_FS_PERIPH_BASE);
+constexpr auto USB_OTG_HS = reinterpret_cast<USB_OTG_TypeDef *> (USB_OTG_HS_PERIPH_BASE);
+constexpr auto DESIG = reinterpret_cast<DESIG_TypeDef *> (DESIG_BASE);
+
+} // namespace reg
+
+} // namespace ucoo
+
+#endif // ucoo_arch_reg_stm32f4_hh
diff --git a/ucoo/arch/vector.arm.cc b/ucoo/arch/vector.arm.cc
new file mode 100644
index 0000000..3e0922a
--- /dev/null
+++ b/ucoo/arch/vector.arm.cc
@@ -0,0 +1,136 @@
+// ucoolib - Microcontroller object oriented library. {{{
+//
+// Copyright (C) 2016 Nicolas Schodet
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+//
+// }}}
+#include "ucoo/common.hh"
+#include "ucoo/arch/interrupt.arm.hh"
+
+#if defined (TARGET_stm32f4)
+# include "ucoo/arch/vector.stm32f4.hh"
+#elif defined (TARGET_stm32f1)
+# include "ucoo/arch/vector.stm32f1.hh"
+#else
+# error "not implemented for this target"
+#endif
+
+extern uint32_t _stack;
+
+extern "C" void entry ();
+
+namespace ucoo {
+
+typedef void (*vector_t) (void);
+
+struct vector_table_t
+{
+ uint32_t *initial_stack;
+ vector_t exception[static_cast<int> (Exception::COUNT) - 1];
+ vector_t irq[static_cast<int> (Irq::COUNT)];
+};
+
+template<> void interrupt<Exception::NMI> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Exception::HARD_FAULT> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Exception::MEMORY_MANAGEMENT_FAULT> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Exception::BUS_FAULT> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Exception::USAGE_FAULT> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Exception::SV_CALL> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Exception::PEND_SV> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Exception::SYSTICK> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+
+vector_table_t vector_table __attribute__ ((section (".vectors"))) =
+{
+ .initial_stack = &_stack,
+ {
+ entry,
+ interrupt<Exception::NMI>,
+ interrupt<Exception::HARD_FAULT>,
+ interrupt<Exception::MEMORY_MANAGEMENT_FAULT>,
+ interrupt<Exception::BUS_FAULT>,
+ interrupt<Exception::USAGE_FAULT>,
+ nullptr,
+ nullptr,
+ nullptr,
+ nullptr,
+ interrupt<Exception::SV_CALL>,
+ nullptr,
+ nullptr,
+ interrupt<Exception::PEND_SV>,
+ interrupt<Exception::SYSTICK>
+ },
+ {
+ UCOO_VECTOR_IRQ
+ }
+};
+
+extern "C" void
+undefined_handler ()
+{
+ halt ();
+}
+
+} // namespace ucoo
+
+int main ();
+
+extern uint32_t _data_loadaddr;
+extern uint32_t _data;
+extern uint32_t _edata;
+extern uint32_t _ebss;
+extern uint32_t __preinit_array_start;
+extern uint32_t __preinit_array_end;
+extern uint32_t __init_array_start;
+extern uint32_t __init_array_end;
+extern uint32_t __fini_array_start;
+extern uint32_t __fini_array_end;
+
+extern "C" void __attribute__ ((naked))
+entry ()
+{
+ uint32_t *src = &_data_loadaddr, *dst = &_data;
+ while (dst < &_edata)
+ *dst++ = *src++;
+ while (dst < &_ebss)
+ *dst++ = 0;
+ SCB->CCR |= SCB_CCR_STKALIGN_Msk;
+#if __FPU_USED
+ SCB->CPACR |= SCB_CPACR_CP10_Full | SCB_CPACR_CP11_Full;
+#endif
+ uint32_t *fp;
+ fp = &__preinit_array_start;
+ while (fp < &__preinit_array_end)
+ reinterpret_cast<void (*) ()> (*fp++) ();
+ fp = &__init_array_start;
+ while (fp < &__init_array_end)
+ reinterpret_cast<void (*) ()> (*fp++) ();
+ main ();
+ fp = &__fini_array_start;
+ while (fp < &__fini_array_end)
+ reinterpret_cast<void (*) ()> (*fp++) ();
+}
diff --git a/ucoo/arch/vector.stm32f1.hh b/ucoo/arch/vector.stm32f1.hh
new file mode 100644
index 0000000..39d3fd4
--- /dev/null
+++ b/ucoo/arch/vector.stm32f1.hh
@@ -0,0 +1,220 @@
+#ifndef ucoo_arch_vector_stm32f1_hh
+#define ucoo_arch_vector_stm32f1_hh
+// ucoolib - Microcontroller object oriented library. {{{
+//
+// Copyright (C) 2016 Nicolas Schodet
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+//
+// }}}
+
+#define UCOO_VECTOR_IRQ \
+ interrupt<Irq::WWDG>, \
+ interrupt<Irq::PVD>, \
+ interrupt<Irq::TAMPER>, \
+ interrupt<Irq::RTC>, \
+ interrupt<Irq::FLASH>, \
+ interrupt<Irq::RCC>, \
+ interrupt<Irq::EXTI0>, \
+ interrupt<Irq::EXTI1>, \
+ interrupt<Irq::EXTI2>, \
+ interrupt<Irq::EXTI3>, \
+ interrupt<Irq::EXTI4>, \
+ interrupt<Irq::DMA1_Channel1>, \
+ interrupt<Irq::DMA1_Channel2>, \
+ interrupt<Irq::DMA1_Channel3>, \
+ interrupt<Irq::DMA1_Channel4>, \
+ interrupt<Irq::DMA1_Channel5>, \
+ interrupt<Irq::DMA1_Channel6>, \
+ interrupt<Irq::DMA1_Channel7>, \
+ interrupt<Irq::ADC1_2>, \
+ interrupt<Irq::CAN1_TX>, \
+ interrupt<Irq::CAN1_RX0>, \
+ interrupt<Irq::CAN1_RX1>, \
+ interrupt<Irq::CAN1_SCE>, \
+ interrupt<Irq::EXTI9_5>, \
+ interrupt<Irq::TIM1_BRK>, \
+ interrupt<Irq::TIM1_UP>, \
+ interrupt<Irq::TIM1_TRG_COM>, \
+ interrupt<Irq::TIM1_CC>, \
+ interrupt<Irq::TIM2>, \
+ interrupt<Irq::TIM3>, \
+ interrupt<Irq::TIM4>, \
+ interrupt<Irq::I2C1_EV>, \
+ interrupt<Irq::I2C1_ER>, \
+ interrupt<Irq::I2C2_EV>, \
+ interrupt<Irq::I2C2_ER>, \
+ interrupt<Irq::SPI1>, \
+ interrupt<Irq::SPI2>, \
+ interrupt<Irq::USART1>, \
+ interrupt<Irq::USART2>, \
+ interrupt<Irq::USART3>, \
+ interrupt<Irq::EXTI15_10>, \
+ interrupt<Irq::RTC_Alarm>, \
+ interrupt<Irq::OTG_FS_WKUP>, \
+ nullptr, \
+ nullptr, \
+ nullptr, \
+ nullptr, \
+ nullptr, \
+ nullptr, \
+ nullptr, \
+ interrupt<Irq::TIM5>, \
+ interrupt<Irq::SPI3>, \
+ interrupt<Irq::UART4>, \
+ interrupt<Irq::UART5>, \
+ interrupt<Irq::TIM6>, \
+ interrupt<Irq::TIM7>, \
+ interrupt<Irq::DMA2_Channel1>, \
+ interrupt<Irq::DMA2_Channel2>, \
+ interrupt<Irq::DMA2_Channel3>, \
+ interrupt<Irq::DMA2_Channel4>, \
+ interrupt<Irq::DMA2_Channel5>, \
+ nullptr, \
+ nullptr, \
+ interrupt<Irq::CAN2_TX>, \
+ interrupt<Irq::CAN2_RX0>, \
+ interrupt<Irq::CAN2_RX1>, \
+ interrupt<Irq::CAN2_SCE>, \
+ interrupt<Irq::OTG_FS>
+
+namespace ucoo {
+
+template<> void interrupt<Irq::WWDG> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::PVD> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::TAMPER> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::RTC> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::FLASH> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::RCC> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::EXTI0> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::EXTI1> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::EXTI2> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::EXTI3> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::EXTI4> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::DMA1_Channel1> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::DMA1_Channel2> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::DMA1_Channel3> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::DMA1_Channel4> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::DMA1_Channel5> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::DMA1_Channel6> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::DMA1_Channel7> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::ADC1_2> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::CAN1_TX> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::CAN1_RX0> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::CAN1_RX1> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::CAN1_SCE> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::EXTI9_5> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::TIM1_BRK> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::TIM1_UP> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::TIM1_TRG_COM> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::TIM1_CC> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::TIM2> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::TIM3> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::TIM4> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::I2C1_EV> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::I2C1_ER> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::I2C2_EV> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::I2C2_ER> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::SPI1> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::SPI2> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::USART1> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::USART2> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::USART3> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::EXTI15_10> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::RTC_Alarm> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::OTG_FS_WKUP> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::TIM5> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::SPI3> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::UART4> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::UART5> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::TIM6> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::TIM7> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::DMA2_Channel1> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::DMA2_Channel2> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::DMA2_Channel3> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::DMA2_Channel4> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::DMA2_Channel5> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::CAN2_TX> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::CAN2_RX0> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::CAN2_RX1> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::CAN2_SCE> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::OTG_FS> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+
+} // namespace ucoo
+
+#endif // ucoo_arch_vector_stm32f1_hh
diff --git a/ucoo/arch/vector.stm32f4.hh b/ucoo/arch/vector.stm32f4.hh
new file mode 100644
index 0000000..5fe1bae
--- /dev/null
+++ b/ucoo/arch/vector.stm32f4.hh
@@ -0,0 +1,307 @@
+#ifndef ucoo_arch_vector_stm32f4_hh
+#define ucoo_arch_vector_stm32f4_hh
+// ucoolib - Microcontroller object oriented library. {{{
+//
+// Copyright (C) 2016 Nicolas Schodet
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+//
+// }}}
+
+#define UCOO_VECTOR_IRQ \
+ interrupt<Irq::WWDG>, \
+ interrupt<Irq::PVD>, \
+ interrupt<Irq::TAMP_STAMP>, \
+ interrupt<Irq::RTC_WKUP>, \
+ interrupt<Irq::FLASH>, \
+ interrupt<Irq::RCC>, \
+ interrupt<Irq::EXTI0>, \
+ interrupt<Irq::EXTI1>, \
+ interrupt<Irq::EXTI2>, \
+ interrupt<Irq::EXTI3>, \
+ interrupt<Irq::EXTI4>, \
+ interrupt<Irq::DMA1_Stream0>, \
+ interrupt<Irq::DMA1_Stream1>, \
+ interrupt<Irq::DMA1_Stream2>, \
+ interrupt<Irq::DMA1_Stream3>, \
+ interrupt<Irq::DMA1_Stream4>, \
+ interrupt<Irq::DMA1_Stream5>, \
+ interrupt<Irq::DMA1_Stream6>, \
+ interrupt<Irq::ADC>, \
+ interrupt<Irq::CAN1_TX>, \
+ interrupt<Irq::CAN1_RX0>, \
+ interrupt<Irq::CAN1_RX1>, \
+ interrupt<Irq::CAN1_SCE>, \
+ interrupt<Irq::EXTI9_5>, \
+ interrupt<Irq::TIM1_BRK_TIM9>, \
+ interrupt<Irq::TIM1_UP_TIM10>, \
+ interrupt<Irq::TIM1_TRG_COM_TIM11>, \
+ interrupt<Irq::TIM1_CC>, \
+ interrupt<Irq::TIM2>, \
+ interrupt<Irq::TIM3>, \
+ interrupt<Irq::TIM4>, \
+ interrupt<Irq::I2C1_EV>, \
+ interrupt<Irq::I2C1_ER>, \
+ interrupt<Irq::I2C2_EV>, \
+ interrupt<Irq::I2C2_ER>, \
+ interrupt<Irq::SPI1>, \
+ interrupt<Irq::SPI2>, \
+ interrupt<Irq::USART1>, \
+ interrupt<Irq::USART2>, \
+ interrupt<Irq::USART3>, \
+ interrupt<Irq::EXTI15_10>, \
+ interrupt<Irq::RTC_Alarm>, \
+ interrupt<Irq::OTG_FS_WKUP>, \
+ interrupt<Irq::TIM8_BRK_TIM12>, \
+ interrupt<Irq::TIM8_UP_TIM13>, \
+ interrupt<Irq::TIM8_TRG_COM_TIM14>, \
+ interrupt<Irq::TIM8_CC>, \
+ interrupt<Irq::DMA1_Stream7>, \
+ interrupt<Irq::FMC>, \
+ interrupt<Irq::SDIO>, \
+ interrupt<Irq::TIM5>, \
+ interrupt<Irq::SPI3>, \
+ interrupt<Irq::UART4>, \
+ interrupt<Irq::UART5>, \
+ interrupt<Irq::TIM6_DAC>, \
+ interrupt<Irq::TIM7>, \
+ interrupt<Irq::DMA2_Stream0>, \
+ interrupt<Irq::DMA2_Stream1>, \
+ interrupt<Irq::DMA2_Stream2>, \
+ interrupt<Irq::DMA2_Stream3>, \
+ interrupt<Irq::DMA2_Stream4>, \
+ interrupt<Irq::ETH>, \
+ interrupt<Irq::ETH_WKUP>, \
+ interrupt<Irq::CAN2_TX>, \
+ interrupt<Irq::CAN2_RX0>, \
+ interrupt<Irq::CAN2_RX1>, \
+ interrupt<Irq::CAN2_SCE>, \
+ interrupt<Irq::OTG_FS>, \
+ interrupt<Irq::DMA2_Stream5>, \
+ interrupt<Irq::DMA2_Stream6>, \
+ interrupt<Irq::DMA2_Stream7>, \
+ interrupt<Irq::USART6>, \
+ interrupt<Irq::I2C3_EV>, \
+ interrupt<Irq::I2C3_ER>, \
+ interrupt<Irq::OTG_HS_EP1_OUT>, \
+ interrupt<Irq::OTG_HS_EP1_IN>, \
+ interrupt<Irq::OTG_HS_WKUP>, \
+ interrupt<Irq::OTG_HS>, \
+ interrupt<Irq::DCMI>, \
+ interrupt<Irq::CRYP>, \
+ interrupt<Irq::HASH_RNG>, \
+ interrupt<Irq::FPU>, \
+ interrupt<Irq::UART7>, \
+ interrupt<Irq::UART8>, \
+ interrupt<Irq::SPI4>, \
+ interrupt<Irq::SPI5>, \
+ interrupt<Irq::SPI6>, \
+ interrupt<Irq::SAI1>, \
+ interrupt<Irq::LTDC>, \
+ interrupt<Irq::LTDC_ER>, \
+ interrupt<Irq::DMA2D>
+
+namespace ucoo {
+
+template<> void interrupt<Irq::WWDG> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::PVD> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::TAMP_STAMP> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::RTC_WKUP> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::FLASH> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::RCC> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::EXTI0> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::EXTI1> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::EXTI2> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::EXTI3> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::EXTI4> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::DMA1_Stream0> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::DMA1_Stream1> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::DMA1_Stream2> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::DMA1_Stream3> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::DMA1_Stream4> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::DMA1_Stream5> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::DMA1_Stream6> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::ADC> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::CAN1_TX> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::CAN1_RX0> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::CAN1_RX1> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::CAN1_SCE> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::EXTI9_5> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::TIM1_BRK_TIM9> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::TIM1_UP_TIM10> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::TIM1_TRG_COM_TIM11> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::TIM1_CC> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::TIM2> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::TIM3> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::TIM4> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::I2C1_EV> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::I2C1_ER> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::I2C2_EV> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::I2C2_ER> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::SPI1> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::SPI2> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::USART1> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::USART2> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::USART3> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::EXTI15_10> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::RTC_Alarm> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::OTG_FS_WKUP> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::TIM8_BRK_TIM12> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::TIM8_UP_TIM13> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::TIM8_TRG_COM_TIM14> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::TIM8_CC> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::DMA1_Stream7> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::FMC> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::SDIO> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::TIM5> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::SPI3> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::UART4> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::UART5> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::TIM6_DAC> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::TIM7> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::DMA2_Stream0> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::DMA2_Stream1> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::DMA2_Stream2> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::DMA2_Stream3> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::DMA2_Stream4> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::ETH> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::ETH_WKUP> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::CAN2_TX> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::CAN2_RX0> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::CAN2_RX1> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::CAN2_SCE> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::OTG_FS> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::DMA2_Stream5> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::DMA2_Stream6> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::DMA2_Stream7> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::USART6> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::I2C3_EV> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::I2C3_ER> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::OTG_HS_EP1_OUT> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::OTG_HS_EP1_IN> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::OTG_HS_WKUP> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::OTG_HS> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::DCMI> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::CRYP> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::HASH_RNG> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::FPU> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::UART7> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::UART8> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::SPI4> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::SPI5> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::SPI6> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::SAI1> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::LTDC> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::LTDC_ER> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+template<> void interrupt<Irq::DMA2D> ()
+ __attribute__ ((weak, alias ("undefined_handler")));
+
+} // namespace ucoo
+
+#endif // ucoo_arch_vector_stm32f4_hh