1 /*
2  * Copyright (c) 2015, Freescale Semiconductor, Inc.
3  * Copyright 2016-2017 NXP
4  * All rights reserved.
5  *
6  * SPDX-License-Identifier: BSD-3-Clause
7  */
8 
9 #include "fsl_lpit.h"
10 
11 /*******************************************************************************
12 * Variables
13 ******************************************************************************/
14 
15 /*! @brief Array to map LPIT instance number to base pointer. */
16 static LPIT_Type* const s_lpitBases[] = LPIT_BASE_PTRS;
17 
18 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
19 /*! @brief Clock array name */
20 static const clock_ip_name_t s_lpitClock[] = LPIT_CLOCKS;
21 
22 #if defined(LPIT_PERIPH_CLOCKS)
23 /* Array of LPIT functional clock name. */
24 static const clock_ip_name_t s_lpitPeriphClocks[] = LPIT_PERIPH_CLOCKS;
25 #endif
26 
27 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
28 
29 /*******************************************************************************
30  * Prototypes
31  ******************************************************************************/
32 
33 /*!
34  * @brief Get the instance for LPIT module.
35  *
36  * @param base LPIT base address
37  */
38 uint32_t LPIT_GetInstance(LPIT_Type* base);
39 
40 /*******************************************************************************
41  * Code
42  ******************************************************************************/
43 
LPIT_GetInstance(LPIT_Type * base)44 uint32_t LPIT_GetInstance(LPIT_Type* base)
45 {
46     uint32_t instance;
47 
48     /* Find the instance index from base address mappings. */
49     for (instance = 0; instance < ARRAY_SIZE(s_lpitBases); instance++)
50     {
51         if (s_lpitBases[instance] == base)
52         {
53             break;
54         }
55     }
56 
57     assert(instance < ARRAY_SIZE(s_lpitBases));
58 
59     return instance;
60 }
61 
LPIT_Init(LPIT_Type * base,const lpit_config_t * config)62 void LPIT_Init(LPIT_Type* base, const lpit_config_t* config)
63 {
64     assert(config);
65 
66 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
67 
68     uint32_t instance = LPIT_GetInstance(base);
69 
70     /* Enable the clock */
71     CLOCK_EnableClock(s_lpitClock[instance]);
72 #if defined(LPIT_PERIPH_CLOCKS)
73     CLOCK_EnableClock(s_lpitPeriphClocks[instance]);
74 #endif
75 
76 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
77 
78     /* Reset the timer channels and registers except the MCR register */
79     LPIT_Reset(base);
80 
81     /* Setup timer operation in debug and doze modes and enable the module */
82     base->MCR =
83         (LPIT_MCR_DBG_EN(config->enableRunInDebug) | LPIT_MCR_DOZE_EN(config->enableRunInDoze) | LPIT_MCR_M_CEN_MASK);
84 }
85 
LPIT_Deinit(LPIT_Type * base)86 void LPIT_Deinit(LPIT_Type* base)
87 {
88     /* Disable the module */
89     base->MCR &= ~LPIT_MCR_M_CEN_MASK;
90 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
91 
92     uint32_t instance = LPIT_GetInstance(base);
93 
94     /* Disable the clock */
95     CLOCK_DisableClock(s_lpitClock[instance]);
96 #if defined(LPIT_PERIPH_CLOCKS)
97     CLOCK_DisableClock(s_lpitPeriphClocks[instance]);
98 #endif
99 
100 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
101 }
102 
LPIT_GetDefaultConfig(lpit_config_t * config)103 void LPIT_GetDefaultConfig(lpit_config_t* config)
104 {
105     assert(config);
106 
107     /* Timers are stopped in debug mode */
108     config->enableRunInDebug = false;
109     /* Timers are stopped in doze mode */
110     config->enableRunInDoze = false;
111 }
112 
LPIT_SetupChannel(LPIT_Type * base,lpit_chnl_t channel,const lpit_chnl_params_t * chnlSetup)113 status_t LPIT_SetupChannel(LPIT_Type* base, lpit_chnl_t channel, const lpit_chnl_params_t* chnlSetup)
114 {
115     assert(chnlSetup);
116 
117     uint32_t reg = 0;
118 
119     /* Cannot assert the chain bit for channel 0 */
120     if ((channel == kLPIT_Chnl_0) && (chnlSetup->chainChannel == true))
121     {
122         return kStatus_Fail;
123     }
124 
125     /* Setup the channel counters operation mode, trigger operation, chain mode */
126     reg = (LPIT_TCTRL_MODE(chnlSetup->timerMode) | LPIT_TCTRL_TRG_SRC(chnlSetup->triggerSource) |
127            LPIT_TCTRL_TRG_SEL(chnlSetup->triggerSelect) | LPIT_TCTRL_TROT(chnlSetup->enableReloadOnTrigger) |
128            LPIT_TCTRL_TSOI(chnlSetup->enableStopOnTimeout) | LPIT_TCTRL_TSOT(chnlSetup->enableStartOnTrigger) |
129            LPIT_TCTRL_CHAIN(chnlSetup->chainChannel));
130 
131     base->CHANNEL[channel].TCTRL = reg;
132 
133     return kStatus_Success;
134 }
135