blob: 3aacc661bfe8c62574a1e77bf79df2d4989720a9 (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
|
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include "ch573/systick.h"
#include "clock.h"
#include "io.h"
#include "isr_vector.h"
void on_reset(void);
#define SYSTICK_I CH573_SYSTICK__SYSTICK_T_INTF
#define SYSTICK ch573_systick__systick
void __attribute__((weak, interrupt, __section__(".isr_vector.routines")))
default_irq_handler(void)
{
return;
}
#define WEAK_IRQ(irq) \
void __attribute__(( \
weak, \
alias("default_irq_handler"), \
__section__(".isr_vector.routines"))) \
irq(void)
WEAK_IRQ(irq_on_reset);
WEAK_IRQ(irq_on_nmi);
WEAK_IRQ(irq_on_exc);
WEAK_IRQ(irq_on_systick);
WEAK_IRQ(irq_on_swi);
WEAK_IRQ(irq_on_tmr0);
WEAK_IRQ(irq_on_gpio_a);
WEAK_IRQ(irq_on_gpio_b);
WEAK_IRQ(irq_on_spi0);
WEAK_IRQ(irq_on_blel);
WEAK_IRQ(irq_on_bleb);
WEAK_IRQ(irq_on_usb);
WEAK_IRQ(irq_on_tmr1);
WEAK_IRQ(irq_on_tmr2);
WEAK_IRQ(irq_on_uart0);
WEAK_IRQ(irq_on_uart1);
WEAK_IRQ(irq_on_rtc);
WEAK_IRQ(irq_on_adc);
WEAK_IRQ(irq_on_pwmx);
WEAK_IRQ(irq_on_tmr3);
WEAK_IRQ(irq_on_uart2);
WEAK_IRQ(irq_on_uart3);
WEAK_IRQ(irq_on_wdog_bat);
// Memory-mapped address of the data values in flash.
extern uint32_t ISR_VECTOR_IN_FLASH;
// Where the data is located in sram.
extern uint32_t ISR_VECTOR_START;
extern uint32_t ISR_VECTOR_STOP;
// Memory-mapped address of the data values in flash.
extern uint32_t DATA_VALUES_IN_FLASH;
// Where the data is located in sram.
extern uint32_t DATA_SEGMENT_START;
extern uint32_t DATA_SEGMENT_STOP;
// Where 0-initialized data is in sram.
extern uint32_t BSS_START;
extern uint32_t BSS_STOP;
static inline void set_mtvec(void* vector_table)
{
uint32_t mtvec = (uint32_t)vector_table;
mtvec |= 1; // Set interrupt table mode to "VECTORED"
asm volatile("csrw mtvec, %0" : : "r"(mtvec));
}
/*
* Initialize the data segment and the bss segment.
*
* This function loads data in the .data section from flash and puts it in
* memory where it can be edited and initialized the BSS data to 0.
*/
void init_data_segments(void)
{
/* Copy the data from the flash to memory. */
uint32_t* src = &DATA_VALUES_IN_FLASH;
uint32_t* dest = &DATA_SEGMENT_START;
while (dest != &DATA_SEGMENT_STOP) {
*(dest++) = *(src++);
}
/* Copy the ISR vector to memory. This makes it possible to still recieve
* interrupts even when the flash is powered down. */
src = &ISR_VECTOR_IN_FLASH;
dest = &ISR_VECTOR_START;
while (dest != &ISR_VECTOR_STOP) {
*(dest++) = *(src++);
}
dest = &BSS_START;
while (dest != &BSS_STOP) {
*(dest++) = 0;
}
}
/*
* External reference to the main() function.
*/
extern int main(void);
/* Start function. Responsible for initializing the system and jumping to the
* main function. */
static __attribute((__section__(".sinit.1"))) void start(void)
{
/* Initialize the data segments. */
init_data_segments();
/* Set the mtvec to the isr_vector. */
set_mtvec(&isr_vector);
enable_interrupts();
/* Initialize stdout. */
init_uart1_for_stdout();
/* Jump to main */
main();
}
/*
* The reset callback.This has to be a naked function because the stack pointer
* may not be initialized!!.
*/
__attribute((naked, __section__(".sinit"))) void _begin(void)
{
// Set up the stack pointer to point to the end of SRAM.
asm volatile(
"li sp,0x20008000\n"
"addi sp,sp,-4\n"
"jalr %0\n"
"spin:\n"
"j spin\n"
:
: "r"(start));
}
|