]> git.sur5r.net Git - freertos/blob
0ba4aa172c2d9b4ab84fab6414946a9345cea422
[freertos] /
1 /***************************************************************************//**\r
2  * @file em_idac.h\r
3  * @brief Current Digital to Analog Converter (IDAC) peripheral API\r
4  * @version 4.2.1\r
5  *******************************************************************************\r
6  * @section License\r
7  * <b>(C) Copyright 2015 Silicon Labs, http://www.silabs.com</b>\r
8  *******************************************************************************\r
9  *\r
10  * Permission is granted to anyone to use this software for any purpose,\r
11  * including commercial applications, and to alter it and redistribute it\r
12  * freely, subject to the following restrictions:\r
13  *\r
14  * 1. The origin of this software must not be misrepresented; you must not\r
15  *    claim that you wrote the original software.\r
16  * 2. Altered source versions must be plainly marked as such, and must not be\r
17  *    misrepresented as being the original software.\r
18  * 3. This notice may not be removed or altered from any source distribution.\r
19  *\r
20  * DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Labs has no\r
21  * obligation to support this Software. Silicon Labs is providing the\r
22  * Software "AS IS", with no express or implied warranties of any kind,\r
23  * including, but not limited to, any implied warranties of merchantability\r
24  * or fitness for any particular purpose or warranties against infringement\r
25  * of any proprietary rights of a third party.\r
26  *\r
27  * Silicon Labs will not be liable for any consequential, incidental, or\r
28  * special damages, or any other relief, or for any claim by any third party,\r
29  * arising from your use of this Software.\r
30  *\r
31  ******************************************************************************/\r
32 \r
33 #ifndef __SILICON_LABS_EM_IDAC_H__\r
34 #define __SILICON_LABS_EM_IDAC_H__\r
35 \r
36 #include "em_device.h"\r
37 \r
38 #if defined(IDAC_COUNT) && (IDAC_COUNT > 0)\r
39 #include <stdbool.h>\r
40 \r
41 #ifdef __cplusplus\r
42 extern "C" {\r
43 #endif\r
44 \r
45 /***************************************************************************//**\r
46  * @addtogroup EM_Library\r
47  * @{\r
48  ******************************************************************************/\r
49 \r
50 /***************************************************************************//**\r
51  * @addtogroup IDAC\r
52  * @{\r
53  ******************************************************************************/\r
54 \r
55 /** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */\r
56 \r
57 /** Validation of IDAC register block pointer reference for assert statements. */\r
58 #define IDAC_REF_VALID(ref)    ((ref) == IDAC0)\r
59 \r
60 /** @endcond */\r
61 \r
62 /*******************************************************************************\r
63  ********************************   ENUMS   ************************************\r
64  ******************************************************************************/\r
65 \r
66 /** Output mode. */\r
67 typedef enum\r
68 {\r
69 #if defined( _IDAC_CTRL_OUTMODE_MASK )\r
70   idacOutputPin     = IDAC_CTRL_OUTMODE_PIN,     /**< Output to IDAC OUT pin */\r
71   idacOutputADC     = IDAC_CTRL_OUTMODE_ADC      /**< Output to ADC */\r
72 #elif ( _IDAC_CTRL_APORTOUTSEL_MASK )\r
73   idacOutputAPORT1XCH0 = IDAC_CTRL_APORTOUTSEL_APORT1XCH0, /**< Output to APORT 1X CH0 */\r
74   idacOutputAPORT1YCH1 = IDAC_CTRL_APORTOUTSEL_APORT1YCH1, /**< Output to APORT 1Y CH1 */\r
75   idacOutputAPORT1XCH2 = IDAC_CTRL_APORTOUTSEL_APORT1XCH2, /**< Output to APORT 1X CH2 */\r
76   idacOutputAPORT1YCH3 = IDAC_CTRL_APORTOUTSEL_APORT1YCH3, /**< Output to APORT 1Y CH3 */\r
77   idacOutputAPORT1XCH4 = IDAC_CTRL_APORTOUTSEL_APORT1XCH4, /**< Output to APORT 1X CH4 */\r
78   idacOutputAPORT1YCH5 = IDAC_CTRL_APORTOUTSEL_APORT1YCH5, /**< Output to APORT 1Y CH5 */\r
79   idacOutputAPORT1XCH6 = IDAC_CTRL_APORTOUTSEL_APORT1XCH6, /**< Output to APORT 1X CH6 */\r
80   idacOutputAPORT1YCH7 = IDAC_CTRL_APORTOUTSEL_APORT1YCH7, /**< Output to APORT 1Y CH7 */\r
81   idacOutputAPORT1XCH8 = IDAC_CTRL_APORTOUTSEL_APORT1XCH8, /**< Output to APORT 1X CH8 */\r
82   idacOutputAPORT1YCH9 = IDAC_CTRL_APORTOUTSEL_APORT1YCH9, /**< Output to APORT 1Y CH9 */\r
83   idacOutputAPORT1XCH10 = IDAC_CTRL_APORTOUTSEL_APORT1XCH10, /**< Output to APORT 1X CH10 */\r
84   idacOutputAPORT1YCH11 = IDAC_CTRL_APORTOUTSEL_APORT1YCH11, /**< Output to APORT 1Y CH11 */\r
85   idacOutputAPORT1XCH12 = IDAC_CTRL_APORTOUTSEL_APORT1XCH12, /**< Output to APORT 1X CH12 */\r
86   idacOutputAPORT1YCH13 = IDAC_CTRL_APORTOUTSEL_APORT1YCH13, /**< Output to APORT 1Y CH13 */\r
87   idacOutputAPORT1XCH14 = IDAC_CTRL_APORTOUTSEL_APORT1XCH14, /**< Output to APORT 1X CH14 */\r
88   idacOutputAPORT1YCH15 = IDAC_CTRL_APORTOUTSEL_APORT1YCH15, /**< Output to APORT 1Y CH15 */\r
89   idacOutputAPORT1XCH16 = IDAC_CTRL_APORTOUTSEL_APORT1XCH16, /**< Output to APORT 1X CH16 */\r
90   idacOutputAPORT1YCH17 = IDAC_CTRL_APORTOUTSEL_APORT1YCH17, /**< Output to APORT 1Y CH17 */\r
91   idacOutputAPORT1XCH18 = IDAC_CTRL_APORTOUTSEL_APORT1XCH18, /**< Output to APORT 1X CH18 */\r
92   idacOutputAPORT1YCH19 = IDAC_CTRL_APORTOUTSEL_APORT1YCH19, /**< Output to APORT 1Y CH19 */\r
93   idacOutputAPORT1XCH20 = IDAC_CTRL_APORTOUTSEL_APORT1XCH20, /**< Output to APORT 1X CH20 */\r
94   idacOutputAPORT1YCH21 = IDAC_CTRL_APORTOUTSEL_APORT1YCH21, /**< Output to APORT 1Y CH21 */\r
95   idacOutputAPORT1XCH22 = IDAC_CTRL_APORTOUTSEL_APORT1XCH22, /**< Output to APORT 1X CH22 */\r
96   idacOutputAPORT1YCH23 = IDAC_CTRL_APORTOUTSEL_APORT1YCH23, /**< Output to APORT 1Y CH23 */\r
97   idacOutputAPORT1XCH24 = IDAC_CTRL_APORTOUTSEL_APORT1XCH24, /**< Output to APORT 1X CH24 */\r
98   idacOutputAPORT1YCH25 = IDAC_CTRL_APORTOUTSEL_APORT1YCH25, /**< Output to APORT 1Y CH25 */\r
99   idacOutputAPORT1XCH26 = IDAC_CTRL_APORTOUTSEL_APORT1XCH26, /**< Output to APORT 1X CH26 */\r
100   idacOutputAPORT1YCH27 = IDAC_CTRL_APORTOUTSEL_APORT1YCH27, /**< Output to APORT 1Y CH27 */\r
101   idacOutputAPORT1XCH28 = IDAC_CTRL_APORTOUTSEL_APORT1XCH28, /**< Output to APORT 1X CH28 */\r
102   idacOutputAPORT1YCH29 = IDAC_CTRL_APORTOUTSEL_APORT1YCH29, /**< Output to APORT 1Y CH29 */\r
103   idacOutputAPORT1XCH30 = IDAC_CTRL_APORTOUTSEL_APORT1XCH30, /**< Output to APORT 1X CH30 */\r
104   idacOutputAPORT1YCH31 = IDAC_CTRL_APORTOUTSEL_APORT1YCH31, /**< Output to APORT 1Y CH31 */\r
105 #endif\r
106 } IDAC_OutMode_TypeDef;\r
107 \r
108 \r
109 /** Selects which Peripheral Reflex System (PRS) signal to use when\r
110     PRS is set to control the IDAC output. */\r
111 typedef enum\r
112 {\r
113   idacPRSSELCh0 = IDAC_CTRL_PRSSEL_PRSCH0,      /**< PRS channel 0. */\r
114   idacPRSSELCh1 = IDAC_CTRL_PRSSEL_PRSCH1,      /**< PRS channel 1. */\r
115   idacPRSSELCh2 = IDAC_CTRL_PRSSEL_PRSCH2,      /**< PRS channel 2. */\r
116   idacPRSSELCh3 = IDAC_CTRL_PRSSEL_PRSCH3,      /**< PRS channel 3. */\r
117 #if defined( IDAC_CTRL_PRSSEL_PRSCH4 )\r
118   idacPRSSELCh4 = IDAC_CTRL_PRSSEL_PRSCH4,      /**< PRS channel 4. */\r
119   idacPRSSELCh5 = IDAC_CTRL_PRSSEL_PRSCH5,      /**< PRS channel 5. */\r
120 #endif\r
121 #if defined( IDAC_CTRL_PRSSEL_PRSCH6 )\r
122   idacPRSSELCh6 = IDAC_CTRL_PRSSEL_PRSCH6,      /**< PRS channel 6. */\r
123   idacPRSSELCh7 = IDAC_CTRL_PRSSEL_PRSCH7,      /**< PRS channel 7. */\r
124   idacPRSSELCh8 = IDAC_CTRL_PRSSEL_PRSCH8,      /**< PRS channel 8. */\r
125   idacPRSSELCh9 = IDAC_CTRL_PRSSEL_PRSCH9,      /**< PRS channel 9. */\r
126   idacPRSSELCh10 = IDAC_CTRL_PRSSEL_PRSCH10,    /**< PRS channel 10 */\r
127   idacPRSSELCh11 = IDAC_CTRL_PRSSEL_PRSCH11,    /**< PRS channel 11 */\r
128 #endif\r
129 } IDAC_PRSSEL_TypeDef;\r
130 \r
131 \r
132 /** Selects which current range to use. */\r
133 typedef enum\r
134 {\r
135   idacCurrentRange0 = IDAC_CURPROG_RANGESEL_RANGE0, /**< current range 0. */\r
136   idacCurrentRange1 = IDAC_CURPROG_RANGESEL_RANGE1, /**< current range 1. */\r
137   idacCurrentRange2 = IDAC_CURPROG_RANGESEL_RANGE2, /**< current range 2. */\r
138   idacCurrentRange3 = IDAC_CURPROG_RANGESEL_RANGE3, /**< current range 3. */\r
139 } IDAC_Range_TypeDef;\r
140 \r
141 /*******************************************************************************\r
142  *******************************   STRUCTS   ***********************************\r
143  ******************************************************************************/\r
144 \r
145 /** IDAC init structure, common for both channels. */\r
146 typedef struct\r
147 {\r
148   /** Enable IDAC. */\r
149   bool                  enable;\r
150 \r
151   /** Output mode */\r
152   IDAC_OutMode_TypeDef  outMode;\r
153 \r
154   /**\r
155    * Enable Peripheral reflex system (PRS) to control IDAC output. If false,\r
156    * the IDAC output is controlled by writing to IDAC_OUTEN in IDAC_CTRL or\r
157    * by calling IDAC_OutEnable().\r
158    */\r
159   bool                  prsEnable;\r
160 \r
161   /**\r
162    * Peripheral reflex system channel selection. Only applicable if @p prsEnable\r
163    * is enabled.\r
164    */\r
165   IDAC_PRSSEL_TypeDef   prsSel;\r
166 \r
167   /** Enable/disable current sink mode. */\r
168   bool                  sinkEnable;\r
169 \r
170 } IDAC_Init_TypeDef;\r
171 \r
172 /** Default config for IDAC init structure. */\r
173 #if defined( _IDAC_CTRL_OUTMODE_MASK )\r
174 #define IDAC_INIT_DEFAULT                                              \\r
175 {                                                                      \\r
176   false,          /**< Leave IDAC disabled when init done. */          \\r
177   idacOutputPin,  /**< Output to IDAC output pin. */                   \\r
178   false,          /**< Disable PRS triggering. */                      \\r
179   idacPRSSELCh0,  /**< Select PRS ch0 (if PRS triggering enabled). */  \\r
180   false           /**< Disable current sink mode. */                   \\r
181 }\r
182 #elif ( _IDAC_CTRL_APORTOUTSEL_MASK )\r
183 #define IDAC_INIT_DEFAULT                                              \\r
184 {                                                                      \\r
185   false,          /**< Leave IDAC disabled when init done. */          \\r
186   idacOutputAPORT1XCH0, /**< Output to APORT. */                       \\r
187   false,          /**< Disable PRS triggering. */                      \\r
188   idacPRSSELCh0,  /**< Select PRS ch0 (if PRS triggering enabled). */  \\r
189   false           /**< Disable current sink mode. */                   \\r
190 }\r
191 #endif\r
192 \r
193 \r
194 /*******************************************************************************\r
195  *****************************   PROTOTYPES   **********************************\r
196  ******************************************************************************/\r
197 \r
198 /***************************************************************************//**\r
199  * @brief\r
200  *   Initialize IDAC.\r
201  *\r
202  * @details\r
203  *   Initializes IDAC according to the initialization structure parameter, and\r
204  *   sets the default calibration value stored in the DEVINFO structure.\r
205  *\r
206  * @note\r
207  *   This function will disable the IDAC prior to configuration.\r
208  *\r
209  * @param[in] idac\r
210  *   Pointer to IDAC peripheral register block.\r
211  *\r
212  * @param[in] init\r
213  *   Pointer to IDAC initialization structure.\r
214  ******************************************************************************/\r
215 void IDAC_Init(IDAC_TypeDef *idac, const IDAC_Init_TypeDef *init);\r
216 \r
217 \r
218 /***************************************************************************//**\r
219  * @brief\r
220  *   Enable/disable IDAC.\r
221  *\r
222  * @param[in] idac\r
223  *   Pointer to IDAC peripheral register block.\r
224  *\r
225  * @param[in] enable\r
226  *   true to enable IDAC, false to disable.\r
227  ******************************************************************************/\r
228 void IDAC_Enable(IDAC_TypeDef *idac, bool enable);\r
229 \r
230 \r
231 /***************************************************************************//**\r
232  * @brief\r
233  *   Reset IDAC to same state as after a HW reset.\r
234  *\r
235  * @param[in] idac\r
236  *   Pointer to IDAC peripheral register block.\r
237  ******************************************************************************/\r
238 void IDAC_Reset(IDAC_TypeDef *idac);\r
239 \r
240 \r
241 /***************************************************************************//**\r
242  * @brief\r
243  *   Enable/disable Minimal Output Transition mode.\r
244  *\r
245  * @param[in] idac\r
246  *   Pointer to IDAC peripheral register block.\r
247  *\r
248  * @param[in] enable\r
249  *   true to enable Minimal Output Transition mode, false to disable.\r
250  ******************************************************************************/\r
251 void IDAC_MinimalOutputTransitionMode(IDAC_TypeDef *idac, bool enable);\r
252 \r
253 \r
254 /***************************************************************************//**\r
255  * @brief\r
256  *   Set the current range of the IDAC output.\r
257  *\r
258  * @details\r
259  *   This function sets the current range of the IDAC output. The function\r
260  *   also updates the IDAC calibration register (IDAC_CAL) with the default\r
261  *   calibration value (from DEVINFO, factory setting) corresponding to the\r
262  *   specified range.\r
263  *\r
264  * @param[in] idac\r
265  *   Pointer to IDAC peripheral register block.\r
266  *\r
267  * @param[in] range\r
268  *   Current range value.\r
269  ******************************************************************************/\r
270 void IDAC_RangeSet(IDAC_TypeDef *idac, const IDAC_Range_TypeDef range);\r
271 \r
272 \r
273 /***************************************************************************//**\r
274  * @brief\r
275  *   Set the current step of the IDAC output.\r
276  *\r
277  * @param[in] idac\r
278  *   Pointer to IDAC peripheral register block.\r
279  *\r
280  * @param[in] step\r
281  *   Step value for IDAC output. Valid range is 0-31.\r
282  ******************************************************************************/\r
283 void IDAC_StepSet(IDAC_TypeDef *idac, const uint32_t step);\r
284 \r
285 \r
286 /***************************************************************************//**\r
287  * @brief\r
288  *   Enable/disable the IDAC OUT pin.\r
289  *\r
290  * @param[in] idac\r
291  *   Pointer to IDAC peripheral register block.\r
292  *\r
293  * @param[in] enable\r
294  *   true to enable the IDAC OUT pin, false to disable.\r
295  ******************************************************************************/\r
296 void IDAC_OutEnable(IDAC_TypeDef *idac, bool enable);\r
297 \r
298 \r
299 #if defined( _IDAC_IEN_MASK )\r
300 /***************************************************************************//**\r
301  * @brief\r
302  *   Clear one or more pending IDAC interrupts.\r
303  *\r
304  * @param[in] IDAC\r
305  *   Pointer to IDAC peripheral register block.\r
306  *\r
307  * @param[in] flags\r
308  *   Pending IDAC interrupt source(s) to clear. Use one or more valid\r
309  *   interrupt flags for the IDAC module (IDAC_IF_nnn) OR'ed together.\r
310  ******************************************************************************/\r
311 __STATIC_INLINE void IDAC_IntClear(IDAC_TypeDef *idac, uint32_t flags)\r
312 {\r
313   idac->IFC = flags;\r
314 }\r
315 \r
316 \r
317 /***************************************************************************//**\r
318  * @brief\r
319  *   Disable one or more IDAC interrupts.\r
320  *\r
321  * @param[in] IDAC\r
322  *   Pointer to IDAC peripheral register block.\r
323  *\r
324  * @param[in] flags\r
325  *   IDAC interrupt source(s) to disable. Use one or more valid\r
326  *   interrupt flags for the IDAC module (IDAC_IF_nnn) OR'ed together.\r
327  ******************************************************************************/\r
328 __STATIC_INLINE void IDAC_IntDisable(IDAC_TypeDef *idac, uint32_t flags)\r
329 {\r
330   idac->IEN &= ~flags;\r
331 }\r
332 \r
333 \r
334 /***************************************************************************//**\r
335  * @brief\r
336  *   Enable one or more IDAC interrupts.\r
337  *\r
338  * @note\r
339  *   Depending on the use, a pending interrupt may already be set prior to\r
340  *   enabling the interrupt. Consider using IDAC_IntClear() prior to enabling\r
341  *   if such a pending interrupt should be ignored.\r
342  *\r
343  * @param[in] IDAC\r
344  *   Pointer to IDAC peripheral register block.\r
345  *\r
346  * @param[in] flags\r
347  *   IDAC interrupt source(s) to enable. Use one or more valid\r
348  *   interrupt flags for the IDAC module (IDAC_IF_nnn) OR'ed together.\r
349  ******************************************************************************/\r
350 __STATIC_INLINE void IDAC_IntEnable(IDAC_TypeDef *idac, uint32_t flags)\r
351 {\r
352   idac->IEN |= flags;\r
353 }\r
354 \r
355 \r
356 /***************************************************************************//**\r
357  * @brief\r
358  *   Get pending IDAC interrupt flags.\r
359  *\r
360  * @note\r
361  *   The event bits are not cleared by the use of this function.\r
362  *\r
363  * @param[in] IDAC\r
364  *   Pointer to IDAC peripheral register block.\r
365  *\r
366  * @return\r
367  *   IDAC interrupt source(s) pending. Returns one or more valid\r
368  *   interrupt flags for the IDAC module (IDAC_IF_nnn) OR'ed together.\r
369  ******************************************************************************/\r
370 __STATIC_INLINE uint32_t IDAC_IntGet(IDAC_TypeDef *idac)\r
371 {\r
372   return idac->IF;\r
373 }\r
374 \r
375 \r
376 /***************************************************************************//**\r
377  * @brief\r
378  *   Get enabled and pending IDAC interrupt flags.\r
379  *   Useful for handling more interrupt sources in the same interrupt handler.\r
380  *\r
381  * @param[in] IDAC\r
382  *   Pointer to IDAC peripheral register block.\r
383  *\r
384  * @note\r
385  *   Interrupt flags are not cleared by the use of this function.\r
386  *\r
387  * @return\r
388  *   Pending and enabled IDAC interrupt sources.\r
389  *   The return value is the bitwise AND combination of\r
390  *   - the OR combination of enabled interrupt sources in IDACx_IEN_nnn\r
391  *     register (IDACx_IEN_nnn) and\r
392  *   - the OR combination of valid interrupt flags of the IDAC module\r
393  *     (IDACx_IF_nnn).\r
394  ******************************************************************************/\r
395 __STATIC_INLINE uint32_t IDAC_IntGetEnabled(IDAC_TypeDef *idac)\r
396 {\r
397   uint32_t ien;\r
398 \r
399   /* Store flags in temporary variable in order to define explicit order\r
400    * of volatile accesses. */\r
401   ien = idac->IEN;\r
402 \r
403   /* Bitwise AND of pending and enabled interrupts */\r
404   return idac->IF & ien;\r
405 }\r
406 \r
407 \r
408 /***************************************************************************//**\r
409  * @brief\r
410  *   Set one or more pending IDAC interrupts from SW.\r
411  *\r
412  * @param[in] IDAC\r
413  *   Pointer to IDAC peripheral register block.\r
414  *\r
415  * @param[in] flags\r
416  *   IDAC interrupt source(s) to set to pending. Use one or more valid\r
417  *   interrupt flags for the IDAC module (IDAC_IF_nnn) OR'ed together.\r
418  ******************************************************************************/\r
419 __STATIC_INLINE void IDAC_IntSet(IDAC_TypeDef *idac, uint32_t flags)\r
420 {\r
421   idac->IFS = flags;\r
422 }\r
423 #endif\r
424 \r
425 \r
426 /** @} (end addtogroup IDAC) */\r
427 /** @} (end addtogroup EM_Library) */\r
428 \r
429 #ifdef __cplusplus\r
430 }\r
431 #endif\r
432 \r
433 #endif /* defined(IDAC_COUNT) && (IDAC_COUNT > 0) */\r
434 \r
435 #endif /* __SILICON_LABS_EM_IDAC_H__ */\r