RISC-V/V003/math/ch32v003/startup.cpp

174 lines
6.9 KiB
C++
Raw Normal View History

2024-03-11 15:05:36 +01:00
#include "CH32V00xxx.h"
typedef __SIZE_TYPE__ size_t;
extern "C" {
extern void handle_reset () __attribute__((naked,nothrow,used));
extern void user_prog () __attribute__((used,noreturn));
extern int main () __attribute__((used));
extern void SystemInit() __attribute__((used));
// This is required to allow pure virtual functions to be defined.
void __cxa_pure_virtual() { while (1); }
void * memset(void * s, int c, size_t n) {
char * p = (char *) s;
for (unsigned i=0u; i<n; i++) p[i] = c;
return s;
}
// These magic symbols are provided by the linker.
extern uint32_t _sbss;
extern uint32_t _ebss;
extern uint32_t _data_lma;
extern uint32_t _data_vma;
extern uint32_t _edata;
extern void (*__preinit_array_start[]) (void) __attribute__((weak));
extern void (*__preinit_array_end[]) (void) __attribute__((weak));
extern void (*__init_array_start[]) (void) __attribute__((weak));
extern void (*__init_array_end[]) (void) __attribute__((weak));
static void __init_array () {
uint32_t * dst, * end;
/* Zero fill the bss section */
dst = &_sbss;
end = &_ebss;
while (dst < end) * dst++ = 0U;
/* Copy data section from flash to RAM */
uint32_t * src;
src = &_data_lma;
dst = &_data_vma;
end = &_edata;
if (src != dst) {
while (dst < end) * dst++ = * src++;
}
size_t count;
/* Pro Cortex-Mx bylo toto zbytečné, lze předpokládat, že je to tak i zde.
count = __preinit_array_end - __preinit_array_start;
for (unsigned i = 0; i < count; i++) __preinit_array_start[i]();
*/
count = __init_array_end - __init_array_start;
for (unsigned i = 0; i < count; i++) __init_array_start[i]();
}
// If you don't override a specific handler, it will just spin forever.
void DefaultIRQHandler( void ) {
// Infinite Loop
for (;;);
}
void NMI_RCC_CSS_IRQHandler( void ) {
RCC.INTR.B.CSSC = RESET; // clear the clock security int flag
}
#define ALIAS(f) __attribute__((nothrow,weak,alias(#f),used))
void NMI_Handler( void ) ALIAS(NMI_RCC_CSS_IRQHandler);
void HardFault_Handler( void ) ALIAS(DefaultIRQHandler);
void SysTick_Handler( void ) ALIAS(DefaultIRQHandler);
void SW_Handler( void ) ALIAS(DefaultIRQHandler);
void WWDG_IRQHandler( void ) ALIAS(DefaultIRQHandler);
void PVD_IRQHandler( void ) ALIAS(DefaultIRQHandler);
void FLASH_IRQHandler( void ) ALIAS(DefaultIRQHandler);
void RCC_IRQHandler( void ) ALIAS(DefaultIRQHandler);
void EXTI7_0_IRQHandler( void ) ALIAS(DefaultIRQHandler);
void AWU_IRQHandler( void ) ALIAS(DefaultIRQHandler);
void DMA1_Channel1_IRQHandler( void ) ALIAS(DefaultIRQHandler);
void DMA1_Channel2_IRQHandler( void ) ALIAS(DefaultIRQHandler);
void DMA1_Channel3_IRQHandler( void ) ALIAS(DefaultIRQHandler);
void DMA1_Channel4_IRQHandler( void ) ALIAS(DefaultIRQHandler);
void DMA1_Channel5_IRQHandler( void ) ALIAS(DefaultIRQHandler);
void DMA1_Channel6_IRQHandler( void ) ALIAS(DefaultIRQHandler);
void DMA1_Channel7_IRQHandler( void ) ALIAS(DefaultIRQHandler);
void ADC1_IRQHandler( void ) ALIAS(DefaultIRQHandler);
void TIM1_BRK_IRQHandler( void ) ALIAS(DefaultIRQHandler);
void TIM1_UP_IRQHandler( void ) ALIAS(DefaultIRQHandler);
void TIM1_TRG_COM_IRQHandler( void ) ALIAS(DefaultIRQHandler);
void TIM1_CC_IRQHandler( void ) ALIAS(DefaultIRQHandler);
void TIM2_IRQHandler( void ) ALIAS(DefaultIRQHandler);
void I2C1_EV_IRQHandler( void ) ALIAS(DefaultIRQHandler);
void I2C1_ER_IRQHandler( void ) ALIAS(DefaultIRQHandler);
void USART1_IRQHandler( void ) ALIAS(DefaultIRQHandler);
void SPI1_IRQHandler( void ) ALIAS(DefaultIRQHandler);
void InterruptVector() __attribute__((nothrow,naked,section(".init"),weak,alias("InterruptVectorDefault")));
void InterruptVectorDefault() __attribute__((nothrow,naked,section(".init")));
};
void InterruptVectorDefault() noexcept {
asm volatile( R"---(
.align 2
.option push
.option norvc
j handle_reset
.word 0
.word NMI_Handler /* NMI Handler */
.word HardFault_Handler /* Hard Fault Handler */
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word SysTick_Handler /* SysTick Handler */
.word 0
.word SW_Handler /* SW Handler */
.word 0
/* External Interrupts */
.word WWDG_IRQHandler /* Window Watchdog */
.word PVD_IRQHandler /* PVD through EXTI Line detect */
.word FLASH_IRQHandler /* Flash */
.word RCC_IRQHandler /* RCC */
.word EXTI7_0_IRQHandler /* EXTI Line 7..0 */
.word AWU_IRQHandler /* AWU */
.word DMA1_Channel1_IRQHandler /* DMA1 Channel 1 */
.word DMA1_Channel2_IRQHandler /* DMA1 Channel 2 */
.word DMA1_Channel3_IRQHandler /* DMA1 Channel 3 */
.word DMA1_Channel4_IRQHandler /* DMA1 Channel 4 */
.word DMA1_Channel5_IRQHandler /* DMA1 Channel 5 */
.word DMA1_Channel6_IRQHandler /* DMA1 Channel 6 */
.word DMA1_Channel7_IRQHandler /* DMA1 Channel 7 */
.word ADC1_IRQHandler /* ADC1 */
.word I2C1_EV_IRQHandler /* I2C1 Event */
.word I2C1_ER_IRQHandler /* I2C1 Error */
.word USART1_IRQHandler /* USART1 */
.word SPI1_IRQHandler /* SPI1 */
.word TIM1_BRK_IRQHandler /* TIM1 Break */
.word TIM1_UP_IRQHandler /* TIM1 Update */
.word TIM1_TRG_COM_IRQHandler /* TIM1 Trigger and Commutation */
.word TIM1_CC_IRQHandler /* TIM1 Capture Compare */
.word TIM2_IRQHandler /* TIM2 */
.option pop
)---");
}
void handle_reset() noexcept {
asm volatile(R"---(
.option push
.option norelax
la gp, __global_pointer$
.option pop
la sp, _eusrstack
)---"
#if __GNUC__ > 10
".option arch, +zicsr\n"
#endif
// Setup the interrupt vector, processor status and INTSYSCR.
R"---(
li a0, 0x80
csrw mstatus, a0
li a3, 0x3
la a0, InterruptVector
or a0, a0, a3
csrw mtvec, a0
/* Takhle RISC-V přejde do uživatelského programu. */
csrw mepc, %[user]
mret
)---"
: : [user]"r"(user_prog)
: "a0", "a3", "memory" );
}
void user_prog () {
SystemInit ();
__init_array();
main();
for (;;);
}