1 /***********************************************************************************************************************
2 * Copyright [2020-2022] Renesas Electronics Corporation and/or its affiliates. All Rights Reserved.
3 *
4 * This software and documentation are supplied by Renesas Electronics America Inc. and may only be used with products
5 * of Renesas Electronics Corp. and its affiliates ("Renesas"). No other uses are authorized. Renesas products are
6 * sold pursuant to Renesas terms and conditions of sale. Purchasers are solely responsible for the selection and use
7 * of Renesas products and Renesas assumes no liability. No license, express or implied, to any intellectual property
8 * right is granted by Renesas. This software is protected under all applicable laws, including copyright laws. Renesas
9 * reserves the right to change or discontinue this software and/or this documentation. THE SOFTWARE AND DOCUMENTATION
10 * IS DELIVERED TO YOU "AS IS," AND RENESAS MAKES NO REPRESENTATIONS OR WARRANTIES, AND TO THE FULLEST EXTENT
11 * PERMISSIBLE UNDER APPLICABLE LAW, DISCLAIMS ALL WARRANTIES, WHETHER EXPLICITLY OR IMPLICITLY, INCLUDING WARRANTIES
12 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT, WITH RESPECT TO THE SOFTWARE OR
13 * DOCUMENTATION. RENESAS SHALL HAVE NO LIABILITY ARISING OUT OF ANY SECURITY VULNERABILITY OR BREACH. TO THE MAXIMUM
14 * EXTENT PERMITTED BY LAW, IN NO EVENT WILL RENESAS BE LIABLE TO YOU IN CONNECTION WITH THE SOFTWARE OR DOCUMENTATION
15 * (OR ANY PERSON OR ENTITY CLAIMING RIGHTS DERIVED FROM YOU) FOR ANY LOSS, DAMAGES, OR CLAIMS WHATSOEVER, INCLUDING,
16 * WITHOUT LIMITATION, ANY DIRECT, CONSEQUENTIAL, SPECIAL, INDIRECT, PUNITIVE, OR INCIDENTAL DAMAGES; ANY LOST PROFITS,
17 * OTHER ECONOMIC DAMAGE, PROPERTY DAMAGE, OR PERSONAL INJURY; AND EVEN IF RENESAS HAS BEEN ADVISED OF THE POSSIBILITY
18 * 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 /* Version of this module's code and API. */
56
57 #if 1 == BSP_CFG_RTOS /* ThreadX */
58 #include "tx_user.h"
59 #if defined(TX_ENABLE_EVENT_TRACE) || defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY)
60 #define FSP_CONTEXT_SAVE tx_isr_start((uint32_t) R_FSP_CurrentIrqGet());
61 #define FSP_CONTEXT_RESTORE tx_isr_end((uint32_t) R_FSP_CurrentIrqGet());
62 #else
63 #define FSP_CONTEXT_SAVE
64 #define FSP_CONTEXT_RESTORE
65 #endif
66 #else
67 #define FSP_CONTEXT_SAVE
68 #define FSP_CONTEXT_RESTORE
69 #endif
70
71 /** Macro that can be defined in order to enable logging in FSP modules. */
72 #ifndef FSP_LOG_PRINT
73 #define FSP_LOG_PRINT(X)
74 #endif
75
76 /** Macro to log and return error without an assertion. */
77 #ifndef FSP_RETURN
78
79 #define FSP_RETURN(err) FSP_ERROR_LOG((err)); \
80 return err;
81 #endif
82
83 /** This function is called before returning an error code. To stop on a runtime error, define fsp_error_log in
84 * user code and do required debugging (breakpoints, stack dump, etc) in this function.*/
85 #if (1 == BSP_CFG_ERROR_LOG)
86
87 #ifndef FSP_ERROR_LOG
88 #define FSP_ERROR_LOG(err) \
89 fsp_error_log((err), __FILE__, __LINE__);
90 #endif
91 #else
92
93 #define FSP_ERROR_LOG(err)
94 #endif
95
96 /** Default assertion calls ::FSP_ERROR_RETURN if condition "a" is false. Used to identify incorrect use of API's in FSP
97 * functions. */
98 #if (3 == BSP_CFG_ASSERT)
99 #define FSP_ASSERT(a)
100 #elif (2 == BSP_CFG_ASSERT)
101 #define FSP_ASSERT(a) {assert(a);}
102 #else
103 #define FSP_ASSERT(a) FSP_ERROR_RETURN((a), FSP_ERR_ASSERTION)
104 #endif // ifndef FSP_ASSERT
105
106 /** All FSP error codes are returned using this macro. Calls ::FSP_ERROR_LOG function if condition "a" is false. Used
107 * to identify runtime errors in FSP functions. */
108
109 #define FSP_ERROR_RETURN(a, err) \
110 { \
111 if ((a)) \
112 { \
113 (void) 0; /* Do nothing */ \
114 } \
115 else \
116 { \
117 FSP_ERROR_LOG(err); \
118 return err; \
119 } \
120 }
121
122 /* Function-like macro used to wait for a condition to be met, most often used to wait for hardware register updates.
123 * This macro can be redefined to add a timeout if necessary. */
124 #ifndef FSP_HARDWARE_REGISTER_WAIT
125 #define FSP_HARDWARE_REGISTER_WAIT(reg, required_value) while (reg != required_value) { /* Wait. */}
126 #endif
127
128 /****************************************************************
129 *
130 * This check is performed to select suitable ASM API with respect to core
131 *
132 * The macros __CORE__ , __ARM7EM__ and __ARM_ARCH_8M_BASE__ are undefined for GCC, but defined(__IAR_SYSTEMS_ICC__) is false for GCC, so
133 * the left half of the || expression evaluates to false for GCC regardless of the values of these macros. */
134
135 #if (defined(__IAR_SYSTEMS_ICC__) && ((__CORE__ == __ARM7EM__) || (__CORE__ == __ARM_ARCH_8M_BASE__))) || \
136 defined(__ARM_ARCH_7EM__) // CM4
137 #ifndef BSP_CFG_IRQ_MASK_LEVEL_FOR_CRITICAL_SECTION
138 #define BSP_CFG_IRQ_MASK_LEVEL_FOR_CRITICAL_SECTION (0U)
139 #endif
140 #else // CM23
141 #ifdef BSP_CFG_IRQ_MASK_LEVEL_FOR_CRITICAL_SECTION
142 #undef BSP_CFG_IRQ_MASK_LEVEL_FOR_CRITICAL_SECTION
143 #endif
144 #define BSP_CFG_IRQ_MASK_LEVEL_FOR_CRITICAL_SECTION (0U)
145 #endif
146
147 /* This macro defines a variable for saving previous mask value */
148 #ifndef FSP_CRITICAL_SECTION_DEFINE
149
150 #define FSP_CRITICAL_SECTION_DEFINE uint32_t old_mask_level = 0U
151 #endif
152
153 /* These macros abstract methods to save and restore the interrupt state for different architectures. */
154 #if (0 == BSP_CFG_IRQ_MASK_LEVEL_FOR_CRITICAL_SECTION)
155 #define FSP_CRITICAL_SECTION_GET_CURRENT_STATE __get_PRIMASK
156 #define FSP_CRITICAL_SECTION_SET_STATE __set_PRIMASK
157 #define FSP_CRITICAL_SECTION_IRQ_MASK_SET (1U)
158 #else
159 #define FSP_CRITICAL_SECTION_GET_CURRENT_STATE __get_BASEPRI
160 #define FSP_CRITICAL_SECTION_SET_STATE __set_BASEPRI
161 #define FSP_CRITICAL_SECTION_IRQ_MASK_SET ((uint8_t) (BSP_CFG_IRQ_MASK_LEVEL_FOR_CRITICAL_SECTION << \
162 (8U - __NVIC_PRIO_BITS)))
163 #endif
164
165 /** This macro temporarily saves the current interrupt state and disables interrupts. */
166 #ifndef FSP_CRITICAL_SECTION_ENTER
167 #define FSP_CRITICAL_SECTION_ENTER \
168 old_mask_level = FSP_CRITICAL_SECTION_GET_CURRENT_STATE(); \
169 FSP_CRITICAL_SECTION_SET_STATE(FSP_CRITICAL_SECTION_IRQ_MASK_SET)
170 #endif
171
172 /** This macro restores the previously saved interrupt state, reenabling interrupts. */
173 #ifndef FSP_CRITICAL_SECTION_EXIT
174 #define FSP_CRITICAL_SECTION_EXIT FSP_CRITICAL_SECTION_SET_STATE(old_mask_level)
175 #endif
176
177 /* Number of Cortex processor exceptions, used as an offset from XPSR value for the IRQn_Type macro. */
178 #define FSP_PRIV_CORTEX_PROCESSOR_EXCEPTIONS (16U)
179
180 /** Used to signify that the requested IRQ vector is not defined in this system. */
181 #define FSP_INVALID_VECTOR ((IRQn_Type) - 33)
182
183 /* Private definition used in R_FSP_SystemClockHzGet. Each bitfield in SCKDIVCR is 3 bits wide. */
184 #define FSP_PRIV_SCKDIVCR_DIV_MASK (7)
185
186 /* Use the secure registers for secure projects and flat projects. */
187 #if !BSP_TZ_NONSECURE_BUILD && BSP_FEATURE_TZ_HAS_TRUSTZONE
188 #define FSP_PRIV_TZ_USE_SECURE_REGS (1)
189 #else
190 #define FSP_PRIV_TZ_USE_SECURE_REGS (0)
191 #endif
192
193 /* Put certain BSP variables in uninitialized RAM when initializing BSP early. */
194 #if BSP_CFG_EARLY_INIT
195 #define BSP_SECTION_EARLY_INIT BSP_PLACE_IN_SECTION(BSP_SECTION_NOINIT)
196 #else
197 #define BSP_SECTION_EARLY_INIT
198 #endif
199
200 /***********************************************************************************************************************
201 * Typedef definitions
202 **********************************************************************************************************************/
203
204 /** Different warm start entry locations in the BSP. */
205 typedef enum e_bsp_warm_start_event
206 {
207 BSP_WARM_START_RESET = 0, ///< Called almost immediately after reset. No C runtime environment, clocks, or IRQs.
208 BSP_WARM_START_POST_CLOCK, ///< Called after clock initialization. No C runtime environment or IRQs.
209 BSP_WARM_START_POST_C ///< Called after clocks and C runtime environment have been set up
210 } bsp_warm_start_event_t;
211
212 /* Private enum used in R_FSP_SystemClockHzGet. Maps clock name to base bit in SCKDIVCR. */
213 typedef enum e_fsp_priv_clock
214 {
215 FSP_PRIV_CLOCK_PCLKD = 0,
216 FSP_PRIV_CLOCK_PCLKC = 4,
217 FSP_PRIV_CLOCK_PCLKB = 8,
218 FSP_PRIV_CLOCK_PCLKA = 12,
219 FSP_PRIV_CLOCK_BCLK = 16,
220 FSP_PRIV_CLOCK_ICLK = 24,
221 FSP_PRIV_CLOCK_FCLK = 28,
222 } fsp_priv_clock_t;
223
224 /* Private enum used in R_FSP_SciSpiClockHzGe. Maps clock name to base bit in SCISPICKCR. */
225 typedef enum e_fsp_priv_source_clock
226 {
227 FSP_PRIV_CLOCK_HOCO = 0, ///< The high speed on chip oscillator
228 FSP_PRIV_CLOCK_MOCO = 1, ///< The middle speed on chip oscillator
229 FSP_PRIV_CLOCK_LOCO = 2, ///< The low speed on chip oscillator
230 FSP_PRIV_CLOCK_MAIN_OSC = 3, ///< The main oscillator
231 FSP_PRIV_CLOCK_SUBCLOCK = 4, ///< The subclock oscillator
232 FSP_PRIV_CLOCK_PLL = 5, ///< The PLL oscillator
233 FSP_PRIV_CLOCK_PLL2 = 6, ///< The PLL2 oscillator
234 } fsp_priv_source_clock_t;
235
236 typedef struct st_bsp_unique_id
237 {
238 union
239 {
240 uint32_t unique_id_words[4];
241 uint8_t unique_id_bytes[16];
242 };
243 } bsp_unique_id_t;
244
245 /***********************************************************************************************************************
246 * Exported global variables
247 **********************************************************************************************************************/
248 uint32_t R_BSP_SourceClockHzGet(fsp_priv_source_clock_t clock);
249
250 /***********************************************************************************************************************
251 * Global variables (defined in other files)
252 **********************************************************************************************************************/
253
254 /***********************************************************************************************************************
255 * Inline Functions
256 **********************************************************************************************************************/
257
258 /*******************************************************************************************************************//**
259 * Return active interrupt vector number value
260 *
261 * @return Active interrupt vector number value
262 **********************************************************************************************************************/
R_FSP_CurrentIrqGet(void)263 __STATIC_INLINE IRQn_Type R_FSP_CurrentIrqGet (void)
264 {
265 xPSR_Type xpsr_value;
266 xpsr_value.w = __get_xPSR();
267
268 return (IRQn_Type) (xpsr_value.b.ISR - FSP_PRIV_CORTEX_PROCESSOR_EXCEPTIONS);
269 }
270
271 /*******************************************************************************************************************//**
272 * Gets the frequency of a system clock.
273 *
274 * @return Frequency of requested clock in Hertz.
275 **********************************************************************************************************************/
R_FSP_SystemClockHzGet(fsp_priv_clock_t clock)276 __STATIC_INLINE uint32_t R_FSP_SystemClockHzGet (fsp_priv_clock_t clock)
277 {
278 uint32_t sckdivcr = R_SYSTEM->SCKDIVCR;
279 uint32_t iclk_div = (sckdivcr >> FSP_PRIV_CLOCK_ICLK) & FSP_PRIV_SCKDIVCR_DIV_MASK;
280 uint32_t clock_div = (sckdivcr >> clock) & FSP_PRIV_SCKDIVCR_DIV_MASK;
281
282 return (SystemCoreClock << iclk_div) >> clock_div;
283 }
284
285 #if BSP_FEATURE_BSP_HAS_SCISPI_CLOCK
286
287 /*******************************************************************************************************************//**
288 * Gets the frequency of a SCI/SPI clock.
289 *
290 * @return Frequency of requested clock in Hertz.
291 **********************************************************************************************************************/
R_FSP_SciSpiClockHzGet(void)292 __STATIC_INLINE uint32_t R_FSP_SciSpiClockHzGet (void)
293 {
294 uint32_t scispidivcr = R_SYSTEM->SCISPICKDIVCR;
295 uint32_t clock_div = (scispidivcr & FSP_PRIV_SCKDIVCR_DIV_MASK);
296 fsp_priv_source_clock_t scispicksel = (fsp_priv_source_clock_t) R_SYSTEM->SCISPICKCR_b.SCISPICKSEL;
297
298 return R_BSP_SourceClockHzGet(scispicksel) >> clock_div;
299 }
300
301 #endif
302
303 /*******************************************************************************************************************//**
304 * Get unique ID for this device.
305 *
306 * @return A pointer to the unique identifier structure
307 **********************************************************************************************************************/
R_BSP_UniqueIdGet(void)308 __STATIC_INLINE bsp_unique_id_t const * R_BSP_UniqueIdGet (void)
309 {
310 return (bsp_unique_id_t *) BSP_FEATURE_BSP_UNIQUE_ID_POINTER;
311 }
312
313 /*******************************************************************************************************************//**
314 * Disables the flash cache.
315 **********************************************************************************************************************/
R_BSP_FlashCacheDisable(void)316 __STATIC_INLINE void R_BSP_FlashCacheDisable (void)
317 {
318 #if BSP_FEATURE_BSP_FLASH_CACHE
319 R_FCACHE->FCACHEE = 0U;
320 #endif
321
322 #if BSP_FEATURE_BSP_HAS_CODE_SYSTEM_CACHE
323
324 /* Disable the C-Cache. */
325 R_CACHE->CCACTL = 0U;
326 #endif
327 }
328
329 /*******************************************************************************************************************//**
330 * Enables the flash cache.
331 **********************************************************************************************************************/
R_BSP_FlashCacheEnable(void)332 __STATIC_INLINE void R_BSP_FlashCacheEnable (void)
333 {
334 #if BSP_FEATURE_BSP_FLASH_CACHE
335
336 /* Invalidate the flash cache and wait until it is invalidated. (See section 55.3.2.2 "Operation" of the Flash Cache
337 * in the RA6M3 manual R01UH0878EJ0100). */
338 R_FCACHE->FCACHEIV = 1U;
339 FSP_HARDWARE_REGISTER_WAIT(R_FCACHE->FCACHEIV, 0U);
340
341 /* Enable flash cache. */
342 R_FCACHE->FCACHEE = 1U;
343 #endif
344
345 #if BSP_FEATURE_BSP_HAS_CODE_SYSTEM_CACHE
346
347 /* Configure the C-Cache line size. */
348 R_CACHE->CCALCF = BSP_CFG_C_CACHE_LINE_SIZE;
349
350 /* Enable the C-Cache. */
351 R_CACHE->CCACTL = 1U;
352 #endif
353 }
354
355 /***********************************************************************************************************************
356 * Exported global functions (to be accessed by other files)
357 **********************************************************************************************************************/
358 #if ((1 == BSP_CFG_ERROR_LOG) || (1 == BSP_CFG_ASSERT))
359
360 /** Prototype of default function called before errors are returned in FSP code if BSP_CFG_LOG_ERRORS is set to 1. */
361 void fsp_error_log(fsp_err_t err, const char * file, int32_t line);
362
363 #endif
364
365 /** In the event of an unrecoverable error the BSP will by default call the __BKPT() intrinsic function which will
366 * alert the user of the error. The user can override this default behavior by defining their own
367 * BSP_CFG_HANDLE_UNRECOVERABLE_ERROR macro.
368 */
369 #if !defined(BSP_CFG_HANDLE_UNRECOVERABLE_ERROR)
370
371 #define BSP_CFG_HANDLE_UNRECOVERABLE_ERROR(x) __BKPT((x))
372 #endif
373
374 /** @} (end addtogroup BSP_MCU) */
375
376 /** Common macro for FSP header files. There is also a corresponding FSP_HEADER macro at the top of this file. */
377 FSP_FOOTER
378
379 #endif
380