1 /**
2 * @file xmc_posif.c
3 * @date 2017-02-25
4 *
5 * @cond
6 **********************************************************************************
7 * XMClib v2.1.24 - XMC Peripheral Driver Library
8 *
9 * Copyright (c) 2015-2019, Infineon Technologies AG
10 * All rights reserved.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification,are permitted provided that the following conditions are met:
14 *
15 * Redistributions of source code must retain the above copyright notice,
16 * this list of conditions and the following disclaimer.
17 *
18 * Redistributions in binary form must reproduce the above copyright notice,
19 * this list of conditions and the following disclaimer in the documentation
20 * and/or other materials provided with the distribution.
21 *
22 * Neither the name of the copyright holders nor the names of its contributors
23 * may be used to endorse or promote products derived from this software without
24 * specific prior written permission.
25 *
26 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
27 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
30 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34 * CONTRACT, STRICT LIABILITY,OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36 * POSSIBILITY OF SUCH DAMAGE.
37 *
38 * To improve the quality of the software, users are encouraged to share
39 * modifications, enhancements or bug fixes with Infineon Technologies AG
40 * dave@infineon.com).
41 **********************************************************************************
42 *
43 * Change History
44 * --------------
45 *
46 * 2015-02-18:
47 * - Initial version
48 *
49 * 2015-02-20:
50 * - Driver description added <BR>
51 *
52 * 2015-04-30:
53 * - XMC_POSIF_Enable and XMC_POSIF_Disable APIs updated for POSIF1 peripheral check <BR>
54 *
55 * 2015-06-19:
56 * - Removed GetDriverVersion API <BR>
57 *
58 * 2017-02-25:
59 * - XMC_POSIF_Enable() and XMC_POSIF_Disable() fixed compilation warnings
60 *
61 * @endcond
62 *
63 */
64
65 /*********************************************************************************************************************
66 * HEADER FILES
67 ********************************************************************************************************************/
68 #include <xmc_posif.h>
69
70 /* POSIF is not available on XMC1100 and XMC1200 */
71 #if defined(POSIF0)
72 #include <xmc_scu.h>
73
74 /*********************************************************************************************************************
75 * MACROS
76 ********************************************************************************************************************/
77 #define XMC_POSIF_PCONF_INSEL_Msk (0x3fUL << POSIF_PCONF_INSEL0_Pos) /*< Mask for input pins selection */
78 #define XMC_POSIF_INSEL_MAX (4U) /*< Maximum possible input selector */
79
80 /*********************************************************************************************************************
81 * LOCAL ROUTINES
82 ********************************************************************************************************************/
83 #ifdef XMC_ASSERT_ENABLE
XMC_POSIF_IsPeripheralValid(const XMC_POSIF_t * const peripheral)84 __STATIC_INLINE bool XMC_POSIF_IsPeripheralValid(const XMC_POSIF_t *const peripheral)
85 {
86 bool tmp;
87
88 tmp = (peripheral == POSIF0);
89 #if defined(POSIF1)
90 tmp |= (peripheral == POSIF1);
91 #endif
92
93 return tmp;
94 }
95 #endif
96 /*********************************************************************************************************************
97 * API IMPLEMENTATION
98 ********************************************************************************************************************/
99
100 /* API to enable the POSIF module */
XMC_POSIF_Enable(XMC_POSIF_t * const peripheral)101 void XMC_POSIF_Enable(XMC_POSIF_t *const peripheral)
102 {
103 #if UC_FAMILY == XMC4
104 XMC_SCU_CLOCK_EnableClock(XMC_SCU_CLOCK_CCU);
105 #endif
106
107 if (peripheral == POSIF0)
108 {
109 #if defined(CLOCK_GATING_SUPPORTED)
110 XMC_SCU_CLOCK_UngatePeripheralClock(XMC_SCU_PERIPHERAL_CLOCK_POSIF0);
111 #endif
112 #if defined(PERIPHERAL_RESET_SUPPORTED)
113 XMC_SCU_RESET_DeassertPeripheralReset(XMC_SCU_PERIPHERAL_RESET_POSIF0);
114 #endif
115 }
116 #if defined(POSIF1)
117 else if (peripheral == POSIF1)
118 {
119 #if defined(CLOCK_GATING_SUPPORTED)
120 XMC_SCU_CLOCK_UngatePeripheralClock(XMC_SCU_PERIPHERAL_CLOCK_POSIF1);
121 #endif
122 #if defined(PERIPHERAL_RESET_SUPPORTED)
123 XMC_SCU_RESET_DeassertPeripheralReset(XMC_SCU_PERIPHERAL_RESET_POSIF1);
124 #endif
125 }
126 #endif
127 else
128 {
129 XMC_ASSERT("XMC_POSIF_Disable:Invalid module pointer", 0);
130 }
131 }
132
133 /* API to disable the POSIF module */
XMC_POSIF_Disable(XMC_POSIF_t * const peripheral)134 void XMC_POSIF_Disable(XMC_POSIF_t *const peripheral)
135 {
136 if (peripheral == POSIF0)
137 {
138 #if defined(PERIPHERAL_RESET_SUPPORTED)
139 XMC_SCU_RESET_AssertPeripheralReset(XMC_SCU_PERIPHERAL_RESET_POSIF0);
140 #endif
141 #if defined(CLOCK_GATING_SUPPORTED)
142 XMC_SCU_CLOCK_GatePeripheralClock(XMC_SCU_PERIPHERAL_CLOCK_POSIF0);
143 #endif
144 }
145 #if defined(POSIF1)
146 else if (peripheral == POSIF1)
147 {
148 #if defined(PERIPHERAL_RESET_SUPPORTED)
149 XMC_SCU_RESET_AssertPeripheralReset(XMC_SCU_PERIPHERAL_RESET_POSIF1);
150 #endif
151 #if defined(CLOCK_GATING_SUPPORTED)
152 XMC_SCU_CLOCK_GatePeripheralClock(XMC_SCU_PERIPHERAL_CLOCK_POSIF1);
153 #endif
154 }
155 #endif
156 else
157 {
158 XMC_ASSERT("XMC_POSIF_Disable:Invalid module pointer", 0);
159 }
160 }
161
162 /* API to initialize POSIF global resources */
XMC_POSIF_Init(XMC_POSIF_t * const peripheral,const XMC_POSIF_CONFIG_t * const config)163 void XMC_POSIF_Init(XMC_POSIF_t *const peripheral, const XMC_POSIF_CONFIG_t *const config)
164 {
165 XMC_ASSERT("XMC_POSIF_Init:Invalid module pointer", XMC_POSIF_IsPeripheralValid(peripheral));
166 XMC_ASSERT("XMC_POSIF_Init:NULL Pointer", (config != (XMC_POSIF_CONFIG_t *)NULL) );
167
168 /* Enable the POSIF module */
169 XMC_POSIF_Enable(peripheral);
170
171 /* Stop POSIF */
172 XMC_POSIF_Stop(peripheral);
173
174 /* Program the operational mode, input selectors and debounce filter */
175 peripheral->PCONF = config->pconf;
176 }
177
178 /* API to initialize hall sensor interface */
XMC_POSIF_HSC_Init(XMC_POSIF_t * const peripheral,const XMC_POSIF_HSC_CONFIG_t * const config)179 XMC_POSIF_STATUS_t XMC_POSIF_HSC_Init(XMC_POSIF_t *const peripheral, const XMC_POSIF_HSC_CONFIG_t * const config)
180 {
181 XMC_POSIF_STATUS_t retval;
182
183 XMC_ASSERT("XMC_POSIF_HSC_Init:Invalid module pointer\n", XMC_POSIF_IsPeripheralValid(peripheral));
184 XMC_ASSERT("XMC_POSIF_HSC_Init:NULL Pointer\n", (config != (XMC_POSIF_HSC_CONFIG_t *)NULL) );
185
186 if (XMC_POSIF_MODE_HALL_SENSOR == (XMC_POSIF_MODE_t)((peripheral->PCONF) & (uint32_t)POSIF_PCONF_FSEL_Msk) )
187 {
188 peripheral->PCONF |= config->hall_config;
189 retval = XMC_POSIF_STATUS_OK;
190 }
191 else
192 {
193 retval = XMC_POSIF_STATUS_ERROR;
194 }
195 return retval;
196 }
197
198 /* API to initialize quadrature decoder interface */
XMC_POSIF_QD_Init(XMC_POSIF_t * const peripheral,const XMC_POSIF_QD_CONFIG_t * const config)199 XMC_POSIF_STATUS_t XMC_POSIF_QD_Init(XMC_POSIF_t *const peripheral, const XMC_POSIF_QD_CONFIG_t * const config)
200 {
201 uint8_t reg;
202 XMC_POSIF_STATUS_t retval;
203
204 XMC_ASSERT("XMC_POSIF_QD_Init:Invalid module pointer", XMC_POSIF_IsPeripheralValid(peripheral));
205 XMC_ASSERT("XMC_POSIF_QD_Init:NULL Pointer", (config != (XMC_POSIF_QD_CONFIG_t *)NULL) );
206
207 reg = (uint8_t)((peripheral->PCONF) & (uint32_t)POSIF_PCONF_FSEL_Msk);
208 if (((uint32_t)XMC_POSIF_MODE_QD == reg) || ((uint32_t)XMC_POSIF_MODE_MCM_QD == reg))
209 {
210 /* Program the quadrature mode */
211 peripheral->PCONF |= (uint32_t)(config->mode) << POSIF_PCONF_QDCM_Pos;
212 peripheral->QDC = config->qdc;
213 retval = XMC_POSIF_STATUS_OK;
214 }
215 else
216 {
217 retval = XMC_POSIF_STATUS_ERROR;
218 }
219
220 return retval;
221 }
222
223 /* API to initialize multi-channel mode.
224 * This is used in Hall mode, standalone multi-channel mode and quadrature with multi-channel mode
225 */
XMC_POSIF_MCM_Init(XMC_POSIF_t * const peripheral,const XMC_POSIF_MCM_CONFIG_t * const config)226 XMC_POSIF_STATUS_t XMC_POSIF_MCM_Init(XMC_POSIF_t *const peripheral, const XMC_POSIF_MCM_CONFIG_t * const config)
227 {
228 XMC_POSIF_STATUS_t retval;
229
230 XMC_ASSERT("XMC_POSIF_MCM_Init:Invalid module pointer", XMC_POSIF_IsPeripheralValid(peripheral));
231 XMC_ASSERT("XMC_POSIF_MCM_Init:NULL Pointer", (config != (XMC_POSIF_MCM_CONFIG_t *)NULL) );
232
233 if ((XMC_POSIF_MODE_t)((peripheral->PCONF) & (uint32_t)POSIF_PCONF_FSEL_Msk) != XMC_POSIF_MODE_QD)
234 {
235 peripheral->PCONF |= config->mcm_config;
236 retval = XMC_POSIF_STATUS_OK;
237 }
238 else
239 {
240 retval = XMC_POSIF_STATUS_ERROR;
241 }
242 return retval;
243 }
244
245 /* API to configure input source */
XMC_POSIF_SelectInputSource(XMC_POSIF_t * const peripheral,const XMC_POSIF_INPUT_PORT_t input0,const XMC_POSIF_INPUT_PORT_t input1,const XMC_POSIF_INPUT_PORT_t input2)246 void XMC_POSIF_SelectInputSource (XMC_POSIF_t *const peripheral, const XMC_POSIF_INPUT_PORT_t input0,
247 const XMC_POSIF_INPUT_PORT_t input1, const XMC_POSIF_INPUT_PORT_t input2)
248 {
249 uint32_t reg;
250 XMC_ASSERT("XMC_POSIF_SelectInputSource:Invalid module pointer", XMC_POSIF_IsPeripheralValid(peripheral));
251 XMC_ASSERT("XMC_POSIF_SelectInputSource:Wrong input port input0", (input0 < XMC_POSIF_INSEL_MAX));
252 XMC_ASSERT("XMC_POSIF_SelectInputSource:Wrong input port input1", (input1 < XMC_POSIF_INSEL_MAX));
253 XMC_ASSERT("XMC_POSIF_SelectInputSource:Wrong input port input2", (input2 < XMC_POSIF_INSEL_MAX));
254
255 reg = (uint32_t)((((uint32_t)input0 << POSIF_PCONF_INSEL0_Pos) & (uint32_t)POSIF_PCONF_INSEL0_Msk) |
256 (((uint32_t)input1 << POSIF_PCONF_INSEL1_Pos) & (uint32_t)POSIF_PCONF_INSEL1_Msk) |
257 (((uint32_t)input2 << POSIF_PCONF_INSEL2_Pos) & (uint32_t)POSIF_PCONF_INSEL2_Msk));
258 peripheral->PCONF = ((peripheral->PCONF & ~(uint32_t)XMC_POSIF_PCONF_INSEL_Msk) | reg);
259 }
260
261 /* API to select an interrupt node */
XMC_POSIF_SetInterruptNode(XMC_POSIF_t * const peripheral,const XMC_POSIF_IRQ_EVENT_t event,const XMC_POSIF_SR_ID_t sr)262 void XMC_POSIF_SetInterruptNode(XMC_POSIF_t *const peripheral, const XMC_POSIF_IRQ_EVENT_t event, const XMC_POSIF_SR_ID_t sr)
263 {
264 uint32_t reg;
265
266 XMC_ASSERT("XMC_POSIF_SetInterruptNode:Invalid module pointer", XMC_POSIF_IsPeripheralValid(peripheral));
267 XMC_ASSERT("XMC_POSIF_SetInterruptNode:Wrong IRQ event", (event <= XMC_POSIF_IRQ_EVENT_PCLK) );
268 XMC_ASSERT("XMC_POSIF_SetInterruptNode:Wrong SR ID", (sr <= XMC_POSIF_SR_ID_1) );
269
270 reg = peripheral->PFLGE;
271 reg &= ~((uint32_t)1 << ((uint32_t)event + (uint32_t)POSIF_PFLGE_CHESEL_Pos));
272 reg |= (uint32_t)sr << ((uint32_t)event + (uint32_t)POSIF_PFLGE_CHESEL_Pos);
273 peripheral->PFLGE = reg;
274 }
275 #endif /* #if defined(POSIF0) */
276