1 /*
2  * Copyright (c) 2016, Freescale Semiconductor, Inc.
3  * All rights reserved.
4  *
5  *
6  * SPDX-License-Identifier: BSD-3-Clause
7  */
8 
9 #include "fsl_lpcmp.h"
10 
11 /*******************************************************************************
12  * Prototypes
13  ******************************************************************************/
14 #if defined(LPCMP_CLOCKS)
15 /*!
16  * @brief Get instance number for LPCMP module.
17  *
18  * @param base LPCMP peripheral base address
19  */
20 static uint32_t LPCMP_GetInstance(LPCMP_Type *base);
21 #endif /* LPCMP_CLOCKS */
22 
23 /*******************************************************************************
24  * Variables
25  ******************************************************************************/
26 #if defined(LPCMP_CLOCKS)
27 /*! @brief Pointers to LPCMP bases for each instance. */
28 static LPCMP_Type *const s_lpcmpBases[] = LPCMP_BASE_PTRS;
29 /*! @brief Pointers to LPCMP clocks for each instance. */
30 static const clock_ip_name_t s_lpcmpClocks[] = LPCMP_CLOCKS;
31 #endif /* LPCMP_CLOCKS */
32 
33 /*******************************************************************************
34  * Codes
35  ******************************************************************************/
36 #if defined(LPCMP_CLOCKS)
LPCMP_GetInstance(LPCMP_Type * base)37 static uint32_t LPCMP_GetInstance(LPCMP_Type *base)
38 {
39     uint32_t instance;
40 
41     /* Find the instance index from base address mappings. */
42     for (instance = 0; instance < ARRAY_SIZE(s_lpcmpBases); instance++)
43     {
44         if (s_lpcmpBases[instance] == base)
45         {
46             break;
47         }
48     }
49 
50     assert(instance < ARRAY_SIZE(s_lpcmpBases));
51 
52     return instance;
53 }
54 #endif /* LPCMP_CLOCKS */
55 
LPCMP_Init(LPCMP_Type * base,const lpcmp_config_t * config)56 void LPCMP_Init(LPCMP_Type *base, const lpcmp_config_t *config)
57 {
58     assert(config != NULL);
59 
60     uint32_t tmp32;
61 
62 #if defined(LPCMP_CLOCKS)
63     /* Enable LPCMP clock. */
64     CLOCK_EnableClock(s_lpcmpClocks[LPCMP_GetInstance(base)]);
65 #endif /* LPCMP_CLOCKS */
66 
67     /* Configure. */
68     LPCMP_Enable(base, false);
69     /* CCR0 register. */
70     if (config->enableStopMode)
71     {
72         base->CCR0 |= LPCMP_CCR0_CMP_STOP_EN_MASK;
73     }
74     else
75     {
76         base->CCR0 &= ~LPCMP_CCR0_CMP_STOP_EN_MASK;
77     }
78     /* CCR1 register. */
79     tmp32 = base->CCR1 & ~(LPCMP_CCR1_COUT_PEN_MASK | LPCMP_CCR1_COUT_SEL_MASK | LPCMP_CCR1_COUT_INV_MASK);
80     if (config->enableOutputPin)
81     {
82         tmp32 |= LPCMP_CCR1_COUT_PEN_MASK;
83     }
84     if (config->useUnfilteredOutput)
85     {
86         tmp32 |= LPCMP_CCR1_COUT_SEL_MASK;
87     }
88     if (config->enableInvertOutput)
89     {
90         tmp32 |= LPCMP_CCR1_COUT_INV_MASK;
91     }
92     base->CCR1 = tmp32;
93     /* CCR2 register. */
94     tmp32 = base->CCR2 & ~(LPCMP_CCR2_HYSTCTR_MASK | LPCMP_CCR2_CMP_NPMD_MASK | LPCMP_CCR2_CMP_HPMD_MASK);
95     tmp32 |= LPCMP_CCR2_HYSTCTR(config->hysteresisMode);
96     tmp32 |= ((uint32_t)(config->powerMode) << LPCMP_CCR2_CMP_HPMD_SHIFT);
97     base->CCR2 = tmp32;
98 
99     LPCMP_Enable(base, true); /* Enable the LPCMP module. */
100 }
101 
LPCMP_Deinit(LPCMP_Type * base)102 void LPCMP_Deinit(LPCMP_Type *base)
103 {
104     /* Disable the LPCMP module. */
105     LPCMP_Enable(base, false);
106 #if defined(LPCMP_CLOCKS)
107     /* Disable the clock for LPCMP. */
108     CLOCK_DisableClock(s_lpcmpClocks[LPCMP_GetInstance(base)]);
109 #endif /* LPCMP_CLOCKS */
110 }
111 
LPCMP_GetDefaultConfig(lpcmp_config_t * config)112 void LPCMP_GetDefaultConfig(lpcmp_config_t *config)
113 {
114     config->enableStopMode = false;
115     config->enableOutputPin = false;
116     config->useUnfilteredOutput = false;
117     config->enableInvertOutput = false;
118     config->hysteresisMode = kLPCMP_HysteresisLevel0;
119     config->powerMode = kLPCMP_LowSpeedPowerMode;
120 }
121 
LPCMP_SetInputChannels(LPCMP_Type * base,uint32_t positiveChannel,uint32_t negativeChannel)122 void LPCMP_SetInputChannels(LPCMP_Type *base, uint32_t positiveChannel, uint32_t negativeChannel)
123 {
124     uint32_t tmp32;
125 
126     tmp32 = base->CCR2 & ~(LPCMP_CCR2_PSEL_MASK | LPCMP_CCR2_MSEL_MASK);
127     tmp32 |= LPCMP_CCR2_PSEL(positiveChannel) | LPCMP_CCR2_MSEL(negativeChannel);
128     base->CCR2 = tmp32;
129 }
130 
LPCMP_SetFilterConfig(LPCMP_Type * base,const lpcmp_filter_config_t * config)131 void LPCMP_SetFilterConfig(LPCMP_Type *base, const lpcmp_filter_config_t *config)
132 {
133     assert(config != NULL);
134 
135     uint32_t tmp32;
136 
137     tmp32 = base->CCR1 & ~(LPCMP_CCR1_FILT_PER_MASK | LPCMP_CCR1_FILT_CNT_MASK | LPCMP_CCR1_SAMPLE_EN_MASK);
138     if (config->enableSample)
139     {
140         tmp32 |= LPCMP_CCR1_SAMPLE_EN_MASK;
141     }
142     tmp32 |= LPCMP_CCR1_FILT_PER(config->filterSamplePeriod) | LPCMP_CCR1_FILT_CNT(config->filterSampleCount);
143     base->CCR1 = tmp32;
144 }
145 
LPCMP_SetDACConfig(LPCMP_Type * base,const lpcmp_dac_config_t * config)146 void LPCMP_SetDACConfig(LPCMP_Type *base, const lpcmp_dac_config_t *config)
147 {
148     uint32_t tmp32;
149     if (config == NULL)
150     {
151         tmp32 = 0U; /* Disable internal DAC. */
152     }
153     else
154     {
155         tmp32 = LPCMP_DCR_VRSEL(config->referenceVoltageSource) | LPCMP_DCR_DAC_DATA(config->DACValue);
156         if (config->enableLowPowerMode)
157         {
158             tmp32 |= LPCMP_DCR_DAC_HPMD_MASK;
159         }
160         tmp32 |= LPCMP_DCR_DAC_EN_MASK;
161     }
162     base->DCR = tmp32;
163 }
164