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