1 /*
2 * Copyright (c) 2020 - 2024 Renesas Electronics Corporation and/or its affiliates
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7 /***********************************************************************************************************************
8 * Includes <System Includes> , "Project Includes"
9 **********************************************************************************************************************/
10 #include "bsp_api.h"
11
12 /***********************************************************************************************************************
13 * Macro definitions
14 **********************************************************************************************************************/
15
16 /***********************************************************************************************************************
17 * Typedef definitions
18 **********************************************************************************************************************/
19
20 /***********************************************************************************************************************
21 * Exported global variables (to be accessed by other files)
22 **********************************************************************************************************************/
23
24 #if (1 == BSP_FEATURE_BSP_IRQ_GPT_SEL_SUPPORTED)
25
26 /* Pointer to control structure table. */
27 void ** gp_bsp_gpt_combined_ctrl_table[BSP_IRQ_GPT_COMBINED_GROUP_NUM] =
28 {
29 NULL, /* Pointer to Group 0 control structure table. (Use NS_GPT_INTSTAT0) */
30 NULL, /* Pointer to Group 1 control structure table. (Use NS_GPT_INTSTAT1) */
31 NULL, /* Pointer to Group 2 control structure table. (Use NS_GPT_INTSTAT2) */
32 NULL, /* Pointer to Group 3 control structure table. (Use NS_GPT_INTSTAT3) */
33 NULL, /* Pointer to Group 4 control structure table. (Use NS_GPT_INTSTAT4) */
34 NULL, /* Pointer to Group 5 control structure table. (Use NS_GPT_INTSTAT5) */
35 NULL, /* Pointer to Group 6 control structure table. (Use NS_GPT_INTSTAT6) */
36 NULL, /* Pointer to Group 7 control structure table. (Use NS_GPT_INTSTAT7) */
37 NULL, /* Pointer to Group 8 control structure table. (Use NS_GPT_INTSTAT8) */
38 NULL, /* Pointer to Group 9 control structure table. (Use NS_GPT_INTSTAT9) */
39 NULL, /* Pointer to Group 10 control structure table. (Use NS_GPT_INTSTAT10) */
40 NULL, /* Pointer to Group 11 control structure table. (Use NS_GPT_INTSTAT11) */
41 NULL, /* Pointer to Group 12 control structure table. (Use NS_GPT_INTSTAT12) */
42 NULL, /* Pointer to Group 13 control structure table. (Use NS_GPT_INTSTAT13) */
43 NULL, /* Pointer to Group 14 control structure table. (Use NS_GPT_INTSTAT14) */
44 NULL, /* Pointer to Group 15 control structure table. (Use NS_GPT_INTSTAT15) */
45 NULL, /* Pointer to Group 16 control structure table. (Use NS_GPT_INTSTAT16) */
46 NULL, /* Pointer to Group 17 control structure table. (Use NS_GPT_INTSTAT17) */
47 NULL, /* Pointer to Group 18 control structure table. (Use NS_GPT_INTSTAT18) */
48 NULL, /* Pointer to Group 19 control structure table. (Use NS_GPT_INTSTAT19) */
49 NULL, /* Pointer to Group 20 control structure table. (Use NS_GPT_INTSTAT20) */
50 NULL, /* Pointer to Group 21 control structure table. (Use NS_GPT_INTSTAT21) */
51 NULL, /* Pointer to Group 22 control structure table. (Use NS_GPT_INTSTAT22) */
52 NULL, /* Pointer to Group 23 control structure table. (Use NS_GPT_INTSTAT23) */
53 NULL, /* Pointer to Group 24 control structure table. (Use NS_GPT_INTSTAT24) */
54 NULL, /* Pointer to Group 25 control structure table. (Use NS_GPT_INTSTAT25) */
55 NULL, /* Pointer to Group 26 control structure table. (Use S_GPT_INTSTAT0) */
56 NULL, /* Pointer to Group 27 control structure table. (Use S_GPT_INTSTAT1) */
57 };
58
59 /* Pointer to interrupt handler table. */
60 fsp_vector_t * gp_bsp_gpt_combined_isr_table[BSP_IRQ_GPT_COMBINED_GROUP_NUM] =
61 {
62 NULL, /* Pointer to Group 0 interrupt handler table. (Use NS_GPT_INTSTAT0) */
63 NULL, /* Pointer to Group 1 interrupt handler table. (Use NS_GPT_INTSTAT1) */
64 NULL, /* Pointer to Group 2 interrupt handler table. (Use NS_GPT_INTSTAT2) */
65 NULL, /* Pointer to Group 3 interrupt handler table. (Use NS_GPT_INTSTAT3) */
66 NULL, /* Pointer to Group 4 interrupt handler table. (Use NS_GPT_INTSTAT4) */
67 NULL, /* Pointer to Group 5 interrupt handler table. (Use NS_GPT_INTSTAT5) */
68 NULL, /* Pointer to Group 6 interrupt handler table. (Use NS_GPT_INTSTAT6) */
69 NULL, /* Pointer to Group 7 interrupt handler table. (Use NS_GPT_INTSTAT7) */
70 NULL, /* Pointer to Group 8 interrupt handler table. (Use NS_GPT_INTSTAT8) */
71 NULL, /* Pointer to Group 9 interrupt handler table. (Use NS_GPT_INTSTAT9) */
72 NULL, /* Pointer to Group 10 interrupt handler table. (Use NS_GPT_INTSTAT10) */
73 NULL, /* Pointer to Group 11 interrupt handler table. (Use NS_GPT_INTSTAT11) */
74 NULL, /* Pointer to Group 12 interrupt handler table. (Use NS_GPT_INTSTAT12) */
75 NULL, /* Pointer to Group 13 interrupt handler table. (Use NS_GPT_INTSTAT13) */
76 NULL, /* Pointer to Group 14 interrupt handler table. (Use NS_GPT_INTSTAT14) */
77 NULL, /* Pointer to Group 15 interrupt handler table. (Use NS_GPT_INTSTAT15) */
78 NULL, /* Pointer to Group 16 interrupt handler table. (Use NS_GPT_INTSTAT16) */
79 NULL, /* Pointer to Group 17 interrupt handler table. (Use NS_GPT_INTSTAT17) */
80 NULL, /* Pointer to Group 18 interrupt handler table. (Use NS_GPT_INTSTAT18) */
81 NULL, /* Pointer to Group 19 interrupt handler table. (Use NS_GPT_INTSTAT19) */
82 NULL, /* Pointer to Group 20 interrupt handler table. (Use NS_GPT_INTSTAT20) */
83 NULL, /* Pointer to Group 21 interrupt handler table. (Use NS_GPT_INTSTAT21) */
84 NULL, /* Pointer to Group 22 interrupt handler table. (Use NS_GPT_INTSTAT22) */
85 NULL, /* Pointer to Group 23 interrupt handler table. (Use NS_GPT_INTSTAT23) */
86 NULL, /* Pointer to Group 24 interrupt handler table. (Use NS_GPT_INTSTAT24) */
87 NULL, /* Pointer to Group 25 interrupt handler table. (Use NS_GPT_INTSTAT25) */
88 NULL, /* Pointer to Group 26 control structure table. (Use S_GPT_INTSTAT0) */
89 NULL, /* Pointer to Group 27 control structure table. (Use S_GPT_INTSTAT1) */
90 };
91
92 #endif
93
94 /***********************************************************************************************************************
95 * Private global variables and functions
96 **********************************************************************************************************************/
97
98 /*******************************************************************************************************************//**
99 * Initialize interrupt controller.
100 *
101 * @retval None
102 **********************************************************************************************************************/
bsp_irq_cfg(void)103 void bsp_irq_cfg (void)
104 {
105 bsp_irq_core_cfg();
106 }
107
108 #if (1 == BSP_FEATURE_BSP_IRQ_GPT_SEL_SUPPORTED)
109
110 /*******************************************************************************************************************//**
111 * Get GPT_INT channel number.
112 *
113 * @param[in] irq IRQ number
114 *
115 * @return GPT_INT channel number.
116 **********************************************************************************************************************/
bsp_prv_irq_gpt_channel_get(IRQn_Type irq)117 uint32_t bsp_prv_irq_gpt_channel_get (IRQn_Type irq)
118 {
119 return ((uint32_t) irq - BSP_IRQ_GPT_EVENT_NUM_BASE) / BSP_IRQ_GPT_INT_NUM_MAX;
120 }
121
122 /*******************************************************************************************************************//**
123 * Get GPT_INT register number.
124 *
125 * @param[in] channel GPT_INT channel number
126 *
127 * @return GPT_INT register number.
128 **********************************************************************************************************************/
bsp_prv_irq_gpt_reg_num_get(uint32_t channel)129 uint32_t bsp_prv_irq_gpt_reg_num_get (uint32_t channel)
130 {
131 return (channel % BSP_FEATURE_GPT_SAFETY_BASE_CHANNEL) / BSP_IRQ_GPT_REGISTER_DIVISION;
132 }
133
134 /*******************************************************************************************************************//**
135 * Get bit shift value of the GPT_INTSELn register.
136 *
137 * @param[in] irq IRQ number
138 * @param[in] channel GPT_INT channel number
139 *
140 * @return Bit shift value.
141 **********************************************************************************************************************/
bsp_prv_irq_gpt_selected_shift_num_get(IRQn_Type irq,uint32_t channel)142 uint32_t bsp_prv_irq_gpt_selected_shift_num_get (IRQn_Type irq, uint32_t channel)
143 {
144 uint32_t irqdiff = (uint32_t) irq - BSP_IRQ_GPT_EVENT_NUM_BASE;
145
146 return channel % BSP_IRQ_GPT_REGISTER_DIVISION ?
147 BSP_IRQ_GPT_SELECTED_INTERVAL * (irqdiff % BSP_IRQ_GPT_INT_NUM_MAX) + BSP_IRQ_GPT_IY_SHIFT_NUM :
148 BSP_IRQ_GPT_SELECTED_INTERVAL * (irqdiff % BSP_IRQ_GPT_INT_NUM_MAX) + BSP_IRQ_GPT_IX_SHIFT_NUM;
149 }
150
151 /*******************************************************************************************************************//**
152 * Get GPT_INT table number.
153 *
154 * @param[in] channel GPT_INT channel number
155 *
156 * @return GPT_INT table number.
157 **********************************************************************************************************************/
bsp_prv_irq_gpt_combined_table_num_get(uint32_t channel)158 uint32_t bsp_prv_irq_gpt_combined_table_num_get (uint32_t channel)
159 {
160 return (channel % BSP_FEATURE_GPT_CHANNEL) / BSP_IRQ_GPT_REGISTER_DIVISION;
161 }
162
163 /*******************************************************************************************************************//**
164 * Allocate memory for 'groupIndex'th control structure table.
165 *
166 * @param[in] groupIndex Register number
167 *
168 * @return Allocated memory address
169 **********************************************************************************************************************/
bsp_prv_irq_gpt_combined_ctrl_table_allocate(uint32_t groupIndex)170 void * bsp_prv_irq_gpt_combined_ctrl_table_allocate (uint32_t groupIndex)
171 {
172 /* Allocate memory for 'groupIndex'th control structure table. */
173 gp_bsp_gpt_combined_ctrl_table[groupIndex] =
174 bsp_prv_malloc(BSP_IRQ_GPT_COMBINED_EVENT_NUM_PER_GROUP * sizeof(uintptr_t));
175 if (NULL != gp_bsp_gpt_combined_ctrl_table[groupIndex])
176 {
177 /* Set initial value at malloc area. */
178 for (uint32_t elementIndex = 0U; elementIndex < BSP_IRQ_GPT_COMBINED_EVENT_NUM_PER_GROUP; elementIndex++)
179 {
180 gp_bsp_gpt_combined_ctrl_table[groupIndex][elementIndex] = NULL;
181 }
182 }
183
184 return gp_bsp_gpt_combined_ctrl_table[groupIndex];
185 }
186
187 /*******************************************************************************************************************//**
188 * Allocate memory for 'groupIndex'th interrupt handler table.
189 *
190 * @param[in] groupIndex Register number
191 *
192 * @return Allocated memory address
193 **********************************************************************************************************************/
bsp_prv_irq_gpt_combined_isr_table_allocate(uint32_t groupIndex)194 void * bsp_prv_irq_gpt_combined_isr_table_allocate (uint32_t groupIndex)
195 {
196 /* Allocate memory for 'groupIndex'th structure table. */
197 gp_bsp_gpt_combined_isr_table[groupIndex] =
198 bsp_prv_malloc(BSP_IRQ_GPT_COMBINED_EVENT_NUM_PER_GROUP * sizeof(uintptr_t));
199 if (NULL != gp_bsp_gpt_combined_isr_table[groupIndex])
200 {
201 /* Set initial value at malloc area. */
202 for (uint32_t elementIndex = 0U; elementIndex < BSP_IRQ_GPT_COMBINED_EVENT_NUM_PER_GROUP; elementIndex++)
203 {
204 gp_bsp_gpt_combined_isr_table[groupIndex][elementIndex] = NULL;
205 }
206 }
207
208 return gp_bsp_gpt_combined_isr_table[groupIndex];
209 }
210
211 /*******************************************************************************************************************//**
212 * Get bit shift value of GPT_INTMSKn, GPT_INTCLRn and GPT_INTSTATn registers.
213 *
214 * @param[in] channel GPT_INT channel number
215 * @param[in] event_source Define the bit shift values of GPT_INTMSKn, GPT_INTCLRn and GPT_INTSTATn as an enum.
216 *
217 * @return Bit shift value.
218 **********************************************************************************************************************/
bsp_prv_irq_gpt_combined_shift_num_get(uint32_t channel,bsp_irq_gpt_combined_event_t event_source)219 uint32_t bsp_prv_irq_gpt_combined_shift_num_get (uint32_t channel, bsp_irq_gpt_combined_event_t event_source)
220 {
221 return channel % BSP_IRQ_GPT_REGISTER_DIVISION ? (uint32_t) event_source + BSP_IRQ_GPT_IY_SHIFT_NUM :
222 (uint32_t) event_source + BSP_IRQ_GPT_IX_SHIFT_NUM;
223 }
224
225 /*******************************************************************************************************************//**
226 * Called when a GPT combined interrupt occurs, clears the GPT/MTU3 interrupt and executes the ISR function.
227 **********************************************************************************************************************/
bsp_irq_gpt_combined_interrupt_handler(void)228 void bsp_irq_gpt_combined_interrupt_handler (void)
229 {
230 /* Save context if RTOS is used */
231 FSP_CONTEXT_SAVE;
232
233 IRQn_Type irq = R_FSP_CurrentIrqGet();
234
235 uint32_t gpt_intstat = R_BSP_IrqGptCombinedStatusRead(irq);
236
237 /* Since the GPT/MTU interrupt status is divided into upper 16 bits and lower 16 bits,
238 * the bit positions are adjusted for the upper bits. */
239 if (bsp_prv_irq_gpt_channel_get(irq) % BSP_IRQ_GPT_REGISTER_DIVISION)
240 {
241 gpt_intstat >>= BSP_IRQ_GPT_IY_SHIFT_NUM;
242 }
243
244 bsp_irq_gpt_combined_event_t event_source;
245 uint32_t next_event = 0;
246 uint32_t event_shift = 0;
247 void * p_context;
248 void (* p_interrupt_handler)(void);
249
250 while (gpt_intstat)
251 {
252 /* Scan and search for GPT and MTU3 interrupts factors one by one. */
253 next_event = __CLZ(__RBIT(gpt_intstat));
254 gpt_intstat >>= next_event;
255 event_shift += next_event;
256 event_source = (bsp_irq_gpt_combined_event_t) (event_shift & BSP_IRQ_GPT_COMBINED_EVENT_ENUM_MASK);
257
258 /* Obtains the context and interrupt handler from the table and executes interrupt processing. */
259 R_BSP_IrqGptCombinedStatusClear(irq, event_source);
260 p_context = R_BSP_IrqGptCombinedCtrlGet(irq, event_source);
261 R_FSP_IsrContextSet(irq, p_context);
262 p_interrupt_handler = R_BSP_IrqGptCombinedIsrGet(irq, event_source);
263 p_interrupt_handler();
264
265 /* Clear the scanned flags one by one. */
266 gpt_intstat &= (uint32_t) ~(1UL);
267 }
268
269 /* Restore context if RTOS is used */
270 FSP_CONTEXT_RESTORE;
271 }
272
273 #endif
274