1 /***************************************************************************//**
2 * \file cy_sysint.c
3 * \version 1.60
4 *
5 * \brief
6 * Provides an API implementation of the SysInt driver.
7 *
8 ********************************************************************************
9 * \copyright
10 * Copyright 2016-2020 Cypress Semiconductor Corporation
11 * SPDX-License-Identifier: Apache-2.0
12 *
13 * Licensed under the Apache License, Version 2.0 (the "License");
14 * you may not use this file except in compliance with the License.
15 * You may obtain a copy of the License at
16 *
17 * http://www.apache.org/licenses/LICENSE-2.0
18 *
19 * Unless required by applicable law or agreed to in writing, software
20 * distributed under the License is distributed on an "AS IS" BASIS,
21 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22 * See the License for the specific language governing permissions and
23 * limitations under the License.
24 *******************************************************************************/
25
26 #include "cy_device.h"
27
28 #if defined (CY_IP_M4CPUSS)
29
30 #include "cy_sysint.h"
31
32 CY_MISRA_FP_BLOCK_START('MISRA C-2012 Rule 8.3', 1, 'Only one prototype will be pciked for compilation');
33 CY_MISRA_FP_BLOCK_START('MISRA C-2012 Rule 8.6', 2, 'Only one prototype will be pciked for compilation');
34 #if (!CY_CPU_CORTEX_M0P) || defined (CY_DOXYGEN)
Cy_SysInt_SetNmiSource(cy_en_sysint_nmi_t nmiNum,IRQn_Type intrSrc)35 void Cy_SysInt_SetNmiSource(cy_en_sysint_nmi_t nmiNum, IRQn_Type intrSrc)
36 #else
37 void Cy_SysInt_SetNmiSource(cy_en_sysint_nmi_t nmiNum, cy_en_intr_t intrSrc)
38 #endif
39 {
40 CY_ASSERT_L3(CY_SYSINT_IS_NMI_NUM_VALID(nmiNum));
41
42 #if (CY_CPU_CORTEX_M0P)
43 CY_ASSERT_L1(CY_SYSINT_IS_PC_0);
44 #endif
45
46 if (CY_CPUSS_V1)
47 {
48 nmiNum = CY_SYSINT_NMI1; /* For CPUSS_ver1 the NMI number is 1 */
49 }
50
51 #if (CY_CPU_CORTEX_M0P)
52 CPUSS_CM0_NMI_CTL((uint32_t)nmiNum - 1UL) = (uint32_t)intrSrc;
53 #else
54 CPUSS_CM4_NMI_CTL((uint32_t)nmiNum - 1UL) = (uint32_t)intrSrc;
55 #endif
56 }
57
58 #if (!CY_CPU_CORTEX_M0P) || defined (CY_DOXYGEN)
Cy_SysInt_GetNmiSource(cy_en_sysint_nmi_t nmiNum)59 IRQn_Type Cy_SysInt_GetNmiSource(cy_en_sysint_nmi_t nmiNum)
60 #else
61 cy_en_intr_t Cy_SysInt_GetNmiSource(cy_en_sysint_nmi_t nmiNum)
62 #endif
63 {
64 CY_ASSERT_L3(CY_SYSINT_IS_NMI_NUM_VALID(nmiNum));
65
66 if (CY_CPUSS_V1)
67 {
68 nmiNum = CY_SYSINT_NMI1; /* For CPUSS_ver1 the NMI number is 1 */
69 }
70
71 #if (CY_CPU_CORTEX_M0P)
72 return ((cy_en_intr_t)(CPUSS_CM0_NMI_CTL((uint32_t)nmiNum - 1UL)));
73 #else
74 return ((IRQn_Type)(CPUSS_CM4_NMI_CTL((uint32_t)nmiNum - 1UL)));
75 #endif
76 }
77 CY_MISRA_BLOCK_END('MISRA C-2012 Rule 8.6');
78 CY_MISRA_BLOCK_END('MISRA C-2012 Rule 8.3');
79
Cy_SysInt_Init(const cy_stc_sysint_t * config,cy_israddress userIsr)80 cy_en_sysint_status_t Cy_SysInt_Init(const cy_stc_sysint_t* config, cy_israddress userIsr)
81 {
82 cy_en_sysint_status_t status = CY_SYSINT_SUCCESS;
83
84 if(NULL != config)
85 {
86 CY_ASSERT_L3(CY_SYSINT_IS_PRIORITY_VALID(config->intrPriority));
87
88 #if (CY_CPU_CORTEX_M0P)
89 if (config->intrSrc > SysTick_IRQn)
90 {
91 Cy_SysInt_SetInterruptSource(config->intrSrc, config->cm0pSrc);
92 }
93 else
94 {
95 status = CY_SYSINT_BAD_PARAM;
96 }
97 #endif
98
99 NVIC_SetPriority(config->intrSrc, config->intrPriority);
100
101 /* Set the new vector only if it was moved to __ramVectors */
102 if (SCB->VTOR == (uint32_t)&__ramVectors)
103 {
104 (void)Cy_SysInt_SetVector(config->intrSrc, userIsr);
105 }
106 }
107 else
108 {
109 status = CY_SYSINT_BAD_PARAM;
110 }
111
112 return(status);
113 }
114
115
116 #if (CY_CPU_CORTEX_M0P) || defined (CY_DOXYGEN)
Cy_SysInt_SetInterruptSource(IRQn_Type IRQn,cy_en_intr_t devIntrSrc)117 void Cy_SysInt_SetInterruptSource(IRQn_Type IRQn, cy_en_intr_t devIntrSrc)
118 {
119 if (CY_CPUSS_V1)
120 {
121 uint32_t regPos = ((uint32_t)IRQn >> CY_SYSINT_CM0P_MUX_SHIFT);
122 if(0UL == (regPos & (uint32_t)~CY_SYSINT_MUX_REG_MSK))
123 {
124 uint32_t bitfield_Pos = (uint32_t)((uint32_t)IRQn - (uint32_t)(regPos << CY_SYSINT_CM0P_MUX_SHIFT)) << CY_SYSINT_CM0P_MUX_SCALE;
125 uint32_t bitfield_Msk = (uint32_t)(CY_SYSINT_CM0P_MUX_MASK << bitfield_Pos);
126
127 CY_REG32_CLR_SET(CPUSS_CM0_INT_CTL[regPos], bitfield, devIntrSrc);
128 }
129 }
130 else /* CPUSS_V2 */
131 {
132 CY_ASSERT_L1(CY_CPUSS_DISCONNECTED_IRQN != devIntrSrc); /* Disconnection feature doesn't work for CPUSS_V2 */
133
134 CPUSS_CM0_SYSTEM_INT_CTL[devIntrSrc] = _VAL2FLD(CPUSS_V2_CM0_SYSTEM_INT_CTL_CPU_INT_IDX, IRQn)
135 | CPUSS_V2_CM0_SYSTEM_INT_CTL_CPU_INT_VALID_Msk;
136 }
137 }
138
139
Cy_SysInt_DisconnectInterruptSource(IRQn_Type IRQn,cy_en_intr_t devIntrSrc)140 void Cy_SysInt_DisconnectInterruptSource(IRQn_Type IRQn, cy_en_intr_t devIntrSrc)
141 {
142 if (CY_CPUSS_V1)
143 {
144 Cy_SysInt_SetInterruptSource(IRQn, CY_CPUSS_DISCONNECTED_IRQN);
145 }
146 else /* CPUSS_V2 */
147 {
148 CPUSS_CM0_SYSTEM_INT_CTL[devIntrSrc] &= (uint32_t)~ CPUSS_V2_CM0_SYSTEM_INT_CTL_CPU_INT_VALID_Msk;
149 }
150 }
151
152
Cy_SysInt_GetInterruptSource(IRQn_Type IRQn)153 cy_en_intr_t Cy_SysInt_GetInterruptSource(IRQn_Type IRQn)
154 {
155 uint32_t tempReg = CY_CPUSS_NOT_CONNECTED_IRQN;
156
157 if (CY_CPUSS_V1)
158 {
159 uint32_t regPos = ((uint32_t)IRQn >> CY_SYSINT_CM0P_MUX_SHIFT);
160 if(0UL == (regPos & (uint32_t)~CY_SYSINT_MUX_REG_MSK))
161 {
162 uint32_t bitfield_Pos = ((uint32_t)IRQn - (regPos << CY_SYSINT_CM0P_MUX_SHIFT)) << CY_SYSINT_CM0P_MUX_SCALE;
163 uint32_t bitfield_Msk = (uint32_t)(CY_SYSINT_CM0P_MUX_MASK << bitfield_Pos);
164
165 tempReg = _FLD2VAL(bitfield, CPUSS_CM0_INT_CTL[regPos]);
166 }
167 }
168
169 return ((cy_en_intr_t)tempReg);
170 }
171
172
Cy_SysInt_GetNvicConnection(cy_en_intr_t devIntrSrc)173 IRQn_Type Cy_SysInt_GetNvicConnection(cy_en_intr_t devIntrSrc)
174 {
175 uint32_t tempReg = CY_CPUSS_NOT_CONNECTED_IRQN;
176
177 if ((!CY_CPUSS_V1) && (CY_SYSINT_ENABLE == _FLD2VAL(CPUSS_V2_CM0_SYSTEM_INT_CTL_CPU_INT_VALID, CPUSS_CM0_SYSTEM_INT_CTL[devIntrSrc])))
178 {
179 tempReg = _FLD2VAL(CPUSS_V2_CM0_SYSTEM_INT_CTL_CPU_INT_IDX, CPUSS_CM0_SYSTEM_INT_CTL[devIntrSrc]);
180 }
181 return ((IRQn_Type)tempReg);
182 }
183
184
Cy_SysInt_GetInterruptActive(IRQn_Type IRQn)185 cy_en_intr_t Cy_SysInt_GetInterruptActive(IRQn_Type IRQn)
186 {
187 uint32_t tempReg = CY_CPUSS_NOT_CONNECTED_IRQN;
188 uint32_t locIdx = (uint32_t)IRQn & CY_SYSINT_INT_STATUS_MSK;
189
190 if (!CY_CPUSS_V1)
191 {
192 if(CY_SYSINT_ENABLE == _FLD2VAL(CPUSS_V2_CM0_INT0_STATUS_SYSTEM_INT_VALID, CPUSS_CM0_INT_STATUS[locIdx]))
193 {
194 tempReg = _FLD2VAL(CPUSS_V2_CM0_INT0_STATUS_SYSTEM_INT_IDX, CPUSS_CM0_INT_STATUS[locIdx]);
195 }
196 }
197 return ((cy_en_intr_t)tempReg);
198 }
199
200 #endif
201
202
203
Cy_SysInt_SetVector(IRQn_Type IRQn,cy_israddress userIsr)204 cy_israddress Cy_SysInt_SetVector(IRQn_Type IRQn, cy_israddress userIsr)
205 {
206 cy_israddress prevIsr;
207
208 /* Set the new vector only if it was moved to __ramVectors */
209 if (SCB->VTOR == (uint32_t)&__ramVectors)
210 {
211 CY_ASSERT_L1(CY_SYSINT_IS_VECTOR_VALID(userIsr));
212
213 prevIsr = __ramVectors[CY_INT_IRQ_BASE + (uint32_t)IRQn];
214 __ramVectors[CY_INT_IRQ_BASE + (uint32_t)IRQn] = userIsr;
215 }
216 else
217 {
218 prevIsr = __Vectors[CY_INT_IRQ_BASE + (uint32_t)IRQn];
219 }
220
221 return (prevIsr);
222 }
223
224
Cy_SysInt_GetVector(IRQn_Type IRQn)225 cy_israddress Cy_SysInt_GetVector(IRQn_Type IRQn)
226 {
227 cy_israddress currIsr;
228
229 /* Return the SRAM ISR address only if it was moved to __ramVectors */
230 if (SCB->VTOR == (uint32_t)&__ramVectors)
231 {
232 currIsr = __ramVectors[CY_INT_IRQ_BASE + (uint32_t)IRQn];
233 }
234 else
235 {
236 currIsr = __Vectors[CY_INT_IRQ_BASE + (uint32_t)IRQn];
237 }
238
239 return (currIsr);
240 }
241
242 #if (!CY_CPU_CORTEX_M0P)
Cy_SysInt_SoftwareTrig(IRQn_Type IRQn)243 void Cy_SysInt_SoftwareTrig(IRQn_Type IRQn)
244 {
245 NVIC->STIR = (uint32_t)IRQn & CY_SYSINT_STIR_MASK;
246 }
247 #endif
248
249 #endif
250
251 /* [] END OF FILE */
252