• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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