S32 SDK
clock_manager.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2013 - 2015, Freescale Semiconductor, Inc.
3  * Copyright 2016 NXP
4  * All rights reserved.
5  *
6  * THIS SOFTWARE IS PROVIDED BY NXP "AS IS" AND ANY EXPRESSED OR
7  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
8  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
9  * IN NO EVENT SHALL NXP OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
10  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
11  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
12  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
13  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
14  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
15  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
16  * THE POSSIBILITY OF SUCH DAMAGE.
17  */
18 
33 #include "device_registers.h"
34 #include "clock_manager.h"
35 #include "interrupt_manager.h"
36 #include <stddef.h>
37 
38 /*******************************************************************************
39  * Definitions
40  ******************************************************************************/
41 
42 /*******************************************************************************
43  * Code
44  ******************************************************************************/
46 
47 
48 /*FUNCTION**********************************************************************
49  *
50  * Function Name : CLOCK_SYS_Init
51  * Description : Install pre-defined clock configurations.
52  * This function installs the pre-defined clock configuration table to the
53  * clock manager.
54  *
55  * Implements CLOCK_SYS_Init_Activity
56  *END**************************************************************************/
58  uint8_t configsNumber,
60  uint8_t callbacksNumber)
61 {
62  DEV_ASSERT(clockConfigsPtr != NULL);
63  DEV_ASSERT(callbacksPtr != NULL);
64 
65  g_clockState.configTable = clockConfigsPtr;
66  g_clockState.clockConfigNum = configsNumber;
67  g_clockState.callbackConfig = callbacksPtr;
68  g_clockState.callbackNum = callbacksNumber;
69 
70  /*
71  * errorCallbackIndex is the index of the callback which returns error
72  * during clock mode switch. If all callbacks return success, then the
73  * errorCallbackIndex is callbacksNumber.
74  */
75  g_clockState.errorCallbackIndex = callbacksNumber;
76 
77  return STATUS_SUCCESS;
78 }
79 
80 /*FUNCTION**********************************************************************
81  *
82  * Function Name : CLOCK_SYS_UpdateConfiguration
83  * Description : Send notification and change system clock configuration.
84  * This function sends the notification to all callback functions, if all
85  * callbacks return OK or forceful policy is used, this function will change
86  * system clock configuration.
87  *
88  * Implements CLOCK_SYS_UpdateConfiguration_Activity
89  *END**************************************************************************/
90 status_t CLOCK_SYS_UpdateConfiguration(uint8_t targetConfigIndex,
92 {
93  uint8_t callbackIdx;
94  bool successfulSetConfig; /* SetConfiguraiton status */
96  const clock_manager_callback_user_config_t * callbackConfig;
97  clock_notify_struct_t notifyStruct;
98 
99  DEV_ASSERT(targetConfigIndex < g_clockState.clockConfigNum); /* Clock configuration index is out of range. */
100 
101  notifyStruct.targetClockConfigIndex = targetConfigIndex;
102  notifyStruct.policy = policy;
103 
104  /* Disable interrupts */
106  /* Set errorcallbackindex as callbackNum, which means no callback error now.*/
107  g_clockState.errorCallbackIndex = g_clockState.callbackNum;
108 
109  /* First step: Send "BEFORE" notification. */
111 
112  /* Send notification to all callback. */
113  for (callbackIdx=0; callbackIdx<g_clockState.callbackNum; callbackIdx++)
114  {
115  callbackConfig = g_clockState.callbackConfig[callbackIdx];
116  if ((callbackConfig) &&
117  (callbackConfig->callbackType != CLOCK_MANAGER_CALLBACK_AFTER))
118  {
119  if (STATUS_SUCCESS !=
120  (*callbackConfig->callback)(&notifyStruct,
121  callbackConfig->callbackData))
122  {
123  g_clockState.errorCallbackIndex = callbackIdx;
124  /* Save the error callback index. */
126 
127  if (CLOCK_MANAGER_POLICY_AGREEMENT == policy)
128  {
129  break;
130  }
131  }
132  }
133  }
134 
135  /* If all callback success or forceful policy is used. */
136  if ((STATUS_SUCCESS == ret) ||
137  (policy == CLOCK_MANAGER_POLICY_FORCIBLE))
138  {
139  /* clock mode switch. */
140  ret = CLOCK_SYS_SetConfiguration(g_clockState.configTable[targetConfigIndex]);
141  successfulSetConfig = (STATUS_SUCCESS == ret);
142 
143  g_clockState.curConfigIndex = targetConfigIndex;
144  }
145  else
146  {
147  /* Unsuccessful setConfiguration */
148  successfulSetConfig = false;
149  }
150 
151  if(successfulSetConfig){
152  notifyStruct.notifyType = CLOCK_MANAGER_NOTIFY_AFTER;
153 
154  for (callbackIdx=0; callbackIdx<g_clockState.callbackNum; callbackIdx++)
155  {
156  callbackConfig = g_clockState.callbackConfig[callbackIdx];
157  if ((callbackConfig) &&
158  (callbackConfig->callbackType != CLOCK_MANAGER_CALLBACK_BEFORE))
159  {
160  if (STATUS_SUCCESS !=
161  (*callbackConfig->callback)(&notifyStruct,
162  callbackConfig->callbackData))
163  {
164  g_clockState.errorCallbackIndex = callbackIdx;
165  /* Save the error callback index. */
167 
168  if (CLOCK_MANAGER_POLICY_AGREEMENT == policy)
169  {
170  break;
171  }
172  }
173  }
174  }
175  }
176  else /* Error occurs, need to send "RECOVER" notification. */
177  {
179  for(;;)
180  {
181  callbackConfig = g_clockState.callbackConfig[callbackIdx];
182  if (callbackConfig != NULL)
183  {
184  (void)(*callbackConfig->callback)(&notifyStruct,
185  callbackConfig->callbackData);
186  }
187  if(callbackIdx == 0U)
188  {
189  break;
190  }
191  callbackIdx--;
192  }
193  }
194 
195  /* Enable interrupts */
197 
198  return ret;
199 }
200 
201 /*FUNCTION**********************************************************************
202  *
203  * Function Name : CLOCK_SYS_GetCurrentConfiguration
204  * Description : Get current clock configuration index.
205  *
206  * Implements CLOCK_SYS_GetCurrentConfiguration_Activity
207  *END**************************************************************************/
209 {
210  return g_clockState.curConfigIndex;
211 }
212 
213 /*FUNCTION**********************************************************************
214  *
215  * Function Name : CLOCK_SYS_GetErrorCallback
216  * Description : Get the callback which returns error in last clock switch.
217  *
218  * Implements CLOCK_SYS_GetErrorCallback_Activity
219  *END**************************************************************************/
221 {
223 
224  /* If all callbacks return success. */
225  if (g_clockState.errorCallbackIndex >= g_clockState.clockConfigNum)
226  {
227  retValue = NULL;
228  }
229  else
230  {
231  retValue = g_clockState.callbackConfig[g_clockState.errorCallbackIndex];
232  }
233  return retValue;
234 }
235 
236 
237 /*******************************************************************************
238  * EOF
239  ******************************************************************************/
240 
Clock manager state structure. Implements clock_manager_state_t_Class.
status_t CLOCK_SYS_UpdateConfiguration(uint8_t targetConfigIndex, clock_manager_policy_t policy)
Set system clock configuration according to pre-defined structure.
Definition: clock_manager.c:90
clock_manager_callback_user_config_t ** callbackConfig
clock_manager_user_config_t const ** configTable
clock_manager_policy_t policy
clock_manager_policy_t
Clock transition policy. Implements clock_manager_policy_t_Class.
static clock_manager_state_t g_clockState
Definition: clock_manager.c:45
void INT_SYS_DisableIRQGlobal(void)
Disable system interrupt.
#define DEV_ASSERT(x)
Definition: devassert.h:78
Structure for callback function and its parameter. Implements clock_manager_callback_user_config_t_Cl...
status_t CLOCK_SYS_SetConfiguration(clock_manager_user_config_t const *config)
Set system clock configuration.
clock_manager_callback_t callback
uint8_t CLOCK_SYS_GetCurrentConfiguration(void)
Get current system clock configuration.
status_t
Status return codes. Common error codes will be a unified enumeration (C enum) that will contain all ...
Definition: status.h:31
status_t CLOCK_SYS_Init(clock_manager_user_config_t const **clockConfigsPtr, uint8_t configsNumber, clock_manager_callback_user_config_t **callbacksPtr, uint8_t callbacksNumber)
Install pre-defined clock configurations.
Definition: clock_manager.c:57
clock_manager_callback_type_t callbackType
void INT_SYS_EnableIRQGlobal(void)
Enables system interrupt.
clock_manager_notify_t notifyType
Clock configuration structure. Implements clock_manager_user_config_t_Class.
Definition: clock_manager.h:66
Clock notification structure passed to clock callback function. Implements clock_notify_struct_t_Clas...
clock_manager_callback_user_config_t * CLOCK_SYS_GetErrorCallback(void)
Get the callback which returns error in last clock switch.