summaryrefslogtreecommitdiff
path: root/utilities/fsl_notifier.h
blob: 1d3913487fae1b4f5325d8431534a7a90839b29d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
/*
 * Copyright (c) 2015, Freescale Semiconductor, Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 *
 * o Redistributions of source code must retain the above copyright notice, this list
 *   of conditions and the following disclaimer.
 *
 * o Redistributions in binary form must reproduce the above copyright notice, this
 *   list of conditions and the following disclaimer in the documentation and/or
 *   other materials provided with the distribution.
 *
 * o Neither the name of Freescale Semiconductor, Inc. nor the names of its
 *   contributors may be used to endorse or promote products derived from this
 *   software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef _FSL_NOTIFIER_H_
#define _FSL_NOTIFIER_H_

#include "fsl_common.h"
/*!
 * @addtogroup notifier
 * @{
 */

/*******************************************************************************
 * Definitions
 ******************************************************************************/

/*!
 * @brief Notifier error codes.
 *
 * Used as return value of Notifier functions.
 */
enum _notifier_status
{
    kStatus_NOTIFIER_ErrorNotificationBefore =
        MAKE_STATUS(kStatusGroup_NOTIFIER, 0), /*!< Error occurs during send "BEFORE" notification. */
    kStatus_NOTIFIER_ErrorNotificationAfter =
        MAKE_STATUS(kStatusGroup_NOTIFIER, 1), /*!< Error occurs during send "AFTER" notification. */
};

/*!
 * @brief Notifier policies.
 *
 * Defines whether user function execution is forced or not.
 * For kNOTIFIER_PolicyForcible, the user function is executed regardless of the callback results,
 * while kNOTIFIER_PolicyAgreement policy is used to exit NOTIFIER_SwitchConfig()
 * when any of the callbacks returns error code.
 * See also NOTIFIER_SwitchConfig() description.
 */
typedef enum _notifier_policy
{
    kNOTIFIER_PolicyAgreement, /*!< NOTIFIER_SwitchConfig() method is exited when any of the callbacks returns error
                                      code. */
    kNOTIFIER_PolicyForcible,  /*!< user function is executed regardless of the results. */
} notifier_policy_t;

/*! @brief Notification type. Used to notify registered callbacks */
typedef enum _notifier_notification_type
{
    kNOTIFIER_NotifyRecover = 0x00U, /*!< Notify IP to recover to previous work state. */
    kNOTIFIER_NotifyBefore = 0x01U,  /*!< Notify IP that configuration setting is going to change. */
    kNOTIFIER_NotifyAfter = 0x02U,   /*!< Notify IP that configuration setting has been changed. */
} notifier_notification_type_t;

/*!
 * @brief The callback type, indicates what kinds of notification the callback handles.
 *
 * Used in the callback configuration structure (notifier_callback_config_t)
 * to specify when the registered callback is called during configuration switch initiated by
 * NOTIFIER_SwitchConfig().
 * Callback can be invoked in following situations:
 *  - before the configuration switch (Callback return value can affect NOTIFIER_SwitchConfig()
 *    execution. See the NOTIFIER_SwitchConfig() and notifier_policy_t documentation).
 *  - after unsuccessful attempt to switch configuration
 *  - after successful configuration switch
 */
typedef enum _notifier_callback_type
{
    kNOTIFIER_CallbackBefore = 0x01U,      /*!< Callback handles BEFORE notification. */
    kNOTIFIER_CallbackAfter = 0x02U,       /*!< Callback handles AFTER notification. */
    kNOTIFIER_CallbackBeforeAfter = 0x03U, /*!< Callback handles BEFORE and AFTER notification. */
} notifier_callback_type_t;

/*! @brief Notifier user configuration type.
 *
 * Reference of user defined configuration is stored in an array; the notifier switches between these configurations
 * based on this array.
 */
typedef void notifier_user_config_t;

/*! @brief Notifier user function prototype
 * Use this function to execute specific operations in configuration switch.
 * Before and after this function execution, different notification is sent to registered callbacks.
 * If this function returns any error code, NOTIFIER_SwitchConfig() exits.
 *
 * @param targetConfig target Configuration.
 * @param userData Refers to other specific data passed to user function.
 * @return An error code or kStatus_Success.
 */
typedef status_t (*notifier_user_function_t)(notifier_user_config_t *targetConfig, void *userData);

/*! @brief notification block passed to the registered callback function. */
typedef struct _notifier_notification_block
{
    notifier_user_config_t *targetConfig;    /*!< Pointer to target configuration. */
    notifier_policy_t policy;                /*!< Configure transition policy. */
    notifier_notification_type_t notifyType; /*!< Configure notification type. */
} notifier_notification_block_t;

/*!
 * @brief Callback prototype.
 *
 * Declaration of callback. It is common for registered callbacks.
 * Reference to function of this type is part of notifier_callback_config_t callback configuration structure.
 * Depending on callback type, function of this prototype is called (see NOTIFIER_SwitchConfig())
 * before configuration switch, after it or in both use cases to notify about
 * the switch progress (see notifier_callback_type_t). When called, type of the notification
 * is passed as parameter along with reference to the target configuration structure (see notifier_notification_block_t)
 * and any data passed during the callback registration.
 * When notified before configuration switch, depending on the configuration switch policy (see
 * notifier_policy_t) the callback may deny the execution of user function by returning any error code different
 * from kStatus_Success (see NOTIFIER_SwitchConfig()).
 *
 * @param notify Notification block.
 * @param data Callback data. Refers to the data passed during callback registration. Intended to
 *  pass any driver or application data such as internal state information.
 * @return An error code or kStatus_Success.
 */
typedef status_t (*notifier_callback_t)(notifier_notification_block_t *notify, void *data);

/*!
 * @brief Callback configuration structure
 *
 * This structure holds configuration of callbacks.
 * Callbacks of this type are expected to be statically allocated.
 * This structure contains following application-defined data:
 *  callback - pointer to the callback function
 *  callbackType - specifies when the callback is called
 *  callbackData - pointer to the data passed to the callback.
 */
typedef struct _notifier_callback_config
{
    notifier_callback_t callback;          /*!< Pointer to the callback function. */
    notifier_callback_type_t callbackType; /*!< Callback type. */
    void *callbackData;                    /*!< Pointer to the data passed to the callback. */
} notifier_callback_config_t;

/*!
 * @brief Notifier handle structure.
 *
 * Notifier handle structure. Contains data necessary for Notifier proper function.
 * Stores references to registered configurations, callbacks, information about their numbers,
 * user function, user data and other internal data.
 * NOTIFIER_CreateHandle() must be called to initialize this handle.
 */
typedef struct _notifier_handle
{
    notifier_user_config_t **configsTable;      /*!< Pointer to configure table. */
    uint8_t configsNumber;                      /*!< Number of configurations. */
    notifier_callback_config_t *callbacksTable; /*!< Pointer to callback table. */
    uint8_t callbacksNumber;                    /*!< Maximum number of callback configurations. */
    uint8_t errorCallbackIndex;                 /*!< Index of callback returns error. */
    uint8_t currentConfigIndex;                 /*!< Index of current configuration.  */
    notifier_user_function_t userFunction;      /*!< user function. */
    void *userData;                             /*!< user data passed to user function. */
} notifier_handle_t;

/*******************************************************************************
 * API
 ******************************************************************************/

#if defined(__cplusplus)
extern "C" {
#endif

/*!
 * @brief Create Notifier handle.
 *
 * @param notifierHandle A pointer to notifier handle
 * @param configs A pointer to an array with references to all configurations which is handled by the Notifier.
 * @param configsNumber Number of configurations. Size of the configuration array.
 * @param callbacks A pointer to an array of callback configurations.
 *  If there are no callbacks to register during Notifier initialization, use NULL value.
 * @param callbacksNumber Number of registered callbacks. Size of callbacks array.
 * @param userFunction user function.
 * @param userData user data passed to user function.
 * @return An error code or kStatus_Success.
 */
status_t NOTIFIER_CreateHandle(notifier_handle_t *notifierHandle,
                               notifier_user_config_t **configs,
                               uint8_t configsNumber,
                               notifier_callback_config_t *callbacks,
                               uint8_t callbacksNumber,
                               notifier_user_function_t userFunction,
                               void *userData);

/*!
 * @brief Switch configuration according to a pre-defined structure.
 *
 * This function sets the system to the target configuration. Before transition,
 * the Notifier sends notifications to all callbacks registered to the callback table.
 * Callbacks are invoked in the following order: All registered callbacks are notified
 * ordered by index in the callbacks array. The same order is used for before and after switch notifications.
 * The notifications before the configuration switch can be used to obtain confirmation about
 * the change from registered callbacks. If any registered callback denies the
 * configuration change, further execution of this function depends on the notifier policy: the
 * configuration change is either forced (kNOTIFIER_PolicyForcible) or exited (kNOTIFIER_PolicyAgreement).
 * When configuration change is forced, the result of the before switch notifications are ignored. If
 * agreement is required, if any callback returns an error code then further notifications
 * before switch notifications are cancelled and all already notified callbacks are re-invoked
 * The index of the callback which returned error code during pre-switch notifications is stored
 * (any error codes during callbacks re-invocation are ignored) and NOTIFIER_GetErrorCallback() can be used to get it.
 * Regardless of the policies, if any callback returned an error code, an error code denoting in which phase
 * the error occurred is returned when NOTIFIER_SwitchConfig() exits.
 * @param notifierHandle pointer to notifier handle
 * @param configIndex Index of the target configuration.
 * @param policy            Transaction policy, kNOTIFIER_PolicyAgreement or kNOTIFIER_PolicyForcible.
 *
 * @return An error code or kStatus_Success.
 *
 */
status_t NOTIFIER_SwitchConfig(notifier_handle_t *notifierHandle, uint8_t configIndex, notifier_policy_t policy);

/*!
 * @brief This function returns the last failed notification callback.
 *
 * This function returns index of the last callback that failed during the configuration switch while
 * the last NOTIFIER_SwitchConfig() was called. If the last NOTIFIER_SwitchConfig() call ended successfully
 * value equal to callbacks number is returned. Returned value represents index in the array of
 * static call-backs.
 *
 * @param notifierHandle pointer to notifier handle
 * @return Callback index of last failed callback or value equal to callbacks count.
 */
uint8_t NOTIFIER_GetErrorCallbackIndex(notifier_handle_t *notifierHandle);

#if defined(__cplusplus)
}
#endif /* __cplusplus */

/*! @}*/

#endif /* _FSL_NOTIFIER_H_ */