1 /***********************************************************************************************************************
2 * Copyright [2015-2017] Renesas Electronics Corporation and/or its licensors. All Rights Reserved.
3 *
4 * This file is part of Renesas SynergyTM Software Package (SSP)
5 *
6 * The contents of this file (the "contents") are proprietary and confidential to Renesas Electronics Corporation
7 * and/or its licensors ("Renesas") and subject to statutory and contractual protections.
8 *
9 * This file is subject to a Renesas SSP license agreement. Unless otherwise agreed in an SSP license agreement with
10 * Renesas: 1) you may not use, copy, modify, distribute, display, or perform the contents; 2) you may not use any name
11 * or mark of Renesas for advertising or publicity purposes or in connection with your use of the contents; 3) RENESAS
12 * MAKES NO WARRANTY OR REPRESENTATIONS ABOUT THE SUITABILITY OF THE CONTENTS FOR ANY PURPOSE; THE CONTENTS ARE PROVIDED
13 * "AS IS" WITHOUT ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
14 * PARTICULAR PURPOSE, AND NON-INFRINGEMENT; AND 4) RENESAS SHALL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL, OR
15 * CONSEQUENTIAL DAMAGES, INCLUDING DAMAGES RESULTING FROM LOSS OF USE, DATA, OR PROJECTS, WHETHER IN AN ACTION OF
16 * CONTRACT OR TORT, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THE CONTENTS. Third-party contents
17 * included in this file may be subject to different terms.
18 **********************************************************************************************************************/
19 /***********************************************************************************************************************
20 * File Name : system_S1JA.c
21 * Description : Initializes C runtime environment, system clocks, pins, and interrupts. Calls warm start functions.
22 ***********************************************************************************************************************/
23
24 /***********************************************************************************************************************
25 Includes <System Includes> , "Project Includes"
26 ***********************************************************************************************************************/
27 #include "bsp_api.h"
28 #include "stdlib.h"
29 #if defined(BSP_MCU_GROUP_S1JA)
30 #include "r_elc.h"
31 /* This include file is need only for the 'temporary' fix to insure that the Ioport reference counter is zeroed before it
32 * gets referenced. Ioport init is currently called before the C Runtime initialization takes place.
33 * It will be removed when a more complete solution for this problem is added.
34 */
35 #include "../../../src/driver/r_ioport/hw/hw_ioport_private.h"
36
37 /* BSP Pin Configuration. Allocate BSP pin configuration table in this module. */
38 #include "bsp_pin_cfg.h"
39
40 /***********************************************************************************************************************
41 Macro definitions
42 ***********************************************************************************************************************/
43
44 /***********************************************************************************************************************
45 Typedef definitions
46 ***********************************************************************************************************************/
47
48 /***********************************************************************************************************************
49 Exported global variables (to be accessed by other files)
50 ***********************************************************************************************************************/
51 /*LDRA_NOANALYSIS LDRA_INSPECTED below not working. */
52 /*LDRA_INSPECTED 27 D This variable must be be publicly accessible per the CMSIS standard. It cannot be static. */
53 uint32_t SystemCoreClock = 0U; /*!< System Clock Frequency (Core Clock)*/
54 /*LDRA_ANALYSIS */
55
56 #if defined(__GNUC__)
57 /* Generated by linker. */
58 /*LDRA_INSPECTED 219 S Linker sections start with underscore. */
59 extern uint32_t __etext;
60 /*LDRA_INSPECTED 219 S Linker sections start with underscore. */
61 extern uint32_t __data_start__;
62 /*LDRA_INSPECTED 219 S Linker sections start with underscore. */
63 extern uint32_t __data_end__;
64 /*LDRA_INSPECTED 219 S Linker sections start with underscore. */
65 extern uint32_t __bss_start__;
66 /*LDRA_INSPECTED 219 S Linker sections start with underscore. */
67 extern uint32_t __bss_end__;
68 #elif defined(__ICCARM__)
69 #pragma section=".bss"
70 #pragma section=".data"
71 #pragma section=".data_init"
72 #endif
73
74 /* Initialize Static Constructors */
75 #if defined(__GNUC__)
76 /*LDRA_INSPECTED 219 S In the GCC compiler, __init_array_start starts with underscore. */
77 /*LDRA_INSPECTED 219 S */
78 extern void (*__init_array_start []) (void);
79 /*LDRA_INSPECTED 219 S In the GCC compiler, __init_array_end starts with underscore. */
80 /*LDRA_INSPECTED 219 S */
81 extern void (*__init_array_end []) (void);
82 #elif defined(__ICCARM__)
83 extern void __call_ctors(void const *, void const *);
84 #pragma section = "SHT$$PREINIT_ARRAY" const
85 #pragma section = "SHT$$INIT_ARRAY" const
86 #endif
87
88 /* IOPORT implementation for this BSP. */
89 extern const ioport_api_t g_ioport_on_ioport;
90
91 /***********************************************************************************************************************
92 Private global variables and functions
93 ***********************************************************************************************************************/
94 static void bsp_section_zero(uint8_t * pstart, uint32_t bytes);
95 static void bsp_section_copy(uint8_t * psource, uint8_t * pdest, uint32_t bytes);
96 static void bsp_reset_trng_circuit(void);
97 static void bsp_init_prng(void);
98
99 /* ram section to read for prng seed generation */
100 /*LDRA_INSPECTED 219 S*/
101 /*LDRA_INSPECTED 57 D*/
102 /*LDRA_INSPECTED 57 D*/
103 static volatile uint64_t bsp_seed BSP_PLACE_IN_SECTION_V2(".noinit");
104
105 /** Currently this structure is not being used. Eventually it will be tool generated. */
106 static const elc_cfg_t g_elc_cfg =
107 {
108 .autostart = true,
109 .link_count = 0U,
110 .link_list = NULL
111 };
112
113 #if defined(__ICCARM__)
114 #pragma weak R_BSP_WarmStart
115 void R_BSP_WarmStart(bsp_warm_start_event_t event);
116 #elif defined(__GNUC__)
117 /*LDRA_INSPECTED 293 S - There is no way to implement a weak reference without using a Non ANSI/ISO construct. */
118 void R_BSP_WarmStart (bsp_warm_start_event_t event) __attribute__ ((weak));
119 #endif
120
121 /***********************************************************************************************************************
122 * Function Name: SystemCoreClockUpdate
123 * Description : Update SystemCoreClock variable based on current clock settings.
124 * Arguments : none
125 * Return Value : none
126 ***********************************************************************************************************************/
SystemCoreClockUpdate(void)127 void SystemCoreClockUpdate (void)
128 {
129 SystemCoreClock = bsp_cpu_clock_get();
130 }
131
132 /***********************************************************************************************************************
133 * Function Name: SystemInit
134 * Description : Setup MCU.
135 * Arguments : none
136 * Return Value : none
137 ***********************************************************************************************************************/
SystemInit(void)138 void SystemInit (void)
139 {
140 /* Call Pre C runtime initialization hook. */
141 R_BSP_WarmStart(BSP_WARM_START_PRE_C);
142
143 /* Initialize register protection. */
144 bsp_register_protect_open();
145
146 /* Initialize grouped interrupts. */
147 bsp_group_interrupt_open();
148
149 /* Initialize FMI. */
150 g_fmi_on_fmi.init();
151
152 /* Configure system clocks using CGC module. */
153 bsp_clock_init();
154
155 /* To prevent an undesired current draw, this MCU requires a reset of the TRNG circuit subsequent to having the clocks initialized */
156 bsp_reset_trng_circuit();
157
158 /* Temporary fix to initialize ioport reference counter to 0, needed before C runtime init. This will be removed
159 * in the next release in favor of a more complete solution. */
160 HW_IOPORT_Init_Reference_Counter();
161
162 /* Initialize pins. */
163 g_ioport_on_ioport.init(&g_bsp_pin_cfg);
164
165 /* Initialize C runtime environment. */
166 /* Zero out BSS */
167 #if defined(__GNUC__)
168 bsp_section_zero((uint8_t *)&__bss_start__, ((uint32_t)&__bss_end__ - (uint32_t)&__bss_start__));
169 #elif defined(__ICCARM__)
170 bsp_section_zero((uint8_t *)__section_begin(".bss"), (uint32_t)__section_size(".bss"));
171 #endif
172
173 /* Copy initialized RAM data from ROM to RAM. */
174 #if defined(__GNUC__)
175 bsp_section_copy((uint8_t *)&__etext,
176 (uint8_t *)&__data_start__,
177 ((uint32_t)&__data_end__ - (uint32_t)&__data_start__));
178 #elif defined(__ICCARM__)
179 bsp_section_copy((uint8_t *)__section_begin(".data_init"),
180 (uint8_t *)__section_begin(".data"),
181 (uint32_t)__section_size(".data"));
182 /* Copy functions to be executed from RAM. */
183 #pragma section=".code_in_ram"
184 #pragma section=".code_in_ram_init"
185 bsp_section_copy((uint8_t *)__section_begin(".code_in_ram_init"),
186 (uint8_t *)__section_begin(".code_in_ram"),
187 (uint32_t)__section_size(".code_in_ram"));
188 /* Copy main thread TLS to RAM. */
189 #pragma section="__DLIB_PERTHREAD_init"
190 #pragma section="__DLIB_PERTHREAD"
191 bsp_section_copy((uint8_t *)__section_begin("__DLIB_PERTHREAD_init"),
192 (uint8_t *)__section_begin("__DLIB_PERTHREAD"),
193 (uint32_t)__section_size("__DLIB_PERTHREAD_init"));
194 #endif
195
196 #if defined(__IAR_SYSTEMS_ICC__)
197 #pragma section=".stack"
198 #elif defined(__GNUC__)
199 /*LDRA_INSPECTED 219 S Linker sections start with underscore. */
200 extern uint32_t __StackLimit;
201 /*LDRA_INSPECTED 219 S Linker sections start with underscore. */
202 extern uint32_t __StackTop;
203 #endif
204
205 R_SPMON->MSPMPUCTL = (uint16_t) 0x0000; /* Disable MSP monitoring */
206
207 R_SPMON->MSPMPUOAD = 0xA500; /* Setup NMI interrupt */
208
209 #if defined(__IAR_SYSTEMS_ICC__)
210 R_SPMON->MSPMPUSA = (uint32_t)__section_begin(".stack"); /* Setup start address */
211 R_SPMON->MSPMPUEA = (uint32_t)__section_end(".stack") - 1U;/* Setup end address */
212
213 #elif defined(__GNUC__)
214 R_SPMON->MSPMPUSA = (uint32_t)&__StackLimit; /* Setup start address */
215 R_SPMON->MSPMPUEA = (uint32_t)&__StackTop - 1U; /* Setup end address */
216
217 #endif
218
219 R_ICU->NMIER |= (uint16_t)0x1000; /* Set SPEEN bit to enable NMI on stack monitor exception */
220 R_SPMON->MSPMPUCTL = (uint16_t)0x0001; /* Enable MSP monitoring */
221
222 /* Initialize SystemCoreClock variable. */
223 SystemCoreClockUpdate();
224
225 /* Call Post C runtime initialization hook. */
226 R_BSP_WarmStart(BSP_WARM_START_POST_C);
227
228 /* Initialize Static Constructors */
229 #if defined(__GNUC__)
230 /*LDRA_INSPECTED 219 S In the GCC compiler, __init_array_start and __init_array_end starts with underscore. */
231 /*LDRA_INSPECTED 219 S */
232 int32_t count = __init_array_end - __init_array_start;
233 for (int32_t i = 0; i < count; i++)
234 {
235 __init_array_start [i]();
236 }
237 #elif defined(__ICCARM__)
238 void const * pibase = __section_begin("SHT$$PREINIT_ARRAY");
239 void const * ilimit = __section_end("SHT$$INIT_ARRAY");
240 __call_ctors(pibase, ilimit);
241 #endif
242
243 /* Initialize the Hardware locks to 'Unlocked' */
244 bsp_init_hardware_locks();
245
246 /* Initialize ELC events that will be used to trigger NVIC interrupts. */
247 bsp_irq_cfg();
248
249 /* Initialize ELC. */
250 g_elc_on_elc.init(&g_elc_cfg);
251
252 /* Initialize the libc pseudo random number generator */
253 bsp_init_prng();
254
255 /* Call any BSP specific code. No arguments are needed so NULL is sent. */
256 bsp_init(NULL);
257 }
258
259 /***********************************************************************************************************************
260 * Function Name: bsp_section_zero
261 * Description : Zero out input section
262 * Arguments : pstart -
263 * Start address of the section
264 * bytes -
265 * Size of section in bytes
266 * Return Value : none
267 ***********************************************************************************************************************/
bsp_section_zero(uint8_t * pstart,uint32_t bytes)268 static void bsp_section_zero (uint8_t * pstart, uint32_t bytes)
269 {
270 while (bytes > 0U)
271 {
272 bytes--;
273 pstart[bytes] = 0U;
274 }
275 }
276
277 /***********************************************************************************************************************
278 * Function Name: bsp_section_copy
279 * Description : Zero out input section
280 * Arguments : psource -
281 * Address of where to copy data from
282 * pdest -
283 * Address of where to copy data to
284 * bytes -
285 * Size of section in bytes
286 * Return Value : none
287 ***********************************************************************************************************************/
bsp_section_copy(uint8_t * psource,uint8_t * pdest,uint32_t bytes)288 static void bsp_section_copy (uint8_t * psource, uint8_t * pdest, uint32_t bytes)
289 {
290 uint32_t index;
291 for (index = 0U; index < bytes; index++,pdest++,psource++)
292 {
293 *pdest = *psource;
294 }
295 }
296
297 /***********************************************************************************************************************
298 * Function Name: R_BSP_WarmStart
299 * Description : This function is called at various points during the startup process. This function is declared as a
300 * weak symbol higher up in this file because it is meant to be overridden by a user implemented version.
301 * One of the main uses for this function is to call functional safety code during the startup process.
302 * To use this function just copy this function into your own code and modify it to meet your needs.
303 * Arguments : event -
304 * Where at in the start up process the code is currently at
305 * Return Value : none
306 ***********************************************************************************************************************/
R_BSP_WarmStart(bsp_warm_start_event_t event)307 void R_BSP_WarmStart (bsp_warm_start_event_t event)
308 {
309 if (BSP_WARM_START_PRE_C == event)
310 {
311 /* C runtime environment has not been setup so you cannot use globals. System clocks and pins are not setup. */
312 }
313 else if (BSP_WARM_START_POST_C == event)
314 {
315 /* C runtime environment, system clocks, and pins are all setup. */
316 }
317 else
318 {
319 /* Unhandled case. */
320 }
321 }
322
323 /*******************************************************************************************************************//**
324 * @brief Disable trng circuit to prevent unnecessary current draw which may otherwise occur when the Crypto module
325 * is not in use.
326 *
327 **********************************************************************************************************************/
bsp_reset_trng_circuit(void)328 static void bsp_reset_trng_circuit (void)
329 {
330 volatile uint8_t read_port = 0U;
331 SSP_PARAMETER_NOT_USED(read_port); /// Prevent compiler 'unused' warning
332
333 /* Enable TRNG function (disable stop function) */
334 R_MSTP->MSTPCRC_b.MSTPC28 = 0U; ///< TRNG Module Stop needs to be started/stopped for S1 series.
335
336 /* Wait for at least 3 PCLKB cycles */
337 read_port = R_PFS->P000PFS_b.PODR;
338 read_port = R_PFS->P000PFS_b.PODR;
339 read_port = R_PFS->P000PFS_b.PODR;
340
341 /* Disable TRNG function (enable stop function) */
342 R_MSTP->MSTPCRC_b.MSTPC28 = 1U;
343 }
344
345 /*******************************************************************************************************************//**
346 * @brief Read ram section that has not been initialized and use that value to generate a seed value for the libc PRNG.
347 *
348 **********************************************************************************************************************/
bsp_init_prng(void)349 static void bsp_init_prng(void)
350 {
351 uint64_t temp = (bsp_seed & 0xFFFFFFFF);
352 /*initialize srand() with SRAM value*/
353 srand( (uint32_t)(temp^(bsp_seed >> 32)) );
354 bsp_seed += (0xF4E64FE3A1E75416ULL); //large prime in LE64
355 bsp_seed ^= (0xFDAD522B9E92B837ULL); //another large prime in LE64
356 }
357
358 #endif
359