1 /**************************************************************************//**
2 * @file system_gr55xx.c
3 * @brief CMSIS Device System Source File for
4 * Device GR55xx
5 * @version V1.00
6 * @date 12. June 2018
7 ******************************************************************************/
8 /*
9 * Copyright (c) 2018 GOODIX. All rights reserved.
10 *
11 * SPDX-License-Identifier: Apache-2.0
12 *
13 * Licensed under the Apache License, Version 2.0 (the License); you may
14 * not use this file except in compliance with the License.
15 * You may obtain a copy of the License at
16 *
17 * www.apache.org/licenses/LICENSE-2.0
18 *
19 * Unless required by applicable law or agreed to in writing, software
20 * distributed under the License is distributed on an AS IS BASIS, WITHOUT
21 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22 * See the License for the specific language governing permissions and
23 * limitations under the License.
24 */
25
26 #include <stdint.h>
27 #include "gr55xx.h"
28 #include "gr55xx_sys.h"
29 #include "gr55xx_hal.h"
30 #include "platform_sdk.h"
31 #include "custom_config.h"
32 #include "gr55xx_rom_symbol.h"
33
34 /*----------------------------------------------------------------------------
35 WEAK Functions
36 *----------------------------------------------------------------------------*/
sdk_init(void)37 __WEAK void sdk_init(void)
38 {
39 /* Prevent unused argument(s) compilation warning */
40 return;
41 }
rom_init(void)42 __WEAK void rom_init(void)
43 {
44 /* Prevent unused argument(s) compilation warning */
45 return;
46 }
47
48 /*----------------------------------------------------------------------------
49 Define clocks
50 *----------------------------------------------------------------------------*/
51 #define SOFTWARE_REG_WAKEUP_FLAG_POS (8)
REG_PL_WR(uint32_t addr,uint32_t value)52 static inline void REG_PL_WR(uint32_t addr, uint32_t value)
53 {
54 (*((volatile uint32_t *)(addr))) = (value);
55 }
REG_PL_RD(uint32_t addr)56 static inline uint32_t REG_PL_RD(uint32_t addr)
57 {
58 return (*((volatile uint32_t *)(addr)));
59 }
60
61 #define SCB_CPACR_BASE_NUM 3UL
READ_VERSION_ADDR(void)62 static inline uint32_t READ_VERSION_ADDR(void)
63 {
64 return REG_PL_RD(0x45004);
65 }
66 #define CALIB_LP_CYCLE_COUNT 20
67
68 #define REGION_TABLE_LIMIT 0x0007e9c0
69 #define REGION_TABLE_BASE 0x0007e990
70 #define SCATTERLOAD_COPY 0x00062d05
71 #define SCATTERLOAD_ZEROINIT 0x00062d21
72 #define DFU_DATA_START_ADDR (0x800000 + 0x4000)
73
74 typedef struct {
75 uint32_t rom_addr;
76 uint32_t ram_addr;
77 uint32_t len;
78 uint32_t fun;
79 } sactter_copy_info_t;
80
81 volatile uint32_t g_app_msp_addr; /* record app msp address */
82
83 static const uint32_t systemClock[CLK_TYPE_NUM] = {
84 CLK_64M, /* CPLL_S64M_CLK */
85 CLK_48M, /* CPLL_F48M_CLK */
86 CLK_16M, /* XO_S16M_CLK */
87 CLK_24M, /* CPLL_T24M_CLK */
88 CLK_16M, /* CPLL_S16M_CLK */
89 CLK_32M, /* CPLL_T32M_CLK */
90 };
91
92 // xqspi clock table by sys_clk_type
93 const uint32_t mcu_clk_2_qspi_clk[CLK_TYPE_NUM] = {
94 [CPLL_S64M_CLK] = QSPI_64M_CLK,
95 [CPLL_F48M_CLK] = QSPI_48M_CLK,
96 [CPLL_T32M_CLK] = QSPI_32M_CLK,
97 [CPLL_T24M_CLK] = QSPI_24M_CLK,
98 [CPLL_S16M_CLK] = QSPI_16M_CLK,
99 [XO_S16M_CLK] = QSPI_16M_CLK,
100 };
101
102 /*----------------------------------------------------------------------------
103 System Core Clock Variable
104 *----------------------------------------------------------------------------*/
105 uint32_t SystemCoreClock = CLK_64M; /* System Core Clock Frequency as 64Mhz */
106
107 // lint -e{2,10,48,63}
108 // The previous line of comment is to inhibit PC-Lint errors for next code block.
SystemCoreSetClock(mcu_clock_type_t clock_type)109 void SystemCoreSetClock(mcu_clock_type_t clock_type)
110 {
111 if (clock_type >= CLK_TYPE_NUM)
112 return; // input parameter is out of range
113
114 if ((AON->PWR_RET01 & AON_PWR_REG01_SYS_CLK_SEL) != clock_type) {
115 uint32_t temp = AON->PWR_RET01 & (~(AON_PWR_REG01_SYS_CLK_SEL | AON_PWR_REG01_XF_SCK_CLK_SEL));
116 // When a 16M or 64M clock is switched to another clock, it needs to be switched to 32M first.
117 AON->PWR_RET01 = (temp | (CPLL_T32M_CLK << AON_PWR_REG01_SYS_CLK_SEL_Pos) |
118 (QSPI_32M_CLK << AON_PWR_REG01_XF_SCK_CLK_SEL_Pos));
119
120 __asm ("nop;nop;nop;nop;");
121 temp = AON->PWR_RET01 & (~(AON_PWR_REG01_SYS_CLK_SEL | AON_PWR_REG01_XF_SCK_CLK_SEL));
122 AON->PWR_RET01 = (temp | (clock_type << AON_PWR_REG01_SYS_CLK_SEL_Pos) |
123 (mcu_clk_2_qspi_clk[clock_type] << AON_PWR_REG01_XF_SCK_CLK_SEL_Pos));
124 }
125
126 SystemCoreClock = systemClock[clock_type];
127
128 // update sleep parameters by system clock.
129 pwr_mgmt_update_wkup_param();
130
131 return;
132 }
133
SystemCoreGetClock(mcu_clock_type_t * clock_type)134 void SystemCoreGetClock(mcu_clock_type_t *clock_type)
135 {
136 *clock_type = (mcu_clock_type_t)(AON->PWR_RET01 & AON_PWR_REG01_SYS_CLK_SEL);
137 }
138
SystemCoreUpdateClock(void)139 void SystemCoreUpdateClock(void)
140 {
141 SystemCoreClock = systemClock[AON->PWR_RET01 & AON_PWR_REG01_SYS_CLK_SEL];
142 }
143
get_wakeup_flag(void)144 static inline uint32_t get_wakeup_flag(void)
145 {
146 return (AON->SOFTWARE_2 & (1 << SOFTWARE_REG_WAKEUP_FLAG_POS));
147 }
148
set_msp(void)149 void set_msp(void)
150 {
151 #ifndef DRIVER_TEST
152 #ifdef APP_CODE_RUN_ADDR
153 __DMB();
154 __set_MSP(REG_PL_RD(APP_CODE_RUN_ADDR));
155 __DSB();
156 #endif
157 #endif
158 }
159
__sdk_init(void)160 static void __sdk_init(void)
161 {
162 sactter_copy_info_t sactter_copy_info = {0};
163
164 for (int i = 0; i < (REGION_TABLE_LIMIT - REGION_TABLE_BASE) / (sizeof(sactter_copy_info_t)); i++) {
165 memcpy_s((void *)&sactter_copy_info, sizeof (sactter_copy_info), \
166 (void *)(REGION_TABLE_BASE + i * sizeof(sactter_copy_info_t)), sizeof(sactter_copy_info_t));
167
168 if ((sactter_copy_info.fun + 1) == SCATTERLOAD_COPY) {
169 if (sactter_copy_info.ram_addr == DFU_DATA_START_ADDR) {
170 continue;
171 }
172 memcpy_s((void *)(sactter_copy_info.ram_addr), sactter_copy_info.len, \
173 (void *)(sactter_copy_info.rom_addr), sactter_copy_info.len);
174 } else {
175 if ((sactter_copy_info.fun + 1) == SCATTERLOAD_ZEROINIT) {
176 memset_s((void *)(sactter_copy_info.ram_addr), sactter_copy_info.len, 0, sactter_copy_info.len);
177 }
178 }
179 }
180 }
181
SystemInit(void)182 void SystemInit(void)
183 {
184 #if (__FPU_USED == 1)
185 SCB->CPACR |= ((SCB_CPACR_BASE_NUM << ITEM_10*ITEM_2) | /* set CP10 Full Access */
186 (SCB_CPACR_BASE_NUM << ITEM_11*ITEM_2) ); /* set CP11 Full Access */
187 #endif
188
189 #ifdef UNALIGNED_SUPPORT_DISABLE
190 SCB->CCR |= SCB_CCR_UNALIGN_TRP_Msk;
191 #endif
192
193 if (COLD_BOOT == get_wakeup_flag()) {
194 #if defined(GR5515_D)
195 __sdk_init();
196 #endif
197 }
198
199 return;
200 }
201
system_platform_init(void)202 void system_platform_init(void)
203 {
204 #if (!defined(ROM_RUN_IN_FLASH)) && defined(GR5515_E)
205 sdk_init();
206 #else
207 #if defined(GR5515_E)
208 rom_init();
209 #endif
210 #endif
211
212 platform_init();
213
214 /* record app msp */
215 g_app_msp_addr = REG_PL_RD(APP_CODE_RUN_ADDR);
216
217 return;
218 }
219
main_init(void)220 void main_init(void)
221 {
222 uint32_t boot_flag = get_wakeup_flag();
223 if (COLD_BOOT == boot_flag) {
224 __main();
225 } else {
226 pwr_mgmt_warm_boot();
227 while (1) {}
228 }
229 // Never execute here
230 }
231
232