fsl_notifier.c 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. /*
  2. * The Clear BSD License
  3. * Copyright (c) 2015, Freescale Semiconductor, Inc.
  4. * Copyright 2016-2017 NXP
  5. * All rights reserved.
  6. *
  7. * Redistribution and use in source and binary forms, with or without modification,
  8. * are permitted (subject to the limitations in the disclaimer below) provided
  9. * that the following conditions are met:
  10. *
  11. * o Redistributions of source code must retain the above copyright notice, this list
  12. * of conditions and the following disclaimer.
  13. *
  14. * o Redistributions in binary form must reproduce the above copyright notice, this
  15. * list of conditions and the following disclaimer in the documentation and/or
  16. * other materials provided with the distribution.
  17. *
  18. * o Neither the name of the copyright holder nor the names of its
  19. * contributors may be used to endorse or promote products derived from this
  20. * software without specific prior written permission.
  21. *
  22. * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE.
  23. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  24. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  25. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  26. * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
  27. * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  28. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  29. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  30. * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  31. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  32. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  33. */
  34. #include "fsl_notifier.h"
  35. /*******************************************************************************
  36. * Definitions
  37. ******************************************************************************/
  38. /*******************************************************************************
  39. * Prototypes
  40. ******************************************************************************/
  41. /*******************************************************************************
  42. * Variables
  43. ******************************************************************************/
  44. /*******************************************************************************
  45. * Code
  46. ******************************************************************************/
  47. status_t NOTIFIER_CreateHandle(notifier_handle_t *notifierHandle,
  48. notifier_user_config_t **configs,
  49. uint8_t configsNumber,
  50. notifier_callback_config_t *callbacks,
  51. uint8_t callbacksNumber,
  52. notifier_user_function_t userFunction,
  53. void *userData)
  54. {
  55. /* Check input parameter - at least one configuration is required and userFunction must exist */
  56. if ((configs == NULL) || (configsNumber == 0U) || (userFunction == NULL))
  57. {
  58. return kStatus_Fail;
  59. }
  60. /* Initialize handle structure */
  61. memset(notifierHandle, 0, sizeof(notifier_handle_t));
  62. /* Store references to user-defined configurations */
  63. notifierHandle->configsTable = configs;
  64. notifierHandle->configsNumber = configsNumber;
  65. /* Store references to user-defined callback configurations */
  66. if (callbacks != NULL)
  67. {
  68. notifierHandle->callbacksTable = callbacks;
  69. notifierHandle->callbacksNumber = callbacksNumber;
  70. /* If all callbacks return success, then the errorCallbackIndex is callbacksNumber */
  71. notifierHandle->errorCallbackIndex = callbacksNumber;
  72. }
  73. notifierHandle->userFunction = userFunction;
  74. notifierHandle->userData = userData;
  75. return kStatus_Success;
  76. }
  77. status_t NOTIFIER_SwitchConfig(notifier_handle_t *notifierHandle, uint8_t configIndex, notifier_policy_t policy)
  78. {
  79. uint8_t currentStaticCallback = 0U; /* Index to array of statically registered call-backs */
  80. status_t returnCode = kStatus_Success; /* Function return */
  81. notifier_notification_block_t notifyBlock; /* Callback notification block */
  82. notifier_callback_config_t *callbackConfig; /* Pointer to callback configuration */
  83. /* Set errorcallbackindex as callbacksNumber, which means no callback error now */
  84. notifierHandle->errorCallbackIndex = notifierHandle->callbacksNumber;
  85. /* Requested configuration availability check */
  86. if (configIndex >= notifierHandle->configsNumber)
  87. {
  88. return kStatus_OutOfRange;
  89. }
  90. /* Initialization of local variables from the Notifier handle structure */
  91. notifyBlock.policy = policy;
  92. notifyBlock.targetConfig = notifierHandle->configsTable[configIndex];
  93. notifyBlock.notifyType = kNOTIFIER_NotifyBefore;
  94. /* From all statically registered call-backs... */
  95. for (currentStaticCallback = 0U; currentStaticCallback < notifierHandle->callbacksNumber; currentStaticCallback++)
  96. {
  97. callbackConfig = &(notifierHandle->callbacksTable[currentStaticCallback]);
  98. /* ...notify only those which asked to be called before the configuration switch */
  99. if (((uint32_t)callbackConfig->callbackType) & kNOTIFIER_CallbackBefore)
  100. {
  101. /* In case that call-back returned error code mark it, store the call-back handle and eventually cancel
  102. * the configuration switch */
  103. if (callbackConfig->callback(&notifyBlock, callbackConfig->callbackData) != kStatus_Success)
  104. {
  105. returnCode = kStatus_NOTIFIER_ErrorNotificationBefore;
  106. notifierHandle->errorCallbackIndex = currentStaticCallback;
  107. /* If not forcing configuration switch, call all already notified call-backs to revert their state
  108. * as the switch is canceled */
  109. if (policy != kNOTIFIER_PolicyForcible)
  110. {
  111. break;
  112. }
  113. }
  114. }
  115. }
  116. /* Set configuration */
  117. /* In case that any call-back returned error code and policy doesn't force the configuration set, go to after
  118. * switch call-backs */
  119. if ((policy == kNOTIFIER_PolicyForcible) || (returnCode == kStatus_Success))
  120. {
  121. returnCode = notifierHandle->userFunction(notifierHandle->configsTable[configIndex], notifierHandle->userData);
  122. if (returnCode != kStatus_Success)
  123. {
  124. return returnCode;
  125. }
  126. /* Update current configuration index */
  127. notifierHandle->currentConfigIndex = configIndex;
  128. notifyBlock.notifyType = kNOTIFIER_NotifyAfter;
  129. /* From all statically registered call-backs... */
  130. for (currentStaticCallback = 0U; currentStaticCallback < notifierHandle->callbacksNumber;
  131. currentStaticCallback++)
  132. {
  133. callbackConfig = &(notifierHandle->callbacksTable[currentStaticCallback]);
  134. /* ...notify only those which asked to be called after the configruation switch */
  135. if (((uint32_t)callbackConfig->callbackType) & kNOTIFIER_CallbackAfter)
  136. {
  137. /* In case that call-back returned error code mark it and store the call-back handle */
  138. if (callbackConfig->callback(&notifyBlock, callbackConfig->callbackData) != kStatus_Success)
  139. {
  140. returnCode = kStatus_NOTIFIER_ErrorNotificationAfter;
  141. notifierHandle->errorCallbackIndex = currentStaticCallback;
  142. if (policy != kNOTIFIER_PolicyForcible)
  143. {
  144. break;
  145. }
  146. }
  147. }
  148. }
  149. }
  150. else
  151. {
  152. /* End of unsuccessful switch */
  153. notifyBlock.notifyType = kNOTIFIER_NotifyRecover;
  154. while (currentStaticCallback--)
  155. {
  156. callbackConfig = &(notifierHandle->callbacksTable[currentStaticCallback]);
  157. if (((uint32_t)callbackConfig->callbackType) & kNOTIFIER_CallbackBefore)
  158. {
  159. callbackConfig->callback(&notifyBlock, callbackConfig->callbackData);
  160. }
  161. }
  162. }
  163. return returnCode;
  164. }
  165. uint8_t NOTIFIER_GetErrorCallbackIndex(notifier_handle_t *notifierHandle)
  166. {
  167. return notifierHandle->errorCallbackIndex;
  168. }