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 /***********************************************************************************************************************
21 * File Name : bsp_module_stop.c
22 * Description : Provides a function to set or clear module stop bits.
23 **********************************************************************************************************************/
24
25 /*******************************************************************************************************************//**
26 * @ingroup BSP_MCU_S1JA
27 * @defgroup BSP_MCU_MODULE_STOP_S1JA Module Start and Stop
28 *
29 * Module start and stop functions are provided to enable or disable peripherals.
30 *
31 * @{
32 **********************************************************************************************************************/
33
34 /***********************************************************************************************************************
35 * Includes <System Includes> , "Project Includes"
36 **********************************************************************************************************************/
37 #include "bsp_api.h"
38
39 #if defined(BSP_MCU_GROUP_S1JA)
40
41 /***********************************************************************************************************************
42 * Macro definitions
43 **********************************************************************************************************************/
44 #define BSP_MSTP_DATA_INVALID (0xFFU)
45
46 #define BSP_MSTP_EXCEPTION (1U << 5)
47
48 /*LDRA_INSPECTED 340 S Using function like macro because inline function cannot be used to initialize an array. */
49 #define BSP_MSTP_REG(x) ((x) << 6)
50 /*LDRA_INSPECTED 340 S Using function like macro because inline function cannot be used to initialize an array. */
51 #define BSP_MSTP_BIT(x) (x)
52
53 #define BSP_MSTPCRA (0U)
54 #define BSP_MSTPCRB (1U)
55 #define BSP_MSTPCRC (2U)
56 #define BSP_MSTPCRD (3U)
57
58 /** Largest channel number associated with lower MSTP bit for GPT on this MCU. */
59 #define HW_GPT_MSTPD5_MAX_CH (0U)
60
61 /** Used to generate a compiler error (divided by 0 error) if the assertion fails. This is used in place of "#error"
62 * for expressions that cannot be evaluated by the preprocessor like sizeof(). */
63 /*LDRA_INSPECTED 340 S Using function like macro because inline function does not generate divided by 0 error. */
64 #define BSP_COMPILE_TIME_ASSERT(e) ((void) sizeof(char[1 - 2 * !(e)]))
65
66 /***********************************************************************************************************************
67 * Typedef definitions
68 **********************************************************************************************************************/
69 /** Definition of BSP module stop bit. */
70 typedef struct u_bsp_mstp_bit_t
71 {
72 uint8_t bit : 5; ///< Which bit in MSTP register
73 uint8_t exception : 1; ///< Special processing required
74 uint8_t reg : 2; ///< Which MSTP register
75 } bsp_mstp_bit_t;
76
77
78 /** Definition of BSP module stop bit. */
79 typedef union u_bsp_mstp_data
80 {
81 uint8_t byte; ///< Byte access for comparison
82 bsp_mstp_bit_t bit;
83 } bsp_mstp_data_t;
84
85 /***********************************************************************************************************************
86 * Exported global variables (to be accessed by other files)
87 **********************************************************************************************************************/
88
89 /***********************************************************************************************************************
90 * Private global variables and functions
91 **********************************************************************************************************************/
92 /** Module stop bit definitions for each ssp_ip_t enum value. */
93 static const uint8_t g_bsp_module_stop[] =
94 {
95 BSP_MSTP_DATA_INVALID, // SSP_IP_CFLASH=0,
96 BSP_MSTP_DATA_INVALID, // SSP_IP_DFLASH=1,
97 BSP_MSTP_DATA_INVALID, // SSP_IP_RAM=2,
98 BSP_MSTP_DATA_INVALID, // SSP_IP_SYSTEM=3,
99 BSP_MSTP_DATA_INVALID, // SSP_IP_FCU=4,
100 BSP_MSTP_DATA_INVALID, // SSP_IP_DEBUG=5,
101 BSP_MSTP_DATA_INVALID, // SSP_IP_ICU=6,
102 BSP_MSTP_DATA_INVALID, // SSP_IP_DMAC=7,
103 BSP_MSTP_REG(BSP_MSTPCRA) | BSP_MSTP_BIT(22U), // SSP_IP_DTC=8,
104 BSP_MSTP_DATA_INVALID, // SSP_IP_IOPORT=9,
105 BSP_MSTP_DATA_INVALID, // SSP_IP_PFC=10,
106 BSP_MSTP_REG(BSP_MSTPCRC) | BSP_MSTP_BIT(14U), // SSP_IP_ELC=11,
107 BSP_MSTP_DATA_INVALID, // SSP_IP_BSC=12,
108 BSP_MSTP_DATA_INVALID, // SSP_IP_MPU=13,
109 BSP_MSTP_DATA_INVALID, // SSP_IP_MSTP=14,
110 BSP_MSTP_DATA_INVALID, // SSP_IP_MMF=15,
111 BSP_MSTP_DATA_INVALID, // SSP_IP_KEY=16,
112 BSP_MSTP_REG(BSP_MSTPCRC) | BSP_MSTP_BIT(0U), // SSP_IP_CAC=17,
113 BSP_MSTP_REG(BSP_MSTPCRC) | BSP_MSTP_BIT(13U), // SSP_IP_DOC=18,
114 BSP_MSTP_REG(BSP_MSTPCRC) | BSP_MSTP_BIT(1U), // SSP_IP_CRC=19,
115 BSP_MSTP_REG(BSP_MSTPCRB) | BSP_MSTP_BIT(31U), // SSP_IP_SCI=20,
116 BSP_MSTP_REG(BSP_MSTPCRB) | BSP_MSTP_BIT(9U), // SSP_IP_IIC=21,
117 BSP_MSTP_REG(BSP_MSTPCRB) | BSP_MSTP_BIT(19U), // SSP_IP_RSPI=22,
118 BSP_MSTP_REG(BSP_MSTPCRC) | BSP_MSTP_BIT(3U), // SSP_IP_CTSU=23,
119 BSP_MSTP_DATA_INVALID, // SSP_IP_SCE=24,
120 BSP_MSTP_DATA_INVALID, // SSP_IP_SLCDC=25,
121 BSP_MSTP_REG(BSP_MSTPCRC) | BSP_MSTP_BIT(31U), // SSP_IP_AES=26,
122 BSP_MSTP_REG(BSP_MSTPCRC) | BSP_MSTP_BIT(28U), // SSP_IP_TRNG=27,
123 BSP_MSTP_DATA_INVALID, // 28,
124 BSP_MSTP_DATA_INVALID, // 29,
125 BSP_MSTP_DATA_INVALID, // SSP_IP_ROMC=30,
126 BSP_MSTP_DATA_INVALID, // SSP_IP_SRAM=31,
127 BSP_MSTP_REG(BSP_MSTPCRD) | BSP_MSTP_BIT(16U) | BSP_MSTP_EXCEPTION, // SSP_IP_ADC=32,
128 BSP_MSTP_REG(BSP_MSTPCRD) | BSP_MSTP_BIT(20U) | BSP_MSTP_EXCEPTION, // SSP_IP_DAC=33,
129 BSP_MSTP_DATA_INVALID, // SSP_IP_TSN=34,
130 BSP_MSTP_DATA_INVALID, // SSP_IP_DAAD=35,
131 BSP_MSTP_REG(BSP_MSTPCRD) | BSP_MSTP_BIT(28U), // SSP_IP_COMP_HS=36,
132 BSP_MSTP_REG(BSP_MSTPCRD) | BSP_MSTP_BIT(29U) | BSP_MSTP_EXCEPTION, // SSP_IP_COMP_LP=37,
133 BSP_MSTP_REG(BSP_MSTPCRD) | BSP_MSTP_BIT(31U), // SSP_IP_OPAMP=38,
134 BSP_MSTP_REG(BSP_MSTPCRD) | BSP_MSTP_BIT(17U), // SSP_IP_SDADC=39,
135 BSP_MSTP_DATA_INVALID, // SSP_IP_RTC=40,
136 BSP_MSTP_DATA_INVALID, // SSP_IP_WDT=41,
137 BSP_MSTP_DATA_INVALID, // SSP_IP_IWDT=42,
138 BSP_MSTP_REG(BSP_MSTPCRD) | BSP_MSTP_BIT(5U) | BSP_MSTP_EXCEPTION, // SSP_IP_GPT=43,
139 BSP_MSTP_REG(BSP_MSTPCRD) | BSP_MSTP_BIT(14U) | BSP_MSTP_EXCEPTION, // SSP_IP_POEG=44,
140 BSP_MSTP_DATA_INVALID, // SSP_IP_OPS=45,
141 BSP_MSTP_DATA_INVALID, // SSP_IP_PSD=46,
142 BSP_MSTP_REG(BSP_MSTPCRD) | BSP_MSTP_BIT(3U), // SSP_IP_AGT=47,
143 BSP_MSTP_REG(BSP_MSTPCRB) | BSP_MSTP_BIT(2U), // SSP_IP_CAN=48,
144 BSP_MSTP_DATA_INVALID, // SSP_IP_IRDA=49,
145 BSP_MSTP_DATA_INVALID, // SSP_IP_QSPI=50,
146 BSP_MSTP_REG(BSP_MSTPCRB) | BSP_MSTP_BIT(11U) | BSP_MSTP_EXCEPTION, // SSP_IP_USB=51,
147 BSP_MSTP_DATA_INVALID, // SSP_IP_SDHIMMC=52,
148 BSP_MSTP_DATA_INVALID, // SSP_IP_SRC=53,
149 BSP_MSTP_DATA_INVALID, // SSP_IP_SSI=54,
150 BSP_MSTP_DATA_INVALID, // 55,
151 BSP_MSTP_DATA_INVALID, // 56,
152 BSP_MSTP_DATA_INVALID, // 57,
153 BSP_MSTP_DATA_INVALID, // 58,
154 BSP_MSTP_DATA_INVALID, // 59,
155 BSP_MSTP_DATA_INVALID, // 60,
156 BSP_MSTP_DATA_INVALID, // 61,
157 BSP_MSTP_DATA_INVALID, // 62,
158 BSP_MSTP_DATA_INVALID, // 63,
159 BSP_MSTP_DATA_INVALID, // SSP_IP_ETHER=64, SSP_IP_EDMAC=64,
160 BSP_MSTP_DATA_INVALID, // SSP_IP_EPTPC=65,
161 BSP_MSTP_DATA_INVALID, // SSP_IP_PDC=66,
162 BSP_MSTP_DATA_INVALID, // SSP_IP_GLCDC=67,
163 BSP_MSTP_DATA_INVALID, // SSP_IP_DRW=68,
164 BSP_MSTP_DATA_INVALID, // SSP_IP_JPEG=69,
165 };
166
167 /** Module stop register addresses. */
168 static volatile uint32_t * const gp_mstp[] =
169 {
170 &(R_SYSTEM->MSTPCRA),
171 &(R_MSTP->MSTPCRB),
172 &(R_MSTP->MSTPCRC),
173 &(R_MSTP->MSTPCRD),
174 };
175
176 static ssp_err_t r_bsp_module_start_stop (ssp_feature_t const * const p_feature, bool stop, bool force);
177 static uint32_t r_bsp_get_mstp_mask (ssp_feature_t const * const p_feature);
178
179 /*******************************************************************************************************************//**
180 * @brief Stop module (enter module stop). Stopping a module disables clocks to the peripheral to save power.
181 *
182 * @note Some module stop bits are shared between peripherals. Modules with shared module stop bits cannot be stopped
183 * to prevent unintentionally stopping related modules.
184 *
185 * @param[in] p_feature Pointer to definition of the feature, defined by ssp_feature_t.
186 *
187 * @retval SSP_SUCCESS Module is stopped
188 * @retval SSP_ERR_ASSERTION p_feature::id is invalid
189 * @retval SSP_ERR_INVALID_ARGUMENT Module has no module stop bit, or module stop bit is shared and entering module
190 * stop is not supported because it could affect other modules.
191 **********************************************************************************************************************/
R_BSP_ModuleStop(ssp_feature_t const * const p_feature)192 ssp_err_t R_BSP_ModuleStop(ssp_feature_t const * const p_feature)
193 {
194 return r_bsp_module_start_stop(p_feature, true, false);
195 }
196
197 /******************************************************************************************************************//**
198 * @brief Stop module (enter module stop) even if the module is used for multiple channels.
199 *
200 * @param[in] p_feature Pointer to definition of the feature, defined by ssp_feature_t.
201 *
202 * @retval SSP_SUCCESS Module is stopped
203 * @retval SSP_ERR_ASSERTION p_feature::id is invalid
204 **********************************************************************************************************************/
R_BSP_ModuleStopAlways(ssp_feature_t const * const p_feature)205 ssp_err_t R_BSP_ModuleStopAlways(ssp_feature_t const * const p_feature)
206 {
207 return r_bsp_module_start_stop(p_feature, true, true);
208 }
209
210 /*******************************************************************************************************************//**
211 * @brief Start module (cancel module stop). Starting a module enables clocks to the peripheral and allows registers
212 * to be set.
213 *
214 * @param[in] p_feature Pointer to definition of the feature, defined by ssp_feature_t.
215 *
216 * @retval SSP_SUCCESS Module is started
217 * @retval SSP_ERR_ASSERTION p_feature::id is invalid
218 * @retval SSP_ERR_INVALID_ARGUMENT Module has no module stop bit.
219 **********************************************************************************************************************/
R_BSP_ModuleStart(ssp_feature_t const * const p_feature)220 ssp_err_t R_BSP_ModuleStart(ssp_feature_t const * const p_feature)
221 {
222 return r_bsp_module_start_stop(p_feature, false, false);
223 }
224
225 /***********************************************************************************************************************
226 * @brief Get the module state.
227 *
228 * @param[in] p_feature Pointer to definition of the feature, defined by ssp_feature_t.
229 * @param[out] p_stop Pointer to a boolean that will contain the module stopped state
230 *
231 * @retval SSP_SUCCESS Module is started
232 * @retval SSP_ERR_ASSERTION p_feature::id is invalid
233 * p_stop is invalid
234 * @retval SSP_ERR_INVALID_ARGUMENT Module has no module stop bit.
235 **********************************************************************************************************************/
R_BSP_ModuleStateGet(ssp_feature_t const * const p_feature,bool * const p_stop)236 ssp_err_t R_BSP_ModuleStateGet(ssp_feature_t const * const p_feature, bool * const p_stop)
237 {
238 bsp_mstp_data_t data = {0};
239
240 #if BSP_CFG_PARAM_CHECKING_ENABLE
241 SSP_ASSERT(p_feature->id < SSP_IP_MAX);
242 SSP_ASSERT(p_stop != NULL);
243 #endif
244
245 /** The g_bsp_module_stop array must have entries for each ssp_ip_t enum value. */
246 /* LDRA will complain about "Statement with no side effect" w/o SSP_PARAMETER_NOT_USED */
247 SSP_PARAMETER_NOT_USED(BSP_COMPILE_TIME_ASSERT(SSP_IP_MAX == sizeof(g_bsp_module_stop)));
248
249 data.byte = g_bsp_module_stop[p_feature->id];
250 if (BSP_MSTP_DATA_INVALID == data.byte)
251 {
252 /* Module has no module stop bit, clocks are enabled by default. */
253 return SSP_ERR_INVALID_ARGUMENT;
254 }
255
256 uint32_t mask = r_bsp_get_mstp_mask(p_feature);
257
258 volatile uint32_t * p_mstp_base = gp_mstp[data.bit.reg];
259
260 /** Save the current module state */
261 *p_stop = ((*p_mstp_base & mask) > 0);
262
263 return SSP_SUCCESS;
264 }
265
266 /*******************************************************************************************************************//**
267 * @brief Start module (cancel module stop) or stop module (enter module stop).
268 *
269 * @note Some module stop bits are shared between peripherals. Entering module stop is not permitted for these
270 * peripherals unless force is true.
271 *
272 * @param[in] p_feature Pointer to definition of the feature, defined by ssp_feature_t.
273 * @param[in] stop true to stop module, false to start module
274 * @param[in] force Set to true if the module should be stopped even if it is shared.
275 *
276 * @retval SSP_SUCCESS Module is stopped or started based on stop parameter
277 * @retval SSP_ERR_ASSERTION p_feature::id is invalid
278 * @retval SSP_ERR_INVALID_ARGUMENT Module has no module stop bit, or module stop bit is shared and entering module
279 * stop is not supported because it could affect other modules.
280 **********************************************************************************************************************/
r_bsp_module_start_stop(ssp_feature_t const * const p_feature,bool stop,bool force)281 static ssp_err_t r_bsp_module_start_stop(ssp_feature_t const * const p_feature, bool stop, bool force)
282 {
283 bsp_mstp_data_t data = {0};
284
285 #if BSP_CFG_PARAM_CHECKING_ENABLE
286 SSP_ASSERT(p_feature->id < SSP_IP_MAX);
287 #endif
288
289 /** The g_bsp_module_stop array must have entries for each ssp_ip_t enum value. */
290 /* LDRA will complain about "Statement with no side effect" w/o SSP_PARAMETER_NOT_USED */
291 SSP_PARAMETER_NOT_USED(BSP_COMPILE_TIME_ASSERT(SSP_IP_MAX == sizeof(g_bsp_module_stop)));
292
293 data.byte = g_bsp_module_stop[p_feature->id];
294 if (BSP_MSTP_DATA_INVALID == data.byte)
295 {
296 /* Module has no module stop bit, clocks are enabled by default. */
297 return SSP_ERR_INVALID_ARGUMENT;
298 }
299
300 uint32_t mask = r_bsp_get_mstp_mask(p_feature);
301
302 volatile uint32_t * p_mstp_base = gp_mstp[data.bit.reg];
303 if (stop)
304 {
305 if (!data.bit.exception || force)
306 {
307 SSP_CRITICAL_SECTION_DEFINE;
308 SSP_CRITICAL_SECTION_ENTER;
309
310 /** Set MSTP bit if stop parameter is true and the bit is not shared with other channels. */
311 *p_mstp_base |= mask;
312
313 SSP_CRITICAL_SECTION_EXIT;
314 }
315 else
316 {
317 /* Module stop bit is shared, so module is not stopped because this could affect other modules. */
318 return SSP_ERR_INVALID_ARGUMENT;
319 }
320 }
321 else
322 {
323 /** Clear MSTP bit if stop parameter is false. */
324 mask = (uint32_t) (~mask);
325
326 SSP_CRITICAL_SECTION_DEFINE;
327 SSP_CRITICAL_SECTION_ENTER;
328
329 *p_mstp_base &= mask;
330
331 SSP_CRITICAL_SECTION_EXIT;
332 }
333
334 return SSP_SUCCESS;
335 }
336
337 /*******************************************************************************************************************//**
338 * @brief Get the correct MSTP mask for a peripheral
339 *
340 * @param[in] p_feature Pointer to definition of the feature, defined by ssp_feature_t.
341 *
342 * @retval Mask for MSTP bit for peripheral
343 **********************************************************************************************************************/
r_bsp_get_mstp_mask(ssp_feature_t const * const p_feature)344 static uint32_t r_bsp_get_mstp_mask(ssp_feature_t const * const p_feature)
345 {
346 bsp_mstp_data_t data = {0};
347 data.byte = g_bsp_module_stop[p_feature->id];
348
349 uint32_t mask = (1U << (data.bit.bit - (p_feature->channel + p_feature->unit)));
350 if (data.bit.exception)
351 {
352 mask = (1U << (data.bit.bit));
353 switch (p_feature->id)
354 {
355 case SSP_IP_GPT:
356 if (p_feature->channel > HW_GPT_MSTPD5_MAX_CH)
357 {
358 mask = (1U << (data.bit.bit + 1U));
359 }
360 break;
361
362 case SSP_IP_DAC:
363 if (p_feature->unit > 0U)
364 {
365 mask = (1U << (data.bit.bit - 1U));
366 }
367 break;
368 default:
369 break;
370 }
371 }
372 return mask;
373 }
374 #endif /* if defined(BSP_MCU_GROUP_S1JA) */
375
376
377 /** @} (end defgroup BSP_MCU_MODULE_STOP_S1JA) */
378