Pdb_Adc_Ip.c 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832
  1. /*==================================================================================================
  2. * Project : RTD AUTOSAR 4.4
  3. * Platform : CORTEXM
  4. * Peripheral : ADC
  5. * Dependencies : none
  6. *
  7. * Autosar Version : 4.4.0
  8. * Autosar Revision : ASR_REL_4_4_REV_0000
  9. * Autosar Conf.Variant :
  10. * SW Version : 1.0.0
  11. * Build Version : S32K1_RTD_1_0_0_HF01_D2109_ASR_REL_4_4_REV_0000_20210907
  12. *
  13. * (c) Copyright 2020-2021 NXP Semiconductors
  14. * All Rights Reserved.
  15. *
  16. * NXP Confidential. This software is owned or controlled by NXP and may only be
  17. * used strictly in accordance with the applicable license terms. By expressly
  18. * accepting such terms or by downloading, installing, activating and/or otherwise
  19. * using the software, you are agreeing that you have read, and that you agree to
  20. * comply with and are bound by, such license terms. If you do not agree to be
  21. * bound by the applicable license terms, then you may not retain, install,
  22. * activate or otherwise use the software.
  23. ==================================================================================================*/
  24. /**
  25. * @file
  26. *
  27. * @addtogroup pdb_adc_ip Pdb Adc IPL
  28. * @{
  29. */
  30. #include "Pdb_Adc_Ip.h"
  31. #include "Pdb_Adc_Ip_HwAccess.h"
  32. #include "SchM_Adc.h"
  33. #include "OsIf.h"
  34. #if (PDB_ADC_IP_DEV_ERROR_DETECT == STD_ON)
  35. #include "Devassert.h"
  36. #endif /* (PDB_ADC_IP_DEV_ERROR_DETECT == STD_ON) */
  37. #if (STD_ON == PDB_ADC_IP_ENABLE_USER_MODE_SUPPORT)
  38. /* USER_MODE_REG_PROT_ENABLED is defined for Base sanity check in RegLockMacros.h */
  39. #define USER_MODE_REG_PROT_ENABLED (PDB_ADC_IP_ENABLE_USER_MODE_SUPPORT)
  40. #include "RegLockMacros.h"
  41. #endif /* (STD_ON == PDB_ADC_IP_ENABLE_USER_MODE_SUPPORT) */
  42. /*******************************************************************************
  43. * Source file version information
  44. ******************************************************************************/
  45. #define PDB_ADC_IP_VENDOR_ID_C 43
  46. #define PDB_ADC_IP_AR_RELEASE_MAJOR_VERSION_C 4
  47. #define PDB_ADC_IP_AR_RELEASE_MINOR_VERSION_C 4
  48. #define PDB_ADC_IP_AR_RELEASE_REVISION_VERSION_C 0
  49. #define PDB_ADC_IP_SW_MAJOR_VERSION_C 1
  50. #define PDB_ADC_IP_SW_MINOR_VERSION_C 0
  51. #define PDB_ADC_IP_SW_PATCH_VERSION_C 0
  52. /*******************************************************************************
  53. * File version checks
  54. ******************************************************************************/
  55. /* Check if Pdb_Adc_Ip.c file and Pdb_Adc_Ip.h file are of the same vendor */
  56. #if (PDB_ADC_IP_VENDOR_ID_C != PDB_ADC_IP_VENDOR_ID_H)
  57. #error "Pdb_Adc_Ip.c and Pdb_Adc_Ip.h have different vendor ids"
  58. #endif
  59. /* Check if Pdb_Adc_Ip.c file and Pdb_Adc_Ip.h file are of the same Autosar version */
  60. #if ((PDB_ADC_IP_AR_RELEASE_MAJOR_VERSION_C != PDB_ADC_IP_AR_RELEASE_MAJOR_VERSION_H) || \
  61. (PDB_ADC_IP_AR_RELEASE_MINOR_VERSION_C != PDB_ADC_IP_AR_RELEASE_MINOR_VERSION_H) || \
  62. (PDB_ADC_IP_AR_RELEASE_REVISION_VERSION_C != PDB_ADC_IP_AR_RELEASE_REVISION_VERSION_H) \
  63. )
  64. #error "AutoSar Version Numbers of Pdb_Adc_Ip.c and Pdb_Adc_Ip.h are different"
  65. #endif
  66. /* Check if Pdb_Adc_Ip.c file and Pdb_Adc_Ip.h file are of the same Software version */
  67. #if ((PDB_ADC_IP_SW_MAJOR_VERSION_C != PDB_ADC_IP_SW_MAJOR_VERSION_H) || \
  68. (PDB_ADC_IP_SW_MINOR_VERSION_C != PDB_ADC_IP_SW_MINOR_VERSION_H) || \
  69. (PDB_ADC_IP_SW_PATCH_VERSION_C != PDB_ADC_IP_SW_PATCH_VERSION_H) \
  70. )
  71. #error "Software Version Numbers of Pdb_Adc_Ip.c and Pdb_Adc_Ip.h are different"
  72. #endif
  73. #if (PDB_ADC_IP_VENDOR_ID_C != PDB_ADC_IP_VENDOR_ID_HWACCESS_H)
  74. #error "Pdb_Adc_Ip.c and Pdb_Adc_Ip_HwAccess.h have different vendor ids"
  75. #endif
  76. /* Check if Pdb_Adc_Ip.c file and Pdb_Adc_Ip_HwAccess.h file are of the same Autosar version */
  77. #if ((PDB_ADC_IP_AR_RELEASE_MAJOR_VERSION_C != PDB_ADC_IP_AR_RELEASE_MAJOR_VERSION_HWACCESS_H) || \
  78. (PDB_ADC_IP_AR_RELEASE_MINOR_VERSION_C != PDB_ADC_IP_AR_RELEASE_MINOR_VERSION_HWACCESS_H) || \
  79. (PDB_ADC_IP_AR_RELEASE_REVISION_VERSION_C != PDB_ADC_IP_AR_RELEASE_REVISION_VERSION_HWACCESS_H) \
  80. )
  81. #error "AutoSar Version Numbers of Pdb_Adc_Ip.c and Pdb_Adc_Ip_HwAccess.h are different"
  82. #endif
  83. /* Check if Pdb_Adc_Ip.c file and Pdb_Adc_Ip_HwAccess.h file are of the same Software version */
  84. #if ((PDB_ADC_IP_SW_MAJOR_VERSION_C != PDB_ADC_IP_SW_MAJOR_VERSION_HWACCESS_H) || \
  85. (PDB_ADC_IP_SW_MINOR_VERSION_C != PDB_ADC_IP_SW_MINOR_VERSION_HWACCESS_H) || \
  86. (PDB_ADC_IP_SW_PATCH_VERSION_C != PDB_ADC_IP_SW_PATCH_VERSION_HWACCESS_H) \
  87. )
  88. #error "Software Version Numbers of Pdb_Adc_Ip.c and Pdb_Adc_Ip_HwAccess.h are different"
  89. #endif
  90. #ifndef DISABLE_MCAL_INTERMODULE_ASR_CHECK
  91. /* Check if Pdb_Adc_Ip.c file and OsIf.h file are of the same Autosar version */
  92. #if ((PDB_ADC_IP_AR_RELEASE_MAJOR_VERSION_C != OSIF_AR_RELEASE_MAJOR_VERSION) || \
  93. (PDB_ADC_IP_AR_RELEASE_MINOR_VERSION_C != OSIF_AR_RELEASE_MINOR_VERSION) \
  94. )
  95. #error "AutoSar Version Numbers of Pdb_Adc_Ip.c and OsIf.h are different"
  96. #endif
  97. #if (STD_ON == PDB_ADC_IP_ENABLE_USER_MODE_SUPPORT)
  98. /* Checks against RegLockMacros.h */
  99. #if ((PDB_ADC_IP_AR_RELEASE_MAJOR_VERSION_C != REGLOCKMACROS_AR_RELEASE_MAJOR_VERSION) || \
  100. (PDB_ADC_IP_AR_RELEASE_MINOR_VERSION_C != REGLOCKMACROS_AR_RELEASE_MINOR_VERSION))
  101. #error "AUTOSAR Version Numbers of Pdb_Adc_Ip.c and RegLockMacros.h are different"
  102. #endif
  103. #endif /* (STD_ON == PDB_ADC_IP_ENABLE_USER_MODE_SUPPORT) */
  104. /* Check if Pdb_Adc_Ip.c and SchM_Adc.h are of the same Autosar version */
  105. #if ((PDB_ADC_IP_AR_RELEASE_MAJOR_VERSION_C != SCHM_ADC_AR_RELEASE_MAJOR_VERSION) || \
  106. (PDB_ADC_IP_AR_RELEASE_MINOR_VERSION_C != SCHM_ADC_AR_RELEASE_MINOR_VERSION) \
  107. )
  108. #error "AutoSar Version Numbers of Pdb_Adc_Ip.c and SchM_Adc.h are different"
  109. #endif
  110. #if (PDB_ADC_IP_DEV_ERROR_DETECT == STD_ON)
  111. /* Check if Pdb_Adc_Ip.c and Devassert.h are of the same Autosar version */
  112. #if ((PDB_ADC_IP_AR_RELEASE_MAJOR_VERSION_C != DEVASSERT_AR_RELEASE_MAJOR_VERSION) || \
  113. (PDB_ADC_IP_AR_RELEASE_MINOR_VERSION_C != DEVASSERT_AR_RELEASE_MINOR_VERSION) \
  114. )
  115. #error "AutoSar Version Numbers of Pdb_Adc_Ip.c and Devassert.h are different"
  116. #endif
  117. #endif /* (PDB_ADC_IP_DEV_ERROR_DETECT == STD_ON) */
  118. #endif /* DISABLE_MCAL_INTERMODULE_ASR_CHECK */
  119. /*******************************************************************************
  120. * Pre-check
  121. ******************************************************************************/
  122. #ifndef MCAL_ENABLE_USER_MODE_SUPPORT
  123. #if (STD_ON == PDB_ADC_IP_ENABLE_USER_MODE_SUPPORT)
  124. #error MCAL_ENABLE_USER_MODE_SUPPORT is not enabled. For running PDB in user mode the MCAL_ENABLE_USER_MODE_SUPPORT needs to be defined
  125. #endif /* (STD_ON == PDB_ADC_IP_ENABLE_USER_MODE_SUPPORT) */
  126. #endif /* ifndef MCAL_ENABLE_USER_MODE_SUPPORT*/
  127. /*******************************************************************************
  128. * Local function prototypes
  129. ******************************************************************************/
  130. #define ADC_START_SEC_CODE
  131. #include "Adc_MemMap.h"
  132. static inline void PDB_ADC_ResetChannel(PDB_Type * const Base, const uint8 ChanIdx, const Pdb_Adc_Ip_PretriggersConfigType * PdbPretriggsConfig);
  133. #if (STD_ON == FEATURE_PDB_HAS_INSTANCE_BACKTOBACK)
  134. static void PDB_ADC_ConfigInstanceBackToBack_TrustedCall(const boolean InstanceBackToBackEnable);
  135. static void PDB_ADC_ConfigInstanceBackToBack(const boolean InstanceBackToBackEnable);
  136. #endif /* (STD_ON == FEATURE_PDB_HAS_INSTANCE_BACKTOBACK) */
  137. #if (STD_ON == FEATURE_PDB_HAS_INTERCHANNEL_BACKTOBACK)
  138. static void PDB_ADC_ConfigInterChannelBackToBack_TrustedCall(const uint32 Instance, const boolean InterChannelBackToBackEnable);
  139. static void PDB_ADC_ConfigInterChannelBackToBack(const uint32 Instance, const boolean InterChannelBackToBackEnable);
  140. #endif /* (STD_ON == FEATURE_PDB_HAS_INTERCHANNEL_BACKTOBACK) */
  141. #define ADC_STOP_SEC_CODE
  142. #include "Adc_MemMap.h"
  143. #define ADC_START_SEC_CONST_UNSPECIFIED
  144. #include "Adc_MemMap.h"
  145. /* Table of Base addresses for PDB instances. */
  146. static PDB_Type * const PdbBase[PDB_INSTANCE_COUNT] = IP_PDB_BASE_PTRS;
  147. #define ADC_STOP_SEC_CONST_UNSPECIFIED
  148. #include "Adc_MemMap.h"
  149. #define ADC_START_SEC_VAR_CLEARED_UNSPECIFIED
  150. #include "Adc_MemMap.h"
  151. /* Global state structure */
  152. static Pdb_Adc_Ip_StateStructType PdbAdcState[PDB_INSTANCE_COUNT];
  153. #define ADC_STOP_SEC_VAR_CLEARED_UNSPECIFIED
  154. #include "Adc_MemMap.h"
  155. #define ADC_START_SEC_CODE
  156. #include "Adc_MemMap.h"
  157. /*FUNCTION**********************************************************************
  158. *
  159. * Function Name : Pdb_Adc_Ip_Init
  160. * Description : This function initializes the PDB counter, input triggers and
  161. * general pretrigger settings.
  162. * It resets PDB registers and enables the PDB clock. Therefore, it should be
  163. * called before any other operation. After it is initialized, the PDB can
  164. * act as a triggered timer, which enables other features in PDB module.
  165. *
  166. * @implements Pdb_Adc_Ip_Init_Activity
  167. * END**************************************************************************/
  168. void Pdb_Adc_Ip_Init(const uint32 Instance, const Pdb_Adc_Ip_ConfigType * const Config)
  169. {
  170. #if (PDB_ADC_IP_DEV_ERROR_DETECT == STD_ON)
  171. DevAssert(Instance < PDB_INSTANCE_COUNT);
  172. DevAssert(Config != NULL_PTR);
  173. #endif /* (PDB_ADC_IP_DEV_ERROR_DETECT == STD_ON) */
  174. PDB_Type * const Base = PdbBase[Instance];
  175. uint8 ChannelIndex, PretriggerIndex;
  176. uint32 Reg = 0u;
  177. Reg |= PDB_SC_LDMOD(Config->LoadValueMode);
  178. Reg |= PDB_SC_PRESCALER(Config->PrescalerDiv);
  179. Reg |= PDB_SC_MULT(Config->ClkPreMultFactor);
  180. Reg |= PDB_SC_TRGSEL(Config->TriggerSource);
  181. if (Config->ContinuousModeEnable == TRUE)
  182. {
  183. Reg |= PDB_SC_CONT_MASK;
  184. }
  185. if (Config->DmaEnable == TRUE)
  186. {
  187. Reg |= PDB_SC_DMAEN_MASK;
  188. }
  189. if (Config->SeqErrNotification != NULL_PTR)
  190. {
  191. Reg |= PDB_SC_PDBEIE_MASK;
  192. }
  193. Base->SC = Reg;
  194. #if (STD_ON == FEATURE_PDB_HAS_INSTANCE_BACKTOBACK)
  195. PDB_ADC_ConfigInstanceBackToBack(Config->InstanceBackToBackEnable);
  196. #endif /* (STD_ON == FEATURE_PDB_HAS_INSTANCE_BACKTOBACK) */
  197. #if (STD_ON == FEATURE_PDB_HAS_INTERCHANNEL_BACKTOBACK)
  198. PDB_ADC_ConfigInterChannelBackToBack(Instance, Config->InterChannelBackToBackEnable);
  199. #endif /* (STD_ON == FEATURE_PDB_HAS_INTERCHANNEL_BACKTOBACK) */
  200. Pdb_Adc_Ip_SetModulus(Instance, Config->ModValue);
  201. if ((Config->NumChans > 0u) && (Config->ChanConfigs != NULL_PTR))
  202. {
  203. for (ChannelIndex = 0u; ChannelIndex < Config->NumChans; ChannelIndex++)
  204. {
  205. const Pdb_Adc_Ip_ChanConfigType * ChanConfig = &(Config->ChanConfigs[ChannelIndex]);
  206. Pdb_Adc_HwAcc_ConfigAdcPretriggers(Base, ChanConfig->ChnIdx, &(ChanConfig->PretriggersConfig));
  207. for (PretriggerIndex = 0u; PretriggerIndex < PDB_DLY_COUNT; PretriggerIndex++)
  208. {
  209. Pdb_Adc_Ip_SetAdcPretriggerDelayValue(Instance, ChanConfig->ChnIdx, PretriggerIndex, ChanConfig->PretriggerDelays[PretriggerIndex]);
  210. }
  211. }
  212. }
  213. Pdb_Adc_Ip_Enable(Instance);
  214. /* Modulus and pretrigger delay values require call to LoadRegValues */
  215. Pdb_Adc_Ip_LoadRegValues(Instance);
  216. PdbAdcState[Instance].SeqErrNotification = Config->SeqErrNotification;
  217. PdbAdcState[Instance].Init = TRUE;
  218. }
  219. /*FUNCTION**********************************************************************
  220. *
  221. * Function Name : Pdb_Adc_Ip_DeInit
  222. * Description : This function resets the PDB internal registers to default values.
  223. *
  224. * When the PDB module is not used. Calling this function would shut down the
  225. * PDB module and reduce the power consumption.
  226. *
  227. * Note: instance back to back configuration is common between PDB instances 0 and 1
  228. * (configures the same register even if configured for either PDB instance)
  229. * This function disables it, so affects all other instances.
  230. *
  231. * @implements Pdb_Adc_Ip_Deinit_Activity
  232. * END**************************************************************************/
  233. void Pdb_Adc_Ip_DeInit(const uint32 Instance)
  234. {
  235. #if (PDB_ADC_IP_DEV_ERROR_DETECT == STD_ON)
  236. DevAssert(Instance < PDB_INSTANCE_COUNT);
  237. #endif /* (PDB_ADC_IP_DEV_ERROR_DETECT == STD_ON) */
  238. Pdb_Adc_Ip_ConfigType DefaultConfig;
  239. Pdb_Adc_Ip_ChanConfigType ChanConfigs[PDB_CH_COUNT];
  240. uint8 ChannelIndex, PretriggerIndex;
  241. DefaultConfig.LoadValueMode = PDB_ADC_IP_LOAD_VAL_IMMEDIATELY;
  242. DefaultConfig.PrescalerDiv = PDB_ADC_IP_CLK_PREDIV_BY_1;
  243. DefaultConfig.ClkPreMultFactor = PDB_ADC_IP_CLK_PREMULT_FACT_AS_1;
  244. DefaultConfig.TriggerSource = PDB_ADC_IP_TRIGGER_IN0;
  245. DefaultConfig.ContinuousModeEnable = FALSE;
  246. DefaultConfig.DmaEnable = FALSE;
  247. DefaultConfig.ModValue = 0u;
  248. #if (STD_ON == FEATURE_PDB_HAS_INSTANCE_BACKTOBACK)
  249. DefaultConfig.InstanceBackToBackEnable = FALSE;
  250. PDB_ADC_ConfigInstanceBackToBack(DefaultConfig.InstanceBackToBackEnable);
  251. #endif /* (STD_ON == FEATURE_PDB_HAS_INSTANCE_BACKTOBACK) */
  252. #if (STD_ON == FEATURE_PDB_HAS_INTERCHANNEL_BACKTOBACK)
  253. DefaultConfig.InterChannelBackToBackEnable = FALSE;
  254. PDB_ADC_ConfigInterChannelBackToBack(Instance, DefaultConfig.InterChannelBackToBackEnable);
  255. #endif /* (STD_ON == FEATURE_PDB_HAS_INTERCHANNEL_BACKTOBACK) */
  256. DefaultConfig.NumChans = PDB_CH_COUNT;
  257. for (ChannelIndex = 0u; ChannelIndex < PDB_CH_COUNT; ChannelIndex++)
  258. {
  259. ChanConfigs[ChannelIndex].ChnIdx = ChannelIndex;
  260. ChanConfigs[ChannelIndex].PretriggersConfig.EnableMask = 0u;
  261. ChanConfigs[ChannelIndex].PretriggersConfig.EnableDelayMask = 0u;
  262. ChanConfigs[ChannelIndex].PretriggersConfig.BackToBackEnableMask = 0u;
  263. for (PretriggerIndex = 0u; PretriggerIndex < PDB_DLY_COUNT; PretriggerIndex++)
  264. {
  265. ChanConfigs[ChannelIndex].PretriggerDelays[PretriggerIndex] = 0u;
  266. }
  267. }
  268. DefaultConfig.ChanConfigs = ChanConfigs;
  269. DefaultConfig.SeqErrNotification = NULL_PTR;
  270. Pdb_Adc_Ip_Init(Instance, &DefaultConfig);
  271. Pdb_Adc_Ip_Disable(Instance);
  272. PdbAdcState[Instance].Init = FALSE;
  273. }
  274. /*FUNCTION**********************************************************************
  275. *
  276. * Function Name : Pdb_Adc_Ip_Enable
  277. * Description : This function enables the PDB module, counter is on.
  278. *
  279. * @implements Pdb_Adc_Ip_Enable_Activity
  280. * END**************************************************************************/
  281. void Pdb_Adc_Ip_Enable(const uint32 Instance)
  282. {
  283. #if (PDB_ADC_IP_DEV_ERROR_DETECT == STD_ON)
  284. DevAssert(Instance < PDB_INSTANCE_COUNT);
  285. #endif /* (PDB_ADC_IP_DEV_ERROR_DETECT == STD_ON) */
  286. PDB_Type * const Base = PdbBase[Instance];
  287. SchM_Enter_Adc_ADC_EXCLUSIVE_AREA_34();
  288. Base->SC |= PDB_SC_PDBEN_MASK;
  289. SchM_Exit_Adc_ADC_EXCLUSIVE_AREA_34();
  290. }
  291. /*FUNCTION**********************************************************************
  292. *
  293. * Function Name : Pdb_Adc_Ip_Disable
  294. * Description : This function disables the PDB module, counter is off.
  295. *
  296. * @implements Pdb_Adc_Ip_Disable_Activity
  297. * END**************************************************************************/
  298. void Pdb_Adc_Ip_Disable(const uint32 Instance)
  299. {
  300. #if (PDB_ADC_IP_DEV_ERROR_DETECT == STD_ON)
  301. DevAssert(Instance < PDB_INSTANCE_COUNT);
  302. #endif /* (PDB_ADC_IP_DEV_ERROR_DETECT == STD_ON) */
  303. PDB_Type * const Base = PdbBase[Instance];
  304. SchM_Enter_Adc_ADC_EXCLUSIVE_AREA_35();
  305. Pdb_Adc_HwAcc_DisablePdb(Base);
  306. SchM_Exit_Adc_ADC_EXCLUSIVE_AREA_35();
  307. }
  308. /*FUNCTION**********************************************************************
  309. *
  310. * Function Name : Pdb_Adc_Ip_SetTriggerInput
  311. * Description : This function sets the PDB trigger source.
  312. *
  313. * @implements Pdb_Adc_Ip_SetTriggerInput_Activity
  314. * END**************************************************************************/
  315. void Pdb_Adc_Ip_SetTriggerInput(const uint32 Instance, const Pdb_Adc_Ip_TriggerSrcType TriggerSource)
  316. {
  317. #if (PDB_ADC_IP_DEV_ERROR_DETECT == STD_ON)
  318. DevAssert(Instance < PDB_INSTANCE_COUNT);
  319. #endif /* (PDB_ADC_IP_DEV_ERROR_DETECT == STD_ON) */
  320. PDB_Type * const Base = PdbBase[Instance];
  321. uint32 SCReg;
  322. SchM_Enter_Adc_ADC_EXCLUSIVE_AREA_36();
  323. SCReg = Base->SC;
  324. SCReg &= ~(PDB_SC_TRGSEL_MASK);
  325. SCReg |= PDB_SC_TRGSEL(TriggerSource);
  326. Base->SC = SCReg;
  327. SchM_Exit_Adc_ADC_EXCLUSIVE_AREA_36();
  328. }
  329. /*FUNCTION**********************************************************************
  330. *
  331. * Function Name : Pdb_Adc_Ip_SetContinuousMode
  332. * Description : This function sets the PDB mode to continuous or one shot.
  333. *
  334. * @implements Pdb_Adc_Ip_SetContinuousMode_Activity
  335. * END**************************************************************************/
  336. void Pdb_Adc_Ip_SetContinuousMode(const uint32 Instance, const boolean State)
  337. {
  338. #if (PDB_ADC_IP_DEV_ERROR_DETECT == STD_ON)
  339. DevAssert(Instance < PDB_INSTANCE_COUNT);
  340. #endif /* (PDB_ADC_IP_DEV_ERROR_DETECT == STD_ON) */
  341. PDB_Type * const Base = PdbBase[Instance];
  342. SchM_Enter_Adc_ADC_EXCLUSIVE_AREA_37();
  343. Pdb_Adc_HwAcc_SetContinuousMode(Base, State);
  344. SchM_Exit_Adc_ADC_EXCLUSIVE_AREA_37();
  345. }
  346. /*FUNCTION**********************************************************************
  347. *
  348. * Function Name : Pdb_Adc_Ip_SwTrigger
  349. * Description : This function triggers the PDB with a software trigger.
  350. * When the PDB is set to use the software trigger as input, calling this function
  351. * triggers the PDB.
  352. *
  353. * @implements Pdb_Adc_Ip_SwTrigger_Activity
  354. * END**************************************************************************/
  355. void Pdb_Adc_Ip_SwTrigger(const uint32 Instance)
  356. {
  357. #if (PDB_ADC_IP_DEV_ERROR_DETECT == STD_ON)
  358. DevAssert(Instance < PDB_INSTANCE_COUNT);
  359. #endif /* (PDB_ADC_IP_DEV_ERROR_DETECT == STD_ON) */
  360. PDB_Type * const Base = PdbBase[Instance];
  361. SchM_Enter_Adc_ADC_EXCLUSIVE_AREA_38();
  362. Base->SC |= PDB_SC_SWTRIG_MASK;
  363. SchM_Exit_Adc_ADC_EXCLUSIVE_AREA_38();
  364. }
  365. /*FUNCTION**********************************************************************
  366. *
  367. * Function Name : Pdb_Adc_Ip_GetTimerValue
  368. * Description : This function gets the current counter value.
  369. *
  370. * @implements Pdb_Adc_Ip_GetTimerValue_Activity
  371. * END**************************************************************************/
  372. uint32 Pdb_Adc_Ip_GetTimerValue(const uint32 Instance)
  373. {
  374. #if (PDB_ADC_IP_DEV_ERROR_DETECT == STD_ON)
  375. DevAssert(Instance < PDB_INSTANCE_COUNT);
  376. #endif /* (PDB_ADC_IP_DEV_ERROR_DETECT == STD_ON) */
  377. const PDB_Type * const Base = PdbBase[Instance];
  378. return ((Base->CNT & PDB_CNT_CNT_MASK) >> PDB_CNT_CNT_SHIFT);
  379. }
  380. /*FUNCTION**********************************************************************
  381. *
  382. * Function Name : Pdb_Adc_Ip_LoadRegValues
  383. * Description : This function sets the LDOK bit.
  384. * Writing one to this bit updates the internal registers MOD, IDLY, CHnDLYm and
  385. * POyDLY with the values written to their buffers. The MOD, IDLY,
  386. * CHnDLYm and POyDLY take effect according to the load mode settings.
  387. *
  388. * After one is written to the LDOK bit, the values in the buffers of above mentioned
  389. * registers are not effective and cannot be written until the values in the
  390. * buffers are loaded into their internal registers. The moment when this happens
  391. * depends on the value of the LDMOD register. Only when this register is in it's
  392. * default state(0), the load operation will happen immediately. Please check the
  393. * reference manual for more information.
  394. * The LDOK can be written only when the the PDB is enabled or as alone with it. It is
  395. * automatically cleared either when the values in the buffers are loaded into the
  396. * internal registers or when the PDB is disabled.
  397. *
  398. * @implements Pdb_Adc_Ip_LoadRegValues_Activity
  399. * END**************************************************************************/
  400. void Pdb_Adc_Ip_LoadRegValues(const uint32 Instance)
  401. {
  402. #if (PDB_ADC_IP_DEV_ERROR_DETECT == STD_ON)
  403. DevAssert(Instance < PDB_INSTANCE_COUNT);
  404. #endif /* (PDB_ADC_IP_DEV_ERROR_DETECT == STD_ON) */
  405. PDB_Type * const Base = PdbBase[Instance];
  406. #if (PDB_ADC_IP_DEV_ERROR_DETECT == STD_ON)
  407. /* PDB must be enabled in order to load register values */
  408. DevAssert((Base->SC & PDB_SC_PDBEN_MASK) != 0u);
  409. #endif /* (PDB_ADC_IP_DEV_ERROR_DETECT == STD_ON) */
  410. SchM_Enter_Adc_ADC_EXCLUSIVE_AREA_39();
  411. Base->SC |= PDB_SC_LDOK_MASK;
  412. SchM_Exit_Adc_ADC_EXCLUSIVE_AREA_39();
  413. }
  414. /*FUNCTION**********************************************************************
  415. *
  416. * Function Name : Pdb_Adc_Ip_SetModulus
  417. * Description : This function sets the PDB Modulus value.
  418. * When the counter reaches the setting value, it is automatically reset to zero.
  419. * When in continuous mode, the counter begins to increase again.
  420. * Note: This function writes in an internal buffer. Depending on the
  421. * value of the LDMOD register, it might be necessary to call
  422. * Pdb_Adc_Ip_LoadRegValues in order to update the value of the register.
  423. * The value of the register can be changed only when the PDB module is enabled.
  424. *
  425. * @implements Pdb_Adc_Ip_SetModulus_Activity
  426. * END**************************************************************************/
  427. void Pdb_Adc_Ip_SetModulus(const uint32 Instance, const uint16 ModVal)
  428. {
  429. #if (PDB_ADC_IP_DEV_ERROR_DETECT == STD_ON)
  430. DevAssert(Instance < PDB_INSTANCE_COUNT);
  431. #endif /* (PDB_ADC_IP_DEV_ERROR_DETECT == STD_ON) */
  432. PDB_Type * const Base = PdbBase[Instance];
  433. uint32 ModReg;
  434. SchM_Enter_Adc_ADC_EXCLUSIVE_AREA_48();
  435. ModReg = Base->MOD;
  436. ModReg &= ~(PDB_MOD_MOD_MASK);
  437. ModReg |= PDB_MOD_MOD(ModVal);
  438. Base->MOD = ModReg;
  439. SchM_Exit_Adc_ADC_EXCLUSIVE_AREA_48();
  440. }
  441. /*FUNCTION**********************************************************************
  442. *
  443. * Function Name : Pdb_Adc_Ip_ConfigAdcPretriggers
  444. * Description : This function configures the back to back modes, delay enable
  445. * and output enable settings for all pretriggers on the selected channel.
  446. *
  447. * @implements Pdb_Adc_Ip_ConfigAdcPretriggers_Activity
  448. * END**************************************************************************/
  449. void Pdb_Adc_Ip_ConfigAdcPretriggers(const uint32 Instance, const uint8 ChanIdx, const Pdb_Adc_Ip_PretriggersConfigType * const Config)
  450. {
  451. #if (PDB_ADC_IP_DEV_ERROR_DETECT == STD_ON)
  452. DevAssert(Instance < PDB_INSTANCE_COUNT);
  453. DevAssert(ChanIdx < PDB_CH_COUNT);
  454. DevAssert(Config != NULL_PTR);
  455. #endif /* (PDB_ADC_IP_DEV_ERROR_DETECT == STD_ON) */
  456. PDB_Type * const Base = PdbBase[Instance];
  457. SchM_Enter_Adc_ADC_EXCLUSIVE_AREA_41();
  458. Pdb_Adc_HwAcc_ConfigAdcPretriggers(Base, ChanIdx, Config);
  459. SchM_Exit_Adc_ADC_EXCLUSIVE_AREA_41();
  460. }
  461. /*FUNCTION**********************************************************************
  462. *
  463. * Function Name : Pdb_Adc_Ip_GetAdcPretriggerFlags
  464. * Description : This function gets all ADC pretrigger flags from the selected channel.
  465. *
  466. * @implements Pdb_Adc_Ip_GetAdcPretriggerFlags_Activity
  467. * END**************************************************************************/
  468. uint32 Pdb_Adc_Ip_GetAdcPretriggerFlags(const uint32 Instance, const uint8 ChanIdx)
  469. {
  470. #if (PDB_ADC_IP_DEV_ERROR_DETECT == STD_ON)
  471. DevAssert(Instance < PDB_INSTANCE_COUNT);
  472. DevAssert(ChanIdx < PDB_CH_COUNT);
  473. #endif /* (PDB_ADC_IP_DEV_ERROR_DETECT == STD_ON) */
  474. const PDB_Type * const Base = PdbBase[Instance];
  475. uint32 Result;
  476. Result = Base->CH[ChanIdx].S;
  477. Result = (Result & PDB_S_CF_MASK) >> PDB_S_CF_SHIFT;
  478. return Result;
  479. }
  480. /*FUNCTION**********************************************************************
  481. *
  482. * Function Name : Pdb_Adc_Ip_ClearAdcPretriggerFlags
  483. * Description : This function clears the ADC pretrigger channel flags selected
  484. * by pretriggMask from channel channel.
  485. *
  486. * @implements Pdb_Adc_Ip_ClearAdcPretriggerFlags_Activity
  487. * END**************************************************************************/
  488. void Pdb_Adc_Ip_ClearAdcPretriggerFlags(const uint32 Instance, const uint8 ChanIdx, const uint16 PretriggMask)
  489. {
  490. #if (PDB_ADC_IP_DEV_ERROR_DETECT == STD_ON)
  491. DevAssert(Instance < PDB_INSTANCE_COUNT);
  492. DevAssert(ChanIdx < PDB_CH_COUNT);
  493. #endif /* (PDB_ADC_IP_DEV_ERROR_DETECT == STD_ON) */
  494. PDB_Type * const Base = PdbBase[Instance];
  495. SchM_Enter_Adc_ADC_EXCLUSIVE_AREA_46();
  496. /* Write 0 to clear */
  497. Pdb_Adc_HwAcc_ClearAdcPretriggerFlags(Base, ChanIdx, PretriggMask);
  498. SchM_Exit_Adc_ADC_EXCLUSIVE_AREA_46();
  499. }
  500. /*FUNCTION**********************************************************************
  501. *
  502. * Function Name : Pdb_Adc_Ip_SetAdcPretriggerBackToBack
  503. * Description : This function sets back to back mode for the selected
  504. * pretrigger on the given channel.
  505. *
  506. * @implements Pdb_Adc_Ip_SetAdcPretriggerBackToBack_Activity
  507. * END**************************************************************************/
  508. void Pdb_Adc_Ip_SetAdcPretriggerBackToBack(const uint32 Instance, const uint8 ChanIdx, const uint8 PretriggIdx, const boolean Value)
  509. {
  510. #if (PDB_ADC_IP_DEV_ERROR_DETECT == STD_ON)
  511. DevAssert(Instance < PDB_INSTANCE_COUNT);
  512. DevAssert(ChanIdx < PDB_CH_COUNT);
  513. DevAssert(PretriggIdx < PDB_DLY_COUNT);
  514. #endif /* (PDB_ADC_IP_DEV_ERROR_DETECT == STD_ON) */
  515. PDB_Type * const Base = PdbBase[Instance];
  516. uint32 Mask = (uint32)1u << PretriggIdx;
  517. Mask = PDB_C1_BB(Mask);
  518. SchM_Enter_Adc_ADC_EXCLUSIVE_AREA_42();
  519. Pdb_Adc_HwAcc_SetAdcPretriggerMask(Base, ChanIdx, Mask, Value);
  520. SchM_Exit_Adc_ADC_EXCLUSIVE_AREA_42();
  521. }
  522. /*FUNCTION**********************************************************************
  523. *
  524. * Function Name : Pdb_Adc_Ip_SetAdcPretriggerEnable
  525. * Description : This function enables or disables the selected pretrigger on
  526. * the given channel.
  527. *
  528. * @implements Pdb_Adc_Ip_SetAdcPretriggerEnable_Activity
  529. * END**************************************************************************/
  530. void Pdb_Adc_Ip_SetAdcPretriggerEnable(const uint32 Instance, const uint8 ChanIdx, const uint8 PretriggIdx, const boolean Value)
  531. {
  532. #if (PDB_ADC_IP_DEV_ERROR_DETECT == STD_ON)
  533. DevAssert(Instance < PDB_INSTANCE_COUNT);
  534. DevAssert(ChanIdx < PDB_CH_COUNT);
  535. DevAssert(PretriggIdx < PDB_DLY_COUNT);
  536. #endif /* (PDB_ADC_IP_DEV_ERROR_DETECT == STD_ON) */
  537. PDB_Type * const Base = PdbBase[Instance];
  538. uint32 Mask = (uint32)1u << PretriggIdx;
  539. Mask = PDB_C1_EN(Mask);
  540. SchM_Enter_Adc_ADC_EXCLUSIVE_AREA_43();
  541. Pdb_Adc_HwAcc_SetAdcPretriggerMask(Base, ChanIdx, Mask, Value);
  542. SchM_Exit_Adc_ADC_EXCLUSIVE_AREA_43();
  543. }
  544. /*FUNCTION**********************************************************************
  545. *
  546. * Function Name : Pdb_Adc_Ip_SetAdcPretriggerDelayEnable
  547. * Description : This function sets the delay enable value for the selected
  548. * pretrigger on the given channel.
  549. *
  550. * @implements Pdb_Adc_Ip_SetAdcPretriggerDelayEnable_Activity
  551. * END**************************************************************************/
  552. void Pdb_Adc_Ip_SetAdcPretriggerDelayEnable(const uint32 Instance, const uint8 ChanIdx, const uint8 PretriggIdx, const boolean Value)
  553. {
  554. #if (PDB_ADC_IP_DEV_ERROR_DETECT == STD_ON)
  555. DevAssert(Instance < PDB_INSTANCE_COUNT);
  556. DevAssert(ChanIdx < PDB_CH_COUNT);
  557. DevAssert(PretriggIdx < PDB_DLY_COUNT);
  558. #endif /* (PDB_ADC_IP_DEV_ERROR_DETECT == STD_ON) */
  559. PDB_Type * const Base = PdbBase[Instance];
  560. uint32 Mask = (uint32)1u << PretriggIdx;
  561. Mask = PDB_C1_TOS(Mask);
  562. SchM_Enter_Adc_ADC_EXCLUSIVE_AREA_44();
  563. Pdb_Adc_HwAcc_SetAdcPretriggerMask(Base, ChanIdx, Mask, Value);
  564. SchM_Exit_Adc_ADC_EXCLUSIVE_AREA_44();
  565. }
  566. /*FUNCTION**********************************************************************
  567. *
  568. * Function Name : Pdb_Adc_Ip_SetAdcPretriggerDelayValue
  569. * Description : This function sets the pretrigger delay value.
  570. * Note: This function writes in an internal buffer. Depending on the
  571. * value of the LDMOD register, it might be necessary to call
  572. * Pdb_Adc_Ip_LoadRegValues in order to update the value of the register.
  573. * The value of the register can be changed only when the PDB module is enabled.
  574. *
  575. * @implements Pdb_Adc_Ip_SetAdcPretriggerDelayValue_Activity
  576. * END**************************************************************************/
  577. void Pdb_Adc_Ip_SetAdcPretriggerDelayValue(const uint32 Instance, const uint8 ChanIdx, const uint8 PretriggIdx, const uint16 DelayValue)
  578. {
  579. #if (PDB_ADC_IP_DEV_ERROR_DETECT == STD_ON)
  580. DevAssert(Instance < PDB_INSTANCE_COUNT);
  581. DevAssert(ChanIdx < PDB_CH_COUNT);
  582. DevAssert(PretriggIdx < PDB_DLY_COUNT);
  583. #endif /* (PDB_ADC_IP_DEV_ERROR_DETECT == STD_ON) */
  584. PDB_Type * const Base = PdbBase[Instance];
  585. Base->CH[ChanIdx].DLY[PretriggIdx] = PDB_DLY_DLY(DelayValue);
  586. }
  587. /*FUNCTION**********************************************************************
  588. *
  589. * Function Name : Pdb_Adc_Ip_DisableAndClearPdb
  590. * Description : This function disables PDB module and clears all channels
  591. * configuration and status registers.
  592. *
  593. * @implements Pdb_Adc_Ip_DisableAndClearPdb_Activity
  594. * END**************************************************************************/
  595. void Pdb_Adc_Ip_DisableAndClearPdb(const uint32 Instance)
  596. {
  597. #if (PDB_ADC_IP_DEV_ERROR_DETECT == STD_ON)
  598. DevAssert(Instance < PDB_INSTANCE_COUNT);
  599. #endif /* (PDB_ADC_IP_DEV_ERROR_DETECT == STD_ON) */
  600. PDB_Type * const Base = PdbBase[Instance];
  601. uint8 ChanIdx;
  602. const Pdb_Adc_Ip_PretriggersConfigType PdbPretriggsConfig = { 0u, 0u, 0u };
  603. SchM_Enter_Adc_ADC_EXCLUSIVE_AREA_40();
  604. Pdb_Adc_HwAcc_DisablePdb(Base);
  605. Pdb_Adc_HwAcc_SetContinuousMode(Base, FALSE);
  606. SchM_Exit_Adc_ADC_EXCLUSIVE_AREA_40();
  607. for (ChanIdx = 0U; ChanIdx < PDB_CH_COUNT; ChanIdx++)
  608. {
  609. PDB_ADC_ResetChannel(Base, ChanIdx, &PdbPretriggsConfig);
  610. }
  611. }
  612. /*FUNCTION*********************************************************************
  613. *
  614. * Function Name : Pdb_Adc_Ip_IRQHandler
  615. * Description : Handles Pdb sequence error interrupt.
  616. *
  617. * @implements Pdb_Adc_Ip_IRQHandler_Activity
  618. *END*************************************************************************/
  619. /* The IAR build wants to see function prototypes */
  620. void Pdb_Adc_Ip_IRQHandler(const uint32 Instance);
  621. void Pdb_Adc_Ip_IRQHandler(const uint32 Instance)
  622. {
  623. #if (PDB_ADC_IP_DEV_ERROR_DETECT == STD_ON)
  624. DevAssert(Instance < PDB_INSTANCE_COUNT);
  625. #endif /* (PDB_ADC_IP_DEV_ERROR_DETECT == STD_ON) */
  626. PDB_Type * const Base = PdbBase[Instance];
  627. uint8 ChanIdx;
  628. uint16 SeqErrMask;
  629. /* Check if the Pdb unit is initialized, if the interrupt is not NULL
  630. * first since all channels use the same callback and if sequence error
  631. * interrupt is enabled. */
  632. if ((PdbAdcState[Instance].Init == TRUE) &&
  633. (PdbAdcState[Instance].SeqErrNotification != NULL_PTR) &&
  634. ((Base->SC & PDB_SC_PDBEIE_MASK) != 0u)\
  635. )
  636. {
  637. for (ChanIdx = 0u; ChanIdx < PDB_CH_COUNT; ChanIdx++)
  638. {
  639. SeqErrMask = (uint16) ((Base->CH[ChanIdx].S & PDB_S_ERR_MASK) >> PDB_S_ERR_SHIFT);
  640. if (SeqErrMask != 0u)
  641. {
  642. PdbAdcState[Instance].SeqErrNotification(ChanIdx, SeqErrMask);
  643. }
  644. }
  645. }
  646. for (ChanIdx = 0u; ChanIdx < PDB_CH_COUNT; ChanIdx++)
  647. {
  648. /* Clear all sequence error flags triggered from the current channel
  649. * by writing 0 to raised bits. */
  650. Base->CH[ChanIdx].S &= ~(PDB_S_ERR_MASK);
  651. }
  652. }
  653. static inline void PDB_ADC_ResetChannel(PDB_Type * const Base, const uint8 ChanIdx, const Pdb_Adc_Ip_PretriggersConfigType * PdbPretriggsConfig)
  654. {
  655. SchM_Enter_Adc_ADC_EXCLUSIVE_AREA_45();
  656. Pdb_Adc_HwAcc_ConfigAdcPretriggers(Base, ChanIdx, PdbPretriggsConfig);
  657. SchM_Exit_Adc_ADC_EXCLUSIVE_AREA_45();
  658. SchM_Enter_Adc_ADC_EXCLUSIVE_AREA_47();
  659. Pdb_Adc_HwAcc_ClearAdcPretriggerFlags(Base, ChanIdx, 0xFFu);
  660. /* Clear all sequence error flags. */
  661. Base->CH[ChanIdx].S &= ~(PDB_S_ERR_MASK);
  662. SchM_Exit_Adc_ADC_EXCLUSIVE_AREA_47();
  663. }
  664. #if (STD_ON == FEATURE_PDB_HAS_INSTANCE_BACKTOBACK)
  665. static void PDB_ADC_ConfigInstanceBackToBack_TrustedCall(const boolean InstanceBackToBackEnable)
  666. {
  667. if(InstanceBackToBackEnable == TRUE)
  668. {
  669. IP_SIM->CHIPCTL |= SIM_CHIPCTL_PDB_BB_SEL_MASK;
  670. }
  671. else
  672. {
  673. IP_SIM->CHIPCTL &= ~SIM_CHIPCTL_PDB_BB_SEL_MASK;
  674. }
  675. }
  676. static void PDB_ADC_ConfigInstanceBackToBack(const boolean InstanceBackToBackEnable)
  677. {
  678. #if (STD_ON == PDB_ADC_IP_ENABLE_USER_MODE_SUPPORT)
  679. OsIf_Trusted_Call1param(PDB_ADC_ConfigInstanceBackToBack_TrustedCall,(InstanceBackToBackEnable));
  680. #else
  681. PDB_ADC_ConfigInstanceBackToBack_TrustedCall(InstanceBackToBackEnable);
  682. #endif
  683. }
  684. #endif /* (STD_ON == FEATURE_PDB_HAS_INSTANCE_BACKTOBACK) */
  685. #if (STD_ON == FEATURE_PDB_HAS_INTERCHANNEL_BACKTOBACK)
  686. static void PDB_ADC_ConfigInterChannelBackToBack_TrustedCall(const uint32 Instance, const boolean InterChannelBackToBackEnable)
  687. {
  688. if(InterChannelBackToBackEnable == TRUE)
  689. {
  690. if (0U == Instance)
  691. {
  692. IP_SIM->CHIPCTL |= SIM_CHIPCTL_PDB_BB_SEL_1_MASK;
  693. }
  694. else
  695. {
  696. IP_SIM->CHIPCTL |= SIM_CHIPCTL_PDB_BB_SEL_2_MASK;
  697. }
  698. }
  699. else
  700. {
  701. if (0U == Instance)
  702. {
  703. IP_SIM->CHIPCTL &= ~(SIM_CHIPCTL_PDB_BB_SEL_1_MASK);
  704. }
  705. else
  706. {
  707. IP_SIM->CHIPCTL &= ~(SIM_CHIPCTL_PDB_BB_SEL_2_MASK);
  708. }
  709. }
  710. }
  711. static void PDB_ADC_ConfigInterChannelBackToBack(const uint32 Instance, const boolean InterChannelBackToBackEnable)
  712. {
  713. #if (STD_ON == PDB_ADC_IP_ENABLE_USER_MODE_SUPPORT)
  714. OsIf_Trusted_Call2params(PDB_ADC_ConfigInterChannelBackToBack_TrustedCall,(Instance),(InterChannelBackToBackEnable));
  715. #else
  716. PDB_ADC_ConfigInterChannelBackToBack_TrustedCall(Instance, InterChannelBackToBackEnable);
  717. #endif
  718. }
  719. #endif /* (STD_ON == FEATURE_PDB_HAS_INTERCHANNEL_BACKTOBACK) */
  720. #define ADC_STOP_SEC_CODE
  721. #include "Adc_MemMap.h"
  722. /** @} */