1 /***********************************************************************************************************************
2  * Copyright [2020-2024] Renesas Electronics Corporation and/or its affiliates.  All Rights Reserved.
3  *
4  * This software and documentation are supplied by Renesas Electronics Corporation and/or its affiliates and may only
5  * be used with products of Renesas Electronics Corp. and its affiliates ("Renesas").  No other uses are authorized.
6  * Renesas products are sold pursuant to Renesas terms and conditions of sale.  Purchasers are solely responsible for
7  * the selection and use of Renesas products and Renesas assumes no liability.  No license, express or implied, to any
8  * intellectual property right is granted by Renesas.  This software is protected under all applicable laws, including
9  * copyright laws. Renesas reserves the right to change or discontinue this software and/or this documentation.
10  * THE SOFTWARE AND DOCUMENTATION IS DELIVERED TO YOU "AS IS," AND RENESAS MAKES NO REPRESENTATIONS OR WARRANTIES, AND
11  * TO THE FULLEST EXTENT PERMISSIBLE UNDER APPLICABLE LAW, DISCLAIMS ALL WARRANTIES, WHETHER EXPLICITLY OR IMPLICITLY,
12  * INCLUDING WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT, WITH RESPECT TO THE
13  * SOFTWARE OR DOCUMENTATION.  RENESAS SHALL HAVE NO LIABILITY ARISING OUT OF ANY SECURITY VULNERABILITY OR BREACH.
14  * TO THE MAXIMUM EXTENT PERMITTED BY LAW, IN NO EVENT WILL RENESAS BE LIABLE TO YOU IN CONNECTION WITH THE SOFTWARE OR
15  * DOCUMENTATION (OR ANY PERSON OR ENTITY CLAIMING RIGHTS DERIVED FROM YOU) FOR ANY LOSS, DAMAGES, OR CLAIMS WHATSOEVER,
16  * INCLUDING, WITHOUT LIMITATION, ANY DIRECT, CONSEQUENTIAL, SPECIAL, INDIRECT, PUNITIVE, OR INCIDENTAL DAMAGES; ANY
17  * LOST PROFITS, OTHER ECONOMIC DAMAGE, PROPERTY DAMAGE, OR PERSONAL INJURY; AND EVEN IF RENESAS HAS BEEN ADVISED OF THE
18  * POSSIBILITY OF SUCH LOSS, DAMAGES, CLAIMS OR COSTS.
19  **********************************************************************************************************************/
20 
21 #ifndef BSP_COMMON_H
22 #define BSP_COMMON_H
23 
24 /***********************************************************************************************************************
25  * Includes   <System Includes> , "Project Includes"
26  **********************************************************************************************************************/
27 
28 /* C99 includes. */
29 #include <stdint.h>
30 #include <stddef.h>
31 #include <stdbool.h>
32 #include <assert.h>
33 #include <string.h>
34 
35 /* Different compiler support. */
36 #include "../../inc/fsp_common_api.h"
37 #include "bsp_compiler_support.h"
38 #include "bsp_cfg.h"
39 
40 /** Common macro for FSP header files. There is also a corresponding FSP_FOOTER macro at the end of this file. */
41 FSP_HEADER
42 
43 /*******************************************************************************************************************//**
44  * @addtogroup BSP_MCU
45  * @{
46  **********************************************************************************************************************/
47 
48 /***********************************************************************************************************************
49  * Macro definitions
50  **********************************************************************************************************************/
51 
52 /** Used to signify that an ELC event is not able to be used as an interrupt. */
53 #define BSP_IRQ_DISABLED                       (0xFFU)
54 
55 /* Vector Number offset */
56 #define BSP_VECTOR_NUM_OFFSET                  (32)
57 #define BSP_INTERRUPT_TYPE_OFFSET              (16U)
58 
59 #define FSP_CONTEXT_SAVE
60 #define FSP_CONTEXT_RESTORE
61 
62 #define BSP_PRV_CPU_FREQ_200_MHZ               (200000000U)  // CPU frequency is 200 MHz
63 #define BSP_PRV_CPU_FREQ_150_MHZ               (150000000U)  // CPU frequency is 150 MHz
64 
65 #define BSP_PRV_ICLK_FREQ_200_MHZ              (200000000U)  // ICLK frequency is 200 MHz
66 #define BSP_PRV_ICLK_FREQ_150_MHZ              (150000000U)  // ICLK frequency is 150 MHz
67 
68 #define BSP_PRV_PCLKH_FREQ_200_MHZ             (200000000U)  // PCLKH frequency is 200 MHz
69 #define BSP_PRV_PCLKH_FREQ_150_MHZ             (150000000U)  // PCLKH frequency is 150 MHz
70 
71 #define BSP_PRV_PCLKM_FREQ_100_MHZ             (100000000U)  // PCLKM frequency is 100 MHz
72 #define BSP_PRV_PCLKM_FREQ_75_MHZ              (75000000U)   // PCLKM frequency is 750 MHz
73 
74 #define BSP_PRV_PCLKL_FREQ_50_MHZ              (50000000U)   // PCLKL frequency is 50 MHz
75 #define BSP_PRV_PCLKL_FREQ_37_5_MHZ            (37500000U)   // PCLKL frequency is 37.5 MHz
76 
77 #define BSP_PRV_PCLKADC_FREQ_25_MHZ            (25000000U)   // PCLKADC frequency is 25 MHz
78 #define BSP_PRV_PCLKADC_FREQ_18_75_MHZ         (18750000U)   // PCLKADC frequency is 18.75 MHz
79 
80 #define BSP_PRV_PCLKGPTL_FREQ_400_MHZ          (400000000U)  // PCLKGPTL frequency is 400 MHz
81 #define BSP_PRV_PCLKGPTL_FREQ_300_MHZ          (300000000U)  // PCLKGPTL frequency is 300 MHz
82 
83 #define BSP_PRV_PCLKSCI_FREQ_75_MHZ            (75000000U)   // PCLKSCI frequency is 75 MHz
84 #define BSP_PRV_PCLKSCI_FREQ_96_MHZ            (96000000U)   // PCLKSCI frequency is 96 MHz
85 
86 #define BSP_PRV_PCLKSPI_FREQ_75_MHZ            (75000000U)   // PCLKSPI frequency is 75 MHz
87 #define BSP_PRV_PCLKSPI_FREQ_96_MHZ            (96000000U)   // PCLKSPI frequency is 96 MHz
88 
89 #define BSP_PRV_PCLKCAN_FREQ_80_MHZ            (80000000U)   // PCLKCAN frequency is 80 MHz
90 #define BSP_PRV_PCLKCAN_FREQ_40_MHZ            (40000000U)   // PCLKCAN frequency is 40 MHz
91 
92 #define BSP_PRV_CKIO_FREQ_100_MHZ              (100000000U)  // CKIO frequency is 100 MHz
93 #define BSP_PRV_CKIO_FREQ_75_MHZ               (75000000U)   // CKIO frequency is 75 MHz
94 #define BSP_PRV_CKIO_FREQ_66_7_MHZ             (66666666U)   // CKIO frequency is 66.7 MHz
95 #define BSP_PRV_CKIO_FREQ_50_MHZ               (50000000U)   // CKIO frequency is 50 MHz
96 #define BSP_PRV_CKIO_FREQ_40_MHZ               (40000000U)   // CKIO frequency is 40 MHz
97 #define BSP_PRV_CKIO_FREQ_37_5_MHZ             (37500000U)   // CKIO frequency is 37.5 MHz
98 #define BSP_PRV_CKIO_FREQ_33_3_MHZ             (33333333U)   // CKIO frequency is 33.3MHz
99 #define BSP_PRV_CKIO_FREQ_30_MHZ               (30000000U)   // CKIO frequency is 30 MHz
100 #define BSP_PRV_CKIO_FREQ_28_6_MHZ             (28571428U)   // CKIO frequency is 28.6 MHz
101 #define BSP_PRV_CKIO_FREQ_25_MHZ               (25000000U)   // CKIO frequency is 25 MHz
102 #define BSP_PRV_CKIO_FREQ_21_4_MHZ             (21428571U)   // CKIO frequency is 21.4 MHz
103 #define BSP_PRV_CKIO_FREQ_18_75_MHZ            (18750000U)   // CKIO frequency is 18.75 MHz
104 #define BSP_PRV_CKIO_FREQ_NOT_SUPPORTED        (0xFFFFFFFFU) // CKIO frequency is not supported
105 
106 #define BSP_PRV_XSPI_CLK_FREQ_133_3_MHZ        (133333333U)  // XSPI_CLK frequency is 133.3 MHz
107 #define BSP_PRV_XSPI_CLK_FREQ_100_MHZ          (100000000U)  // XSPI_CLK frequency is 100.0 MHz
108 #define BSP_PRV_XSPI_CLK_FREQ_75_MHZ           (75000000U)   // XSPI_CLK frequency is 75.0 MHz
109 #define BSP_PRV_XSPI_CLK_FREQ_50_MHZ           (50000000U)   // XSPI_CLK frequency is 50.0 MHz
110 #define BSP_PRV_XSPI_CLK_FREQ_37_5_MHZ         (37500000U)   // XSPI_CLK frequency is 37.5 MHz
111 #define BSP_PRV_XSPI_CLK_FREQ_25_MHZ           (25000000U)   // XSPI_CLK frequency is 25.0 MHz
112 #define BSP_PRV_XSPI_CLK_FREQ_12_5_MHZ         (12500000U)   // XSPI_CLK frequency is 12.5 MHz
113 #define BSP_PRV_XSPI_CLK_FREQ_NOT_SUPPORTED    (0xFFFFFFFFU) // XSPI_CLK frequency is not supported
114 
115 /** Macro to log and return error without an assertion. */
116 #ifndef FSP_RETURN
117 
118  #define FSP_RETURN(err)    FSP_ERROR_LOG((err)); \
119     return err;
120 #endif
121 
122 /** This function is called before returning an error code. To stop on a runtime error, define fsp_error_log in
123  * user code and do required debugging (breakpoints, stack dump, etc) in this function.*/
124 #if (1 == BSP_CFG_ERROR_LOG)
125 
126  #ifndef FSP_ERROR_LOG
127   #define FSP_ERROR_LOG(err) \
128     fsp_error_log((err), __FILE__, __LINE__);
129  #endif
130 #else
131 
132  #define FSP_ERROR_LOG(err)
133 #endif
134 
135 /** Default assertion calls ::FSP_ERROR_RETURN if condition "a" is false. Used to identify incorrect use of API's in FSP
136  * functions. */
137 #if (3 == BSP_CFG_ASSERT)
138  #define FSP_ASSERT(a)
139 #elif (2 == BSP_CFG_ASSERT)
140  #define FSP_ASSERT(a)    {assert(a);}
141 #else
142  #define FSP_ASSERT(a)    FSP_ERROR_RETURN((a), FSP_ERR_ASSERTION)
143 #endif                                 // ifndef FSP_ASSERT
144 
145 /** All FSP error codes are returned using this macro. Calls ::FSP_ERROR_LOG function if condition "a" is false. Used
146  * to identify runtime errors in FSP functions. */
147 
148 #define FSP_ERROR_RETURN(a, err)                        \
149     {                                                   \
150         if ((a))                                        \
151         {                                               \
152             (void) 0;                  /* Do nothing */ \
153         }                                               \
154         else                                            \
155         {                                               \
156             FSP_ERROR_LOG(err);                         \
157             return err;                                 \
158         }                                               \
159     }
160 
161 /* Function-like macro used to wait for a condition to be met, most often used to wait for hardware register updates.
162  * This macro can be redefined to add a timeout if necessary. */
163 #ifndef FSP_HARDWARE_REGISTER_WAIT
164  #define FSP_HARDWARE_REGISTER_WAIT(reg, required_value)    while (reg != required_value) { /* Wait. */}
165 #endif
166 
167 /* Function-like macro used to wait for a condition to be met with timeout,
168  * most often used to wait for hardware register updates. */
169 #define BSP_HARDWARE_REGISTER_WAIT_WTIH_TIMEOUT(reg, required_value, timeout) \
170     while ((timeout))                                                         \
171     {                                                                         \
172         if ((required_value) == (reg))                                        \
173         {                                                                     \
174             break;                                                            \
175         }                                                                     \
176         (timeout)--;                                                          \
177     }
178 
179 #ifndef BSP_CFG_IRQ_MASK_LEVEL_FOR_CRITICAL_SECTION
180  #define BSP_CFG_IRQ_MASK_LEVEL_FOR_CRITICAL_SECTION    (0U)
181 #endif
182 
183 /* This macro defines a variable for saving previous mask value */
184 #ifndef FSP_CRITICAL_SECTION_DEFINE
185 
186  #define FSP_CRITICAL_SECTION_DEFINE              uintptr_t old_mask_level = 0U
187 #endif
188 
189 /* These macros abstract methods to save and restore the interrupt state. */
190 #define FSP_CRITICAL_SECTION_GET_CURRENT_STATE    __get_ICC_PMR
191 #define FSP_CRITICAL_SECTION_SET_STATE            __set_ICC_PMR
192 #define FSP_CRITICAL_SECTION_IRQ_MASK_SET         ((uint8_t) (BSP_CFG_IRQ_MASK_LEVEL_FOR_CRITICAL_SECTION << \
193                                                               BSP_FEATURE_BSP_IRQ_PRIORITY_POS_BIT))
194 
195 /** This macro temporarily saves the current interrupt state and disables interrupts. */
196 #ifndef FSP_CRITICAL_SECTION_ENTER
197  #define FSP_CRITICAL_SECTION_ENTER                            \
198     old_mask_level = FSP_CRITICAL_SECTION_GET_CURRENT_STATE(); \
199     FSP_CRITICAL_SECTION_SET_STATE(FSP_CRITICAL_SECTION_IRQ_MASK_SET)
200 #endif
201 
202 /** This macro restores the previously saved interrupt state, reenabling interrupts. */
203 #ifndef FSP_CRITICAL_SECTION_EXIT
204  #define FSP_CRITICAL_SECTION_EXIT              FSP_CRITICAL_SECTION_SET_STATE(old_mask_level)
205 #endif
206 
207 /* Number of Cortex processor exceptions. */
208 #define FSP_PRIV_CORTEX_PROCESSOR_EXCEPTIONS    (32U)
209 
210 /** Used to signify that the requested IRQ vector is not defined in this system. */
211 #define FSP_INVALID_VECTOR                      ((IRQn_Type) - 33)
212 
213 /* This macro Enable or Disable interrupts. */
214 #define BSP_INTERRUPT_ENABLE                    __asm volatile ("cpsie i"); \
215     __asm volatile ("isb");
216 
217 #define BSP_INTERRUPT_DISABLE                   __asm volatile ("cpsid i"); \
218     __asm volatile ("isb");
219 
220 /** In the event of an unrecoverable error the BSP will by default call the __BKPT() intrinsic function which will
221  *  alert the user of the error. The user can override this default behavior by defining their own
222  *  BSP_CFG_HANDLE_UNRECOVERABLE_ERROR macro.
223  */
224 #if !defined(BSP_CFG_HANDLE_UNRECOVERABLE_ERROR)
225 
226  #define BSP_CFG_HANDLE_UNRECOVERABLE_ERROR(x)    __BKPT((x))
227 #endif
228 
229 /***********************************************************************************************************************
230  * Typedef definitions
231  **********************************************************************************************************************/
232 
233 /** Different warm start entry locations in the BSP. */
234 typedef enum e_bsp_warm_start_event
235 {
236     BSP_WARM_START_RESET = 0,          ///< Called almost immediately after reset. No C runtime environment, clocks, or IRQs.
237     BSP_WARM_START_POST_CLOCK,         ///< Called after clock initialization. No C runtime environment or IRQs.
238     BSP_WARM_START_POST_C              ///< Called after clocks and C runtime environment have been set up
239 } bsp_warm_start_event_t;
240 
241 /* Private enum used in R_FSP_SystemClockHzGet. */
242 typedef enum e_fsp_priv_clock
243 {
244     FSP_PRIV_CLOCK_CPU0      = 0,
245     FSP_PRIV_CLOCK_ICLK      = 2,
246     FSP_PRIV_CLOCK_PCLKH     = 3,
247     FSP_PRIV_CLOCK_PCLKM     = 4,
248     FSP_PRIV_CLOCK_PCLKL     = 5,
249     FSP_PRIV_CLOCK_PCLKADC   = 6,
250     FSP_PRIV_CLOCK_PCLKGPTL  = 7,
251     FSP_PRIV_CLOCK_PCLKSPI0  = 8,
252     FSP_PRIV_CLOCK_PCLKSPI1  = 9,
253     FSP_PRIV_CLOCK_PCLKSPI2  = 10,
254     FSP_PRIV_CLOCK_PCLKSPI3  = 11,
255     FSP_PRIV_CLOCK_PCLKSCI0  = 12,
256     FSP_PRIV_CLOCK_PCLKSCI1  = 13,
257     FSP_PRIV_CLOCK_PCLKSCI2  = 14,
258     FSP_PRIV_CLOCK_PCLKSCI3  = 15,
259     FSP_PRIV_CLOCK_PCLKSCI4  = 16,
260     FSP_PRIV_CLOCK_PCLKSCI5  = 17,
261     FSP_PRIV_CLOCK_PCLKCAN   = 18,
262     FSP_PRIV_CLOCK_CKIO      = 19,
263     FSP_PRIV_CLOCK_XSPI0_CLK = 20,
264     FSP_PRIV_CLOCK_XSPI1_CLK = 21,
265 } fsp_priv_clock_t;
266 
267 /***********************************************************************************************************************
268  * Exported global variables
269  **********************************************************************************************************************/
270 
271 extern const uint32_t g_bsp_system_clock_select[][2];
272 extern const uint32_t g_bsp_system_clock_select_ckio[][2];
273 extern const uint32_t g_bsp_system_clock_select_xspi_clk[][2];
274 
275 extern IRQn_Type g_current_interrupt_num[];
276 extern uint8_t   g_current_interrupt_pointer;
277 
278 /***********************************************************************************************************************
279  * Exported global functions (to be accessed by other files)
280  **********************************************************************************************************************/
281 
282 /***********************************************************************************************************************
283  * Inline Functions
284  **********************************************************************************************************************/
285 
286 /*******************************************************************************************************************//**
287  * Return active interrupt vector number value
288  *
289  * @return     Active interrupt vector number value
290  **********************************************************************************************************************/
R_FSP_CurrentIrqGet(void)291 __STATIC_INLINE IRQn_Type R_FSP_CurrentIrqGet (void)
292 {
293     /* Return the current interrupt number. */
294     return g_current_interrupt_num[(g_current_interrupt_pointer - 1U)];
295 }
296 
297 /*******************************************************************************************************************//**
298  * Gets the frequency of a system clock.
299  *
300  * @return     Frequency of requested clock in Hertz.
301  **********************************************************************************************************************/
R_FSP_SystemClockHzGet(fsp_priv_clock_t clock)302 __STATIC_INLINE uint32_t R_FSP_SystemClockHzGet (fsp_priv_clock_t clock)
303 {
304     uint32_t clock_hz = 0;
305     uint32_t fselcpu0 = R_SYSC_S->SCKCR2_b.FSELCPU0;
306 
307     switch (clock)
308     {
309         case FSP_PRIV_CLOCK_CPU0:
310         {
311             clock_hz = g_bsp_system_clock_select[clock][R_SYSC_S->SCKCR2_b.DIVSELSUB] << fselcpu0;
312             break;
313         }
314 
315         /* These iclk and pclk cases are intentionally combined. */
316         case FSP_PRIV_CLOCK_ICLK:
317         case FSP_PRIV_CLOCK_PCLKH:
318         case FSP_PRIV_CLOCK_PCLKM:
319         case FSP_PRIV_CLOCK_PCLKL:
320         case FSP_PRIV_CLOCK_PCLKADC:
321         case FSP_PRIV_CLOCK_PCLKGPTL:
322         {
323             clock_hz = g_bsp_system_clock_select[clock][R_SYSC_S->SCKCR2_b.DIVSELSUB];
324             break;
325         }
326 
327         case FSP_PRIV_CLOCK_PCLKSPI0:
328         {
329             clock_hz = g_bsp_system_clock_select[clock][R_SYSC_NS->SCKCR_b.SPI0ASYNCSEL];
330             break;
331         }
332 
333         case FSP_PRIV_CLOCK_PCLKSPI1:
334         {
335             clock_hz = g_bsp_system_clock_select[clock][R_SYSC_NS->SCKCR_b.SPI1ASYNCSEL];
336             break;
337         }
338 
339         case FSP_PRIV_CLOCK_PCLKSPI2:
340         {
341             clock_hz = g_bsp_system_clock_select[clock][R_SYSC_NS->SCKCR_b.SPI2ASYNCSEL];
342             break;
343         }
344 
345         case FSP_PRIV_CLOCK_PCLKSPI3:
346         {
347             clock_hz = g_bsp_system_clock_select[clock][R_SYSC_S->SCKCR2_b.SPI3ASYNCSEL];
348             break;
349         }
350 
351         case FSP_PRIV_CLOCK_PCLKSCI0:
352         {
353             clock_hz = g_bsp_system_clock_select[clock][R_SYSC_NS->SCKCR_b.SCI0ASYNCSEL];
354             break;
355         }
356 
357         case FSP_PRIV_CLOCK_PCLKSCI1:
358         {
359             clock_hz = g_bsp_system_clock_select[clock][R_SYSC_NS->SCKCR_b.SCI1ASYNCSEL];
360             break;
361         }
362 
363         case FSP_PRIV_CLOCK_PCLKSCI2:
364         {
365             clock_hz = g_bsp_system_clock_select[clock][R_SYSC_NS->SCKCR_b.SCI2ASYNCSEL];
366             break;
367         }
368 
369         case FSP_PRIV_CLOCK_PCLKSCI3:
370         {
371             clock_hz = g_bsp_system_clock_select[clock][R_SYSC_NS->SCKCR_b.SCI3ASYNCSEL];
372             break;
373         }
374 
375         case FSP_PRIV_CLOCK_PCLKSCI4:
376         {
377             clock_hz = g_bsp_system_clock_select[clock][R_SYSC_NS->SCKCR_b.SCI4ASYNCSEL];
378             break;
379         }
380 
381         case FSP_PRIV_CLOCK_PCLKSCI5:
382         {
383             clock_hz = g_bsp_system_clock_select[clock][R_SYSC_S->SCKCR2_b.SCI5ASYNCSEL];
384             break;
385         }
386 
387         case FSP_PRIV_CLOCK_PCLKCAN:
388         {
389             clock_hz = g_bsp_system_clock_select[clock][R_SYSC_NS->SCKCR_b.FSELCANFD];
390             break;
391         }
392 
393         case FSP_PRIV_CLOCK_CKIO:
394         {
395             uint32_t ckio = R_SYSC_NS->SCKCR_b.CKIO;
396             clock_hz = g_bsp_system_clock_select_ckio[ckio][R_SYSC_S->SCKCR2_b.DIVSELSUB];
397             break;
398         }
399 
400         case FSP_PRIV_CLOCK_XSPI0_CLK:
401         {
402             uint32_t fselxspi0 = R_SYSC_NS->SCKCR_b.FSELXSPI0;
403             clock_hz = g_bsp_system_clock_select_xspi_clk[fselxspi0][R_SYSC_NS->SCKCR_b.DIVSELXSPI0];
404             break;
405         }
406 
407         case FSP_PRIV_CLOCK_XSPI1_CLK:
408         {
409             uint32_t fselxspi1 = R_SYSC_NS->SCKCR_b.FSELXSPI1;
410             clock_hz = g_bsp_system_clock_select_xspi_clk[fselxspi1][R_SYSC_NS->SCKCR_b.DIVSELXSPI1];
411             break;
412         }
413 
414         default:
415         {
416             break;
417         }
418     }
419 
420     return clock_hz;
421 }
422 
423 #if ((1 == BSP_CFG_ERROR_LOG) || (1 == BSP_CFG_ASSERT))
424 
425 /** Prototype of default function called before errors are returned in FSP code if BSP_CFG_LOG_ERRORS is set to 1. */
426 void fsp_error_log(fsp_err_t err, const char * file, int32_t line);
427 
428 #endif
429 
430 /** @} (end addtogroup BSP_MCU) */
431 
432 /** Common macro for FSP header files. There is also a corresponding FSP_HEADER macro at the top of this file. */
433 FSP_FOOTER
434 
435 #endif
436