1 /***************************************************************************//**
2  * @file
3  * @brief Capacitive Sense Module (CSEN) peripheral API
4  *******************************************************************************
5  * # License
6  * <b>Copyright 2018 Silicon Laboratories Inc. www.silabs.com</b>
7  *******************************************************************************
8  *
9  * SPDX-License-Identifier: Zlib
10  *
11  * The licensor of this software is Silicon Laboratories Inc.
12  *
13  * This software is provided 'as-is', without any express or implied
14  * warranty. In no event will the authors be held liable for any damages
15  * arising from the use of this software.
16  *
17  * Permission is granted to anyone to use this software for any purpose,
18  * including commercial applications, and to alter it and redistribute it
19  * freely, subject to the following restrictions:
20  *
21  * 1. The origin of this software must not be misrepresented; you must not
22  *    claim that you wrote the original software. If you use this software
23  *    in a product, an acknowledgment in the product documentation would be
24  *    appreciated but is not required.
25  * 2. Altered source versions must be plainly marked as such, and must not be
26  *    misrepresented as being the original software.
27  * 3. This notice may not be removed or altered from any source distribution.
28  *
29  ******************************************************************************/
30 
31 #ifndef EM_CSEN_H
32 #define EM_CSEN_H
33 
34 #include "em_device.h"
35 #if defined(CSEN_COUNT) && (CSEN_COUNT > 0)
36 
37 #include <stdbool.h>
38 #include "em_bus.h"
39 
40 #ifdef __cplusplus
41 extern "C" {
42 #endif
43 
44 /***************************************************************************//**
45  * @addtogroup csen CSEN - Capacitive Sense
46  * @brief Capacitive Sense (CSEN) Peripheral API.
47  *
48  * @details
49  *  Provides functions to control the capacitive sense
50  *  peripheral of Silicon Labs' 32-bit MCUs and SoCs. The CSEN includes a
51  *  capacitance-to-digital circuit that measures capacitance on selected
52  *  inputs. Measurements are performed using either a Successive Approximation
53  *  Register (SAR) or a Delta Modulator (DM) analog to digital converter.
54  *
55  *  The CSEN can be configured to measure capacitance on a single port pin
56  *  or to automatically measure multiple port pins in succession using scan
57  *  mode. Also, several port pins can be shorted together to measure the
58  *  combined capacitance.
59  *
60  *  The CSEN includes an accumulator, which can be configured to average
61  *  multiple conversions on the selected input. Additionally, an Exponential
62  *  Moving Average (EMA) calculator is included to provide data smoothing.
63  *  A comparator is also included and can be used to terminate a continuous
64  *  conversion when the configured threshold condition is met.
65  *
66  *  The following example shows how to initialize and start a single
67  *  conversion on one input:
68  *
69  *  @include em_csen_single.c
70  *
71  * @{
72  ******************************************************************************/
73 
74 /*******************************************************************************
75  ********************************   ENUMS   ************************************
76  ******************************************************************************/
77 
78 /** Comparator Mode. Selects the operation of the digital comparator. */
79 typedef enum {
80   /** Comparator is disabled. */
81   csenCmpModeDisabled    = 0,
82 
83   /** Comparator trips when the result is greater than the threshold. */
84   csenCmpModeGreater     = CSEN_CTRL_CMPEN | CSEN_CTRL_CMPPOL_GT,
85 
86   /** Comparator trips when the result is less than or equal to the threshold. */
87   csenCmpModeLessOrEqual = CSEN_CTRL_CMPEN | CSEN_CTRL_CMPPOL_LTE,
88 
89   /** Comparator trips when the EMA is within the threshold window. */
90   csenCmpModeEMAWindow   = CSEN_CTRL_EMACMPEN,
91 } CSEN_CmpMode_TypeDef;
92 
93 /** Converter Select. Determines the converter operational mode. */
94 typedef enum {
95   /** Successive Approximation (SAR) converter. */
96   csenConvSelSAR     = CSEN_CTRL_CONVSEL_SAR,
97 
98   /** Successive Approximation (SAR) converter with low frequency attenuation. */
99   csenConvSelSARChop = CSEN_CTRL_CONVSEL_SAR | CSEN_CTRL_CHOPEN_ENABLE,
100 
101   /** Delta Modulation (DM) converter. */
102   csenConvSelDM      = CSEN_CTRL_CONVSEL_DM,
103 
104   /** Delta Modulation (DM) converter with low frequency attenuation. */
105   csenConvSelDMChop  = CSEN_CTRL_CONVSEL_DM | CSEN_CTRL_CHOPEN_ENABLE,
106 } CSEN_ConvSel_TypeDef;
107 
108 /** Sample Mode. Determines how inputs are sampled for a conversion. */
109 typedef enum {
110   /** Converts multiple inputs shorted together and stop. */
111   csenSampleModeBonded     = CSEN_CTRL_CM_SGL | CSEN_CTRL_MCEN_ENABLE,
112 
113   /** Converts one input and stop. */
114   csenSampleModeSingle     = CSEN_CTRL_CM_SGL,
115 
116   /** Converts multiple inputs one at a time and stop. */
117   csenSampleModeScan       = CSEN_CTRL_CM_SCAN,
118 
119   /** Continuously converts multiple inputs shorted together. */
120   csenSampleModeContBonded = CSEN_CTRL_CM_CONTSGL | CSEN_CTRL_MCEN_ENABLE,
121 
122   /** Continuously converts one input. */
123   csenSampleModeContSingle = CSEN_CTRL_CM_CONTSGL,
124 
125   /** Continuously converts multiple inputs one at a time. */
126   csenSampleModeContScan   = CSEN_CTRL_CM_CONTSCAN,
127 } CSEN_SampleMode_TypeDef;
128 
129 /** Starts Trigger Select. */
130 typedef enum {
131   csenTrigSelPRS   = _CSEN_CTRL_STM_PRS,   /**< PRS system. */
132   csenTrigSelTimer = _CSEN_CTRL_STM_TIMER, /**< CSEN PC timer. */
133   csenTrigSelStart = _CSEN_CTRL_STM_START, /**< Start bit. */
134 } CSEN_TrigSel_TypeDef;
135 
136 /** Accumulator Mode Select. */
137 typedef enum {
138   csenAccMode1  = _CSEN_CTRL_ACU_ACC1,  /**< Accumulate 1 sample. */
139   csenAccMode2  = _CSEN_CTRL_ACU_ACC2,  /**< Accumulate 2 samples. */
140   csenAccMode4  = _CSEN_CTRL_ACU_ACC4,  /**< Accumulate 4 samples. */
141   csenAccMode8  = _CSEN_CTRL_ACU_ACC8,  /**< Accumulate 8 samples. */
142   csenAccMode16 = _CSEN_CTRL_ACU_ACC16, /**< Accumulate 16 samples. */
143   csenAccMode32 = _CSEN_CTRL_ACU_ACC32, /**< Accumulate 32 samples. */
144   csenAccMode64 = _CSEN_CTRL_ACU_ACC64, /**< Accumulate 64 samples. */
145 } CSEN_AccMode_TypeDef;
146 
147 /** Successive Approximation (SAR) Conversion Resolution. */
148 typedef enum {
149   csenSARRes10 = _CSEN_CTRL_SARCR_CLK10, /**< 10-bit resolution. */
150   csenSARRes12 = _CSEN_CTRL_SARCR_CLK12, /**< 12-bit resolution. */
151   csenSARRes14 = _CSEN_CTRL_SARCR_CLK14, /**< 14-bit resolution. */
152   csenSARRes16 = _CSEN_CTRL_SARCR_CLK16, /**< 16-bit resolution. */
153 } CSEN_SARRes_TypeDef;
154 
155 /** Delta Modulator (DM) Conversion Resolution. */
156 typedef enum {
157   csenDMRes10 = _CSEN_DMCFG_CRMODE_DM10, /**< 10-bit resolution. */
158   csenDMRes12 = _CSEN_DMCFG_CRMODE_DM12, /**< 12-bit resolution. */
159   csenDMRes14 = _CSEN_DMCFG_CRMODE_DM14, /**< 14-bit resolution. */
160   csenDMRes16 = _CSEN_DMCFG_CRMODE_DM16, /**< 16-bit resolution. */
161 } CSEN_DMRes_TypeDef;
162 
163 /** Period counter clock pre-scaler. See the reference manual for source clock
164  *  information. */
165 typedef enum {
166   csenPCPrescaleDiv1   = _CSEN_TIMCTRL_PCPRESC_DIV1,   /**< Divide by 1. */
167   csenPCPrescaleDiv2   = _CSEN_TIMCTRL_PCPRESC_DIV2,   /**< Divide by 2. */
168   csenPCPrescaleDiv4   = _CSEN_TIMCTRL_PCPRESC_DIV4,   /**< Divide by 4. */
169   csenPCPrescaleDiv8   = _CSEN_TIMCTRL_PCPRESC_DIV8,   /**< Divide by 8. */
170   csenPCPrescaleDiv16  = _CSEN_TIMCTRL_PCPRESC_DIV16,  /**< Divide by 16. */
171   csenPCPrescaleDiv32  = _CSEN_TIMCTRL_PCPRESC_DIV32,  /**< Divide by 32. */
172   csenPCPrescaleDiv64  = _CSEN_TIMCTRL_PCPRESC_DIV64,  /**< Divide by 64. */
173   csenPCPrescaleDiv128 = _CSEN_TIMCTRL_PCPRESC_DIV128, /**< Divide by 128. */
174 } CSEN_PCPrescale_TypeDef;
175 
176 /** Exponential Moving Average sample weight. */
177 typedef enum {
178   csenEMASampleW1  = _CSEN_EMACTRL_EMASAMPLE_W1,  /**< Weight 1. */
179   csenEMASampleW2  = _CSEN_EMACTRL_EMASAMPLE_W2,  /**< Weight 2. */
180   csenEMASampleW4  = _CSEN_EMACTRL_EMASAMPLE_W4,  /**< Weight 4. */
181   csenEMASampleW8  = _CSEN_EMACTRL_EMASAMPLE_W8,  /**< Weight 8. */
182   csenEMASampleW16 = _CSEN_EMACTRL_EMASAMPLE_W16, /**< Weight 16. */
183   csenEMASampleW32 = _CSEN_EMACTRL_EMASAMPLE_W32, /**< Weight 32. */
184   csenEMASampleW64 = _CSEN_EMACTRL_EMASAMPLE_W64, /**< Weight 64. */
185 } CSEN_EMASample_TypeDef;
186 
187 /** Reset Phase Timing Select (units are microseconds). */
188 typedef enum {
189   csenResetPhaseSel0 = 0,  /**< Reset phase time = 0.75 usec. */
190   csenResetPhaseSel1 = 1,  /**< Reset phase time = 1.00 usec. */
191   csenResetPhaseSel2 = 2,  /**< Reset phase time = 1.20 usec. */
192   csenResetPhaseSel3 = 3,  /**< Reset phase time = 1.50 usec. */
193   csenResetPhaseSel4 = 4,  /**< Reset phase time = 2.00 usec. */
194   csenResetPhaseSel5 = 5,  /**< Reset phase time = 3.00 usec. */
195   csenResetPhaseSel6 = 6,  /**< Reset phase time = 6.00 usec. */
196   csenResetPhaseSel7 = 7,  /**< Reset phase time = 12.0 usec. */
197 } CSEN_ResetPhaseSel_TypeDef;
198 
199 /** Drive Strength Select. Scales the output current. */
200 typedef enum {
201   csenDriveSelFull = 0,  /**< Drive strength = fully on. */
202   csenDriveSel1 = 1,     /**< Drive strength = 1/8 full scale. */
203   csenDriveSel2 = 2,     /**< Drive strength = 1/4 full scale. */
204   csenDriveSel3 = 3,     /**< Drive strength = 3/8 full scale. */
205   csenDriveSel4 = 4,     /**< Drive strength = 1/2 full scale. */
206   csenDriveSel5 = 5,     /**< Drive strength = 5/8 full scale. */
207   csenDriveSel6 = 6,     /**< Drive strength = 3/4 full scale. */
208   csenDriveSel7 = 7,     /**< Drive strength = 7/8 full scale. */
209 } CSEN_DriveSel_TypeDef;
210 
211 /** Gain Select. See reference manual for information on each setting. */
212 typedef enum {
213   csenGainSel1X = 0,  /**< Gain = 1x. */
214   csenGainSel2X = 1,  /**< Gain = 2x. */
215   csenGainSel3X = 2,  /**< Gain = 3x. */
216   csenGainSel4X = 3,  /**< Gain = 4x. */
217   csenGainSel5X = 4,  /**< Gain = 5x. */
218   csenGainSel6X = 5,  /**< Gain = 6x. */
219   csenGainSel7X = 6,  /**< Gain = 7x. */
220   csenGainSel8X = 7,  /**< Gain = 8x. */
221 } CSEN_GainSel_TypeDef;
222 
223 /** Peripheral Reflex System signal used to trigger conversion. */
224 typedef enum {
225   csenPRSSELCh0  = _CSEN_PRSSEL_PRSSEL_PRSCH0,  /**< PRS channel 0. */
226   csenPRSSELCh1  = _CSEN_PRSSEL_PRSSEL_PRSCH1,  /**< PRS channel 1. */
227   csenPRSSELCh2  = _CSEN_PRSSEL_PRSSEL_PRSCH2,  /**< PRS channel 2. */
228   csenPRSSELCh3  = _CSEN_PRSSEL_PRSSEL_PRSCH3,  /**< PRS channel 3. */
229   csenPRSSELCh4  = _CSEN_PRSSEL_PRSSEL_PRSCH4,  /**< PRS channel 4. */
230   csenPRSSELCh5  = _CSEN_PRSSEL_PRSSEL_PRSCH5,  /**< PRS channel 5. */
231   csenPRSSELCh6  = _CSEN_PRSSEL_PRSSEL_PRSCH6,  /**< PRS channel 6. */
232   csenPRSSELCh7  = _CSEN_PRSSEL_PRSSEL_PRSCH7,  /**< PRS channel 7. */
233 #if defined(_CSEN_PRSSEL_PRSSEL_PRSCH8)
234   csenPRSSELCh8  = _CSEN_PRSSEL_PRSSEL_PRSCH8,  /**< PRS channel 8. */
235 #endif
236 #if defined(_CSEN_PRSSEL_PRSSEL_PRSCH9)
237   csenPRSSELCh9  = _CSEN_PRSSEL_PRSSEL_PRSCH9,  /**< PRS channel 9. */
238 #endif
239 #if defined(_CSEN_PRSSEL_PRSSEL_PRSCH10)
240   csenPRSSELCh10 = _CSEN_PRSSEL_PRSSEL_PRSCH10, /**< PRS channel 10. */
241 #endif
242 #if defined(_CSEN_PRSSEL_PRSSEL_PRSCH11)
243   csenPRSSELCh11 = _CSEN_PRSSEL_PRSSEL_PRSCH11, /**< PRS channel 11. */
244 #endif
245 } CSEN_PRSSel_TypeDef;
246 
247 /** APORT channel to CSEN input selection. */
248 typedef enum {
249   csenInputSelDefault        = _CSEN_SCANINPUTSEL0_INPUT0TO7SEL_DEFAULT,
250   csenInputSelAPORT1CH0TO7   = _CSEN_SCANINPUTSEL0_INPUT0TO7SEL_APORT1CH0TO7,
251   csenInputSelAPORT1CH8TO15  = _CSEN_SCANINPUTSEL0_INPUT0TO7SEL_APORT1CH8TO15,
252   csenInputSelAPORT1CH16TO23 = _CSEN_SCANINPUTSEL0_INPUT0TO7SEL_APORT1CH16TO23,
253   csenInputSelAPORT1CH24TO31 = _CSEN_SCANINPUTSEL0_INPUT0TO7SEL_APORT1CH24TO31,
254   csenInputSelAPORT3CH0TO7   = _CSEN_SCANINPUTSEL0_INPUT0TO7SEL_APORT3CH0TO7,
255   csenInputSelAPORT3CH8TO15  = _CSEN_SCANINPUTSEL0_INPUT0TO7SEL_APORT3CH8TO15,
256   csenInputSelAPORT3CH16TO23 = _CSEN_SCANINPUTSEL0_INPUT0TO7SEL_APORT3CH16TO23,
257   csenInputSelAPORT3CH24TO31 = _CSEN_SCANINPUTSEL0_INPUT0TO7SEL_APORT3CH24TO31,
258 } CSEN_InputSel_TypeDef;
259 
260 /** APORT channel to CSEN single input selection. */
261 typedef enum {
262   csenSingleSelDefault     = _CSEN_SINGLECTRL_SINGLESEL_DEFAULT,
263   csenSingleSelAPORT1XCH0  = _CSEN_SINGLECTRL_SINGLESEL_APORT1XCH0,
264   csenSingleSelAPORT1YCH1  = _CSEN_SINGLECTRL_SINGLESEL_APORT1YCH1,
265   csenSingleSelAPORT1XCH2  = _CSEN_SINGLECTRL_SINGLESEL_APORT1XCH2,
266   csenSingleSelAPORT1YCH3  = _CSEN_SINGLECTRL_SINGLESEL_APORT1YCH3,
267   csenSingleSelAPORT1XCH4  = _CSEN_SINGLECTRL_SINGLESEL_APORT1XCH4,
268   csenSingleSelAPORT1YCH5  = _CSEN_SINGLECTRL_SINGLESEL_APORT1YCH5,
269   csenSingleSelAPORT1XCH6  = _CSEN_SINGLECTRL_SINGLESEL_APORT1XCH6,
270   csenSingleSelAPORT1YCH7  = _CSEN_SINGLECTRL_SINGLESEL_APORT1YCH7,
271   csenSingleSelAPORT1XCH8  = _CSEN_SINGLECTRL_SINGLESEL_APORT1XCH8,
272   csenSingleSelAPORT1YCH9  = _CSEN_SINGLECTRL_SINGLESEL_APORT1YCH9,
273   csenSingleSelAPORT1XCH10 = _CSEN_SINGLECTRL_SINGLESEL_APORT1XCH10,
274   csenSingleSelAPORT1YCH11 = _CSEN_SINGLECTRL_SINGLESEL_APORT1YCH11,
275   csenSingleSelAPORT1XCH12 = _CSEN_SINGLECTRL_SINGLESEL_APORT1XCH12,
276   csenSingleSelAPORT1YCH13 = _CSEN_SINGLECTRL_SINGLESEL_APORT1YCH13,
277   csenSingleSelAPORT1XCH14 = _CSEN_SINGLECTRL_SINGLESEL_APORT1XCH14,
278   csenSingleSelAPORT1YCH15 = _CSEN_SINGLECTRL_SINGLESEL_APORT1YCH15,
279   csenSingleSelAPORT1XCH16 = _CSEN_SINGLECTRL_SINGLESEL_APORT1XCH16,
280   csenSingleSelAPORT1YCH17 = _CSEN_SINGLECTRL_SINGLESEL_APORT1YCH17,
281   csenSingleSelAPORT1XCH18 = _CSEN_SINGLECTRL_SINGLESEL_APORT1XCH18,
282   csenSingleSelAPORT1YCH19 = _CSEN_SINGLECTRL_SINGLESEL_APORT1YCH19,
283   csenSingleSelAPORT1XCH20 = _CSEN_SINGLECTRL_SINGLESEL_APORT1XCH20,
284   csenSingleSelAPORT1YCH21 = _CSEN_SINGLECTRL_SINGLESEL_APORT1YCH21,
285   csenSingleSelAPORT1XCH22 = _CSEN_SINGLECTRL_SINGLESEL_APORT1XCH22,
286   csenSingleSelAPORT1YCH23 = _CSEN_SINGLECTRL_SINGLESEL_APORT1YCH23,
287   csenSingleSelAPORT1XCH24 = _CSEN_SINGLECTRL_SINGLESEL_APORT1XCH24,
288   csenSingleSelAPORT1YCH25 = _CSEN_SINGLECTRL_SINGLESEL_APORT1YCH25,
289   csenSingleSelAPORT1XCH26 = _CSEN_SINGLECTRL_SINGLESEL_APORT1XCH26,
290   csenSingleSelAPORT1YCH27 = _CSEN_SINGLECTRL_SINGLESEL_APORT1YCH27,
291   csenSingleSelAPORT1XCH28 = _CSEN_SINGLECTRL_SINGLESEL_APORT1XCH28,
292   csenSingleSelAPORT1YCH29 = _CSEN_SINGLECTRL_SINGLESEL_APORT1YCH29,
293   csenSingleSelAPORT1XCH30 = _CSEN_SINGLECTRL_SINGLESEL_APORT1XCH30,
294   csenSingleSelAPORT1YCH31 = _CSEN_SINGLECTRL_SINGLESEL_APORT1YCH31,
295   csenSingleSelAPORT3XCH0  = _CSEN_SINGLECTRL_SINGLESEL_APORT3XCH0,
296   csenSingleSelAPORT3YCH1  = _CSEN_SINGLECTRL_SINGLESEL_APORT3YCH1,
297   csenSingleSelAPORT3XCH2  = _CSEN_SINGLECTRL_SINGLESEL_APORT3XCH2,
298   csenSingleSelAPORT3YCH3  = _CSEN_SINGLECTRL_SINGLESEL_APORT3YCH3,
299   csenSingleSelAPORT3XCH4  = _CSEN_SINGLECTRL_SINGLESEL_APORT3XCH4,
300   csenSingleSelAPORT3YCH5  = _CSEN_SINGLECTRL_SINGLESEL_APORT3YCH5,
301   csenSingleSelAPORT3XCH6  = _CSEN_SINGLECTRL_SINGLESEL_APORT3XCH6,
302   csenSingleSelAPORT3YCH7  = _CSEN_SINGLECTRL_SINGLESEL_APORT3YCH7,
303   csenSingleSelAPORT3XCH8  = _CSEN_SINGLECTRL_SINGLESEL_APORT3XCH8,
304   csenSingleSelAPORT3YCH9  = _CSEN_SINGLECTRL_SINGLESEL_APORT3YCH9,
305   csenSingleSelAPORT3XCH10 = _CSEN_SINGLECTRL_SINGLESEL_APORT3XCH10,
306   csenSingleSelAPORT3YCH11 = _CSEN_SINGLECTRL_SINGLESEL_APORT3YCH11,
307   csenSingleSelAPORT3XCH12 = _CSEN_SINGLECTRL_SINGLESEL_APORT3XCH12,
308   csenSingleSelAPORT3YCH13 = _CSEN_SINGLECTRL_SINGLESEL_APORT3YCH13,
309   csenSingleSelAPORT3XCH14 = _CSEN_SINGLECTRL_SINGLESEL_APORT3XCH14,
310   csenSingleSelAPORT3YCH15 = _CSEN_SINGLECTRL_SINGLESEL_APORT3YCH15,
311   csenSingleSelAPORT3XCH16 = _CSEN_SINGLECTRL_SINGLESEL_APORT3XCH16,
312   csenSingleSelAPORT3YCH17 = _CSEN_SINGLECTRL_SINGLESEL_APORT3YCH17,
313   csenSingleSelAPORT3XCH18 = _CSEN_SINGLECTRL_SINGLESEL_APORT3XCH18,
314   csenSingleSelAPORT3YCH19 = _CSEN_SINGLECTRL_SINGLESEL_APORT3YCH19,
315   csenSingleSelAPORT3XCH20 = _CSEN_SINGLECTRL_SINGLESEL_APORT3XCH20,
316   csenSingleSelAPORT3YCH21 = _CSEN_SINGLECTRL_SINGLESEL_APORT3YCH21,
317   csenSingleSelAPORT3XCH22 = _CSEN_SINGLECTRL_SINGLESEL_APORT3XCH22,
318   csenSingleSelAPORT3YCH23 = _CSEN_SINGLECTRL_SINGLESEL_APORT3YCH23,
319   csenSingleSelAPORT3XCH24 = _CSEN_SINGLECTRL_SINGLESEL_APORT3XCH24,
320   csenSingleSelAPORT3YCH25 = _CSEN_SINGLECTRL_SINGLESEL_APORT3YCH25,
321   csenSingleSelAPORT3XCH26 = _CSEN_SINGLECTRL_SINGLESEL_APORT3XCH26,
322   csenSingleSelAPORT3YCH27 = _CSEN_SINGLECTRL_SINGLESEL_APORT3YCH27,
323   csenSingleSelAPORT3XCH28 = _CSEN_SINGLECTRL_SINGLESEL_APORT3XCH28,
324   csenSingleSelAPORT3YCH29 = _CSEN_SINGLECTRL_SINGLESEL_APORT3YCH29,
325   csenSingleSelAPORT3XCH30 = _CSEN_SINGLECTRL_SINGLESEL_APORT3XCH30,
326   csenSingleSelAPORT3YCH31 = _CSEN_SINGLECTRL_SINGLESEL_APORT3YCH31,
327 } CSEN_SingleSel_TypeDef;
328 
329 /*******************************************************************************
330  *******************************   STRUCTS   ***********************************
331  ******************************************************************************/
332 
333 /** CSEN initialization structure, common for all measurement modes. */
334 typedef struct {
335   /** Requests system charge pump high accuracy mode. */
336   bool                          cpAccuracyHi;
337 
338   /** Disables external kelvin connection and senses capacitor locally. */
339   bool                          localSense;
340 
341   /** Keeps the converter warm allowing continuous conversions. */
342   bool                          keepWarm;
343 
344   /** Converter warm-up time is warmUpCount + 3 converter clock cycles. */
345   uint8_t                       warmUpCount;
346 
347   /** Period counter reload value. */
348   uint8_t                       pcReload;
349 
350   /** Period counter pre-scaler. */
351   CSEN_PCPrescale_TypeDef       pcPrescale;
352 
353   /** Peripheral reflex system trigger selection. */
354   CSEN_PRSSel_TypeDef           prsSel;
355 
356   /** CSEN input to APORT channel mapping. */
357   CSEN_InputSel_TypeDef         input0To7;   /** CSEN input select 0-7. */
358   CSEN_InputSel_TypeDef         input8To15;  /** CSEN input select 8-15. */
359   CSEN_InputSel_TypeDef         input16To23; /** CSEN input select 6-23. */
360   CSEN_InputSel_TypeDef         input24To31; /** CSEN input select 24-31. */
361   CSEN_InputSel_TypeDef         input32To39; /** CSEN input select 32-39. */
362   CSEN_InputSel_TypeDef         input40To47; /** CSEN input select 40-47. */
363   CSEN_InputSel_TypeDef         input48To55; /** CSEN input select 48-55. */
364   CSEN_InputSel_TypeDef         input56To63; /** CSEN input select 56-63. */
365 } CSEN_Init_TypeDef;
366 
367 /** CSEN default initialization. */
368 #define CSEN_INIT_DEFAULT                                             \
369   {                                                                   \
370     false,                      /* Charge pump low accuracy mode. */  \
371     false,                      /* Use external kelvin connection. */ \
372     false,                      /* Disable keep warm. */              \
373     0,                          /* 0+3 cycle warm-up time. */         \
374     0,                          /* Period counter reload. */          \
375     csenPCPrescaleDiv1,         /* Period counter prescale. */        \
376     csenPRSSELCh0,              /* PRS channel 0. */                  \
377     csenInputSelAPORT1CH0TO7,   /* input0To7   -> aport1ch0to7 */     \
378     csenInputSelAPORT1CH8TO15,  /* input8To15  -> aport1ch8to15 */    \
379     csenInputSelAPORT1CH16TO23, /* input16To23 -> aport1ch16to23 */   \
380     csenInputSelAPORT1CH24TO31, /* input24To31 -> aport1ch24to31 */   \
381     csenInputSelAPORT3CH0TO7,   /* input32To39 -> aport3ch0to7 */     \
382     csenInputSelAPORT3CH8TO15,  /* input40To47 -> aport3ch8to15 */    \
383     csenInputSelAPORT3CH16TO23, /* input48To55 -> aport3ch16to23 */   \
384     csenInputSelAPORT3CH24TO31, /* input56To63 -> aport3ch24to31 */   \
385   }
386 
387 /** Measurement mode initialization structure. */
388 typedef struct {
389   /** Selects the conversion sample mode. */
390   CSEN_SampleMode_TypeDef       sampleMode;
391 
392   /** Selects the conversion trigger source. */
393   CSEN_TrigSel_TypeDef          trigSel;
394 
395   /** Enables DMA operation. */
396   bool                          enableDma;
397 
398   /** Disables dividing the accumulated result. */
399   bool                          sumOnly;
400 
401   /** Selects the number of samples to accumulate per conversion. */
402   CSEN_AccMode_TypeDef          accMode;
403 
404   /** Selects the Exponential Moving Average sample weighting. */
405   CSEN_EMASample_TypeDef        emaSample;
406 
407   /** Enables the comparator and selects the comparison type. */
408   CSEN_CmpMode_TypeDef          cmpMode;
409 
410   /** Comparator threshold value. Meaning depends on @p cmpMode. */
411   uint16_t                      cmpThr;
412 
413   /** Selects an APORT channel for a single conversion. */
414   CSEN_SingleSel_TypeDef        singleSel;
415 
416   /**
417    * Mask selects inputs 0 to 31. Effect depends on @p sampleMode. If sample
418    * mode is bonded, then mask selects inputs to short together. If sample
419    * mode is scan, then mask selects which inputs will be scanned. If sample
420    * mode is single and auto-ground is on (@p autoGnd is true), mask selects
421    * which pins are grounded.
422    */
423   uint32_t                      inputMask0;
424 
425   /** Mask selects inputs 32 to 63. See @p inputMask0 for more information. */
426   uint32_t                      inputMask1;
427 
428   /** Ground inactive inputs during a conversion. */
429   bool                          autoGnd;
430 
431   /** Selects the converter type. */
432   CSEN_ConvSel_TypeDef          convSel;
433 
434   /** Selects the Successive Approximation (SAR) converter resolution. */
435   CSEN_SARRes_TypeDef           sarRes;
436 
437   /** Selects the Delta Modulation (DM) converter resolution. */
438   CSEN_DMRes_TypeDef            dmRes;
439 
440   /** Sets the number of DM iterations (comparisons) per cycle. Only applies
441    *  to the Delta Modulation converter. */
442   uint8_t                       dmIterPerCycle;
443 
444   /** Sets number of DM converter cycles. Only applies to the
445    *  Delta Modulation converter. */
446   uint8_t                       dmCycles;
447 
448   /** Sets the DM converter initial delta value. Only applies to the
449    *  Delta Modulation converter. */
450   uint8_t                       dmDelta;
451 
452   /** Disables DM automatic delta size reduction per cycle. Only applies to the
453    *  Delta Modulation converter. */
454   bool                          dmFixedDelta;
455 
456   /** Selects the reset phase timing. Most measurements should use the default
457    *  value. See reference manual for details on when to adjust. */
458   CSEN_ResetPhaseSel_TypeDef    resetPhase;
459 
460   /** Selects the output drive strength.  Most measurements should use the
461   *  default value. See reference manual for details on when to adjust. */
462   CSEN_DriveSel_TypeDef         driveSel;
463 
464   /** Selects the converter gain. */
465   CSEN_GainSel_TypeDef          gainSel;
466 } CSEN_InitMode_TypeDef;
467 
468 /** CSEN default mode initialization. */
469 #define CSEN_INITMODE_DEFAULT                                          \
470   {                                                                    \
471     csenSampleModeSingle,       /* Sample one input and stop. */       \
472     csenTrigSelStart,           /* Use start bit to trigger. */        \
473     false,                      /* Disable DMA. */                     \
474     false,                      /* Average the accumulated result. */  \
475     csenAccMode1,               /* Accumulate 1 sample. */             \
476     csenEMASampleW1,            /* Disable the EMA. */                 \
477     csenCmpModeDisabled,        /* Disable the comparator. */          \
478     0,                          /* Comparator threshold not used. */   \
479     csenSingleSelDefault,       /* Disconnect the single input. */     \
480     0,                          /* Disable inputs 0 to 31. */          \
481     0,                          /* Disable inputs 32 to 63. */         \
482     false,                      /* Do not ground inactive inputs. */   \
483     csenConvSelSAR,             /* Use the SAR converter. */           \
484     csenSARRes10,               /* Set SAR resolution to 10 bits. */   \
485     csenDMRes10,                /* Set DM resolution to 10 bits. */    \
486     0,                          /* Set DM conv/cycle to default. */    \
487     0,                          /* Set DM cycles to default. */        \
488     0,                          /* Set DM initial delta to default. */ \
489     false,                      /* Use DM auto delta reduction. */     \
490     csenResetPhaseSel0,         /* Use shortest reset phase time. */   \
491     csenDriveSelFull,           /* Use full output current. */         \
492     csenGainSel8X,              /* Use highest converter gain. */      \
493   }
494 
495 /*******************************************************************************
496  *****************************   PROTOTYPES   **********************************
497  ******************************************************************************/
498 
499 /***************************************************************************//**
500  * @brief
501  *   Get the last conversion result.
502  *
503  * @note
504  *   Check the conversion busy flag before calling this function. In addition,
505  *   the result width and format depend on the parameters passed to the
506  *   @ref CSEN_InitMode() function.
507  *
508  * @param[in] csen
509  *   Pointer to a CSEN peripheral register block.
510  *
511  * @return
512  *   Result data from last conversion.
513  ******************************************************************************/
CSEN_DataGet(CSEN_TypeDef * csen)514 __STATIC_INLINE uint32_t CSEN_DataGet(CSEN_TypeDef *csen)
515 {
516   return csen->DATA;
517 }
518 
519 /***************************************************************************//**
520  * @brief
521  *   Get the last exponential moving average.
522  *
523  * @note
524  *   Confirm that CSEN is idle before calling this function.
525  *
526  * @param[in] csen
527  *   Pointer to a CSEN peripheral register block.
528  *
529  * @return
530  *   Exponential moving average from last conversion.
531  ******************************************************************************/
CSEN_EMAGet(CSEN_TypeDef * csen)532 __STATIC_INLINE uint32_t CSEN_EMAGet(CSEN_TypeDef *csen)
533 {
534   return (csen->EMA & _CSEN_EMA_EMA_MASK);
535 }
536 
537 /***************************************************************************//**
538  * @brief
539  *   Set the exponential moving average initial value.
540  *
541  * @note
542  *   Call this function before starting a conversion.
543  *
544  * @param[in] csen
545  *   Pointer to a CSEN peripheral register block.
546  *
547  * @param[in] ema
548  *   Initial value for the exponential moving average.
549  ******************************************************************************/
CSEN_EMASet(CSEN_TypeDef * csen,uint32_t ema)550 __STATIC_INLINE void CSEN_EMASet(CSEN_TypeDef *csen, uint32_t ema)
551 {
552   csen->EMA = ema & _CSEN_EMA_EMA_MASK;
553 }
554 
555 /***************************************************************************//**
556  * @brief
557  *   Disable CSEN.
558  *
559  * @param[in] csen
560  *   Pointer to a CSEN peripheral register block.
561  ******************************************************************************/
CSEN_Disable(CSEN_TypeDef * csen)562 __STATIC_INLINE void CSEN_Disable(CSEN_TypeDef *csen)
563 {
564   BUS_RegBitWrite(&csen->CTRL, _CSEN_CTRL_EN_SHIFT, 0);
565 }
566 
567 /***************************************************************************//**
568  * @brief
569  *   Enable CSEN.
570  *
571  * @param[in] csen
572  *   Pointer to a CSEN peripheral register block.
573  ******************************************************************************/
CSEN_Enable(CSEN_TypeDef * csen)574 __STATIC_INLINE void CSEN_Enable(CSEN_TypeDef *csen)
575 {
576   BUS_RegBitWrite(&csen->CTRL, _CSEN_CTRL_EN_SHIFT, 1);
577 }
578 
579 void CSEN_DMBaselineSet(CSEN_TypeDef *csen, uint32_t up, uint32_t down);
580 void CSEN_Init(CSEN_TypeDef *csen, const CSEN_Init_TypeDef *init);
581 void CSEN_InitMode(CSEN_TypeDef *csen, const CSEN_InitMode_TypeDef *init);
582 void CSEN_Reset(CSEN_TypeDef *csen);
583 
584 /***************************************************************************//**
585  * @brief
586  *   Clear one or more pending CSEN interrupts.
587  *
588  * @param[in] csen
589  *   Pointer to a CSEN peripheral register block.
590  *
591  * @param[in] flags
592  *   Pending CSEN interrupt source to clear. Use a bitwise logic OR combination
593  *   of valid interrupt flags for the CSEN module (CSEN_IF_nnn).
594  ******************************************************************************/
CSEN_IntClear(CSEN_TypeDef * csen,uint32_t flags)595 __STATIC_INLINE void CSEN_IntClear(CSEN_TypeDef *csen, uint32_t flags)
596 {
597   csen->IFC = flags;
598 }
599 
600 /***************************************************************************//**
601  * @brief
602  *   Disable one or more CSEN interrupts.
603  *
604  * @param[in] csen
605  *   Pointer to a CSEN peripheral register block.
606  *
607  * @param[in] flags
608  *   CSEN interrupt sources to disable. Use a bitwise logic OR combination of
609  *   valid interrupt flags for the CSEN module (CSEN_IF_nnn).
610  ******************************************************************************/
CSEN_IntDisable(CSEN_TypeDef * csen,uint32_t flags)611 __STATIC_INLINE void CSEN_IntDisable(CSEN_TypeDef *csen, uint32_t flags)
612 {
613   csen->IEN &= ~flags;
614 }
615 
616 /***************************************************************************//**
617  * @brief
618  *   Enable one or more CSEN interrupts.
619  *
620  * @note
621  *   Depending on the use case, a pending interrupt may already be set prior to
622  *   enabling the interrupt. Consider using CSEN_IntClear() prior to enabling
623  *   if such a pending interrupt should be ignored.
624  *
625  * @param[in] csen
626  *   Pointer to a CSEN peripheral register block.
627  *
628  * @param[in] flags
629  *   CSEN interrupt sources to enable. Use a bitwise logic OR combination of
630  *   valid interrupt flags for the CSEN module (CSEN_IF_nnn).
631  ******************************************************************************/
CSEN_IntEnable(CSEN_TypeDef * csen,uint32_t flags)632 __STATIC_INLINE void CSEN_IntEnable(CSEN_TypeDef *csen, uint32_t flags)
633 {
634   csen->IEN |= flags;
635 }
636 
637 /***************************************************************************//**
638  * @brief
639  *   Get pending CSEN interrupt flags.
640  *
641  * @note
642  *   The event bits are not cleared by the use of this function.
643  *
644  * @param[in] csen
645  *   Pointer to a CSEN peripheral register block.
646  *
647  * @return
648  *   CSEN interrupt sources pending. A bitwise logic OR combination of valid
649  *   interrupt flags for the CSEN module (CSEN_IF_nnn).
650  ******************************************************************************/
CSEN_IntGet(CSEN_TypeDef * csen)651 __STATIC_INLINE uint32_t CSEN_IntGet(CSEN_TypeDef *csen)
652 {
653   return csen->IF;
654 }
655 
656 /***************************************************************************//**
657  * @brief
658  *   Get enabled and pending CSEN interrupt flags.
659  *   Useful for handling more interrupt sources in the same interrupt handler.
660  *
661  * @param[in] csen
662  *   Pointer to a CSEN peripheral register block.
663  *
664  * @note
665  *   Interrupt flags are not cleared by the use of this function.
666  *
667  * @return
668  *   Pending and enabled CSEN interrupt sources.
669  *   The return value is the bitwise AND combination of
670  *   - the OR combination of enabled interrupt sources in CSENx_IEN_nnn
671  *     register (CSENx_IEN_nnn) and
672  *   - the OR combination of valid interrupt flags of the CSEN module
673  *     (CSENx_IF_nnn).
674  ******************************************************************************/
CSEN_IntGetEnabled(CSEN_TypeDef * csen)675 __STATIC_INLINE uint32_t CSEN_IntGetEnabled(CSEN_TypeDef *csen)
676 {
677   uint32_t ien;
678 
679   /* Store CSENx->IEN in temporary variable to define explicit order
680    * of volatile accesses. */
681   ien = csen->IEN;
682 
683   /* Bitwise AND of pending and enabled interrupts */
684   return csen->IF & ien;
685 }
686 
687 /***************************************************************************//**
688  * @brief
689  *   Set one or more pending CSEN interrupts from SW.
690  *
691  * @param[in] csen
692  *   Pointer to a CSEN peripheral register block.
693  *
694  * @param[in] flags
695  *   CSEN interrupt sources to set to pending. Use a bitwise logic OR combination
696  *   of valid interrupt flags for the CSEN module (CSEN_IF_nnn).
697  ******************************************************************************/
CSEN_IntSet(CSEN_TypeDef * csen,uint32_t flags)698 __STATIC_INLINE void CSEN_IntSet(CSEN_TypeDef *csen, uint32_t flags)
699 {
700   csen->IFS = flags;
701 }
702 
703 /***************************************************************************//**
704  * @brief
705  *   Return CSEN conversion busy status.
706  *
707  * @param[in] csen
708  *   Pointer to a CSEN peripheral register block.
709  *
710  * @return
711  *   True if CSEN conversion is in progress.
712  ******************************************************************************/
CSEN_IsBusy(CSEN_TypeDef * csen)713 __STATIC_INLINE bool CSEN_IsBusy(CSEN_TypeDef *csen)
714 {
715   return (bool)(csen->STATUS & _CSEN_STATUS_CSENBUSY_MASK);
716 }
717 
718 /***************************************************************************//**
719  * @brief
720  *   Start a scan sequence and/or a single conversion.
721  *
722  * @param[in] csen
723  *   Pointer to a CSEN peripheral register block.
724  ******************************************************************************/
CSEN_Start(CSEN_TypeDef * csen)725 __STATIC_INLINE void CSEN_Start(CSEN_TypeDef *csen)
726 {
727   csen->CMD = CSEN_CMD_START;
728 }
729 
730 /** @} (end addtogroup CSEN) */
731 
732 #ifdef __cplusplus
733 }
734 #endif
735 
736 #endif /* defined(CSEN_COUNT) && (CSEN_COUNT > 0) */
737 #endif /* EM_CSEN_H */
738