HAL_gpio.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548
  1. /**
  2. ******************************************************************************
  3. * @file HAL_gpio.c
  4. * @author IC Applications Department
  5. * @version V0.8
  6. * @date 2019_08_02
  7. * @brief This file provides all the GPIO firmware functions.
  8. ******************************************************************************
  9. * @copy
  10. *
  11. * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
  12. * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
  13. * TIME. AS A RESULT, HOLOCENE SHALL NOT BE HELD LIABLE FOR ANY
  14. * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
  15. * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
  16. * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
  17. *
  18. * <h2><center>&copy; COPYRIGHT 2016 HOLOCENE</center></h2>
  19. */
  20. /* Includes ------------------------------------------------------------------*/
  21. #include "HAL_gpio.h"
  22. #include "HAL_rcc.h"
  23. /** @addtogroup StdPeriph_Driver
  24. * @{
  25. */
  26. /** @defgroup GPIO
  27. * @brief GPIO driver modules
  28. * @{
  29. */
  30. /** @defgroup GPIO_Private_TypesDefinitions
  31. * @{
  32. */
  33. /**
  34. * @}
  35. */
  36. /** @defgroup GPIO_Private_Defines
  37. * @{
  38. */
  39. /* ------------ RCC registers bit address in the alias region ----------------*/
  40. #define AFIO_OFFSET (AFIO_BASE - PERIPH_BASE)
  41. /* --- EVENTCR Register -----*/
  42. /* Alias word address of EVOE bit */
  43. #define EVCR_OFFSET (AFIO_OFFSET + 0x00)
  44. #define EVOE_BitNumber ((uint8_t)0x07)
  45. #define EVCR_EVOE_BB (PERIPH_BB_BASE + (EVCR_OFFSET * 32) + (EVOE_BitNumber * 4))
  46. #define EVCR_PORTPINCONFIG_MASK ((uint16_t)0xFF80)
  47. #define LSB_MASK ((uint16_t)0xFFFF)
  48. #define DBGAFR_POSITION_MASK ((uint32_t)0x000F0000)
  49. #define DBGAFR_SWJCFG_MASK ((uint32_t)0xF0FFFFFF)
  50. #define DBGAFR_LOCATION_MASK ((uint32_t)0x00200000)
  51. #define DBGAFR_NUMBITS_MASK ((uint32_t)0x00100000)
  52. /**
  53. * @}
  54. */
  55. /** @defgroup GPIO_Private_Macros
  56. * @{
  57. */
  58. /**
  59. * @}
  60. */
  61. /** @defgroup GPIO_Private_Variables
  62. * @{
  63. */
  64. /**
  65. * @}
  66. */
  67. /** @defgroup GPIO_Private_FunctionPrototypes
  68. * @{
  69. */
  70. /**
  71. * @}
  72. */
  73. /** @defgroup GPIO_Private_Functions
  74. * @{
  75. */
  76. /**
  77. * @brief Deinitializes the GPIOx peripheral registers to their default
  78. * reset values.
  79. * @param GPIOx: where x can be (A..G) to select the GPIO peripheral.
  80. * @retval : None
  81. */
  82. void GPIO_DeInit(GPIO_TypeDef* GPIOx)
  83. {
  84. /* Check the parameters */
  85. assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
  86. switch (*(uint32_t*)&GPIOx)
  87. {
  88. case GPIOA_BASE:
  89. RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
  90. RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, DISABLE);
  91. break;
  92. case GPIOB_BASE:
  93. RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);
  94. RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, DISABLE);
  95. break;
  96. case GPIOC_BASE:
  97. RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOC, ENABLE);
  98. RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOC, DISABLE);
  99. break;
  100. case GPIOD_BASE:
  101. RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOD, ENABLE);
  102. RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOD, DISABLE);
  103. break;
  104. default:
  105. break;
  106. }
  107. }
  108. /**
  109. * @brief Initializes the GPIOx peripheral according to the specified
  110. * parameters in the GPIO_InitStruct.
  111. * @param GPIOx: where x can be (A..G) to select the GPIO peripheral.
  112. * @param GPIO_InitStruct: pointer to a GPIO_InitTypeDef structure that
  113. * contains the configuration information for the specified GPIO
  114. * peripheral.
  115. * @retval : None
  116. */
  117. void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct)
  118. {
  119. uint32_t currentmode = 0x00, currentpin = 0x00, pinpos = 0x00, pos = 0x00;
  120. uint32_t tmpreg = 0x00, pinmask = 0x00;
  121. /* Check the parameters */
  122. assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
  123. assert_param(IS_GPIO_MODE(GPIO_InitStruct->GPIO_Mode));
  124. assert_param(IS_GPIO_PIN(GPIO_InitStruct->GPIO_Pin));
  125. /*---------------------------- GPIO Mode Configuration -----------------------*/
  126. currentmode = ((uint32_t)GPIO_InitStruct->GPIO_Mode) & ((uint32_t)0x0F);
  127. if ((((uint32_t)GPIO_InitStruct->GPIO_Mode) & ((uint32_t)0x10)) != 0x00)
  128. {
  129. /* Check the parameters */
  130. assert_param(IS_GPIO_SPEED(GPIO_InitStruct->GPIO_Speed));
  131. /* Output mode */
  132. currentmode |= (uint32_t)GPIO_InitStruct->GPIO_Speed;
  133. }
  134. /*---------------------------- GPIO CRL Configuration ------------------------*/
  135. /* Configure the eight low port pins */
  136. if (((uint32_t)GPIO_InitStruct->GPIO_Pin & ((uint32_t)0x00FF)) != 0x00)
  137. {
  138. tmpreg = GPIOx->CRL;
  139. for (pinpos = 0x00; pinpos < 0x08; pinpos++)
  140. {
  141. pos = ((uint32_t)0x01) << pinpos;
  142. /* Get the port pins position */
  143. currentpin = (GPIO_InitStruct->GPIO_Pin) & pos;
  144. if (currentpin == pos)
  145. {
  146. pos = pinpos << 2;
  147. /* Clear the corresponding low control register bits */
  148. pinmask = ((uint32_t)0x0F) << pos;
  149. tmpreg &= ~pinmask;
  150. /* Write the mode configuration in the corresponding bits */
  151. tmpreg |= (currentmode << pos);
  152. /* Reset the corresponding ODR bit */
  153. if (GPIO_InitStruct->GPIO_Mode == GPIO_Mode_IPD)
  154. {
  155. GPIOx->BRR = (((uint32_t)0x01) << pinpos);
  156. }
  157. else
  158. {
  159. /* Set the corresponding ODR bit */
  160. if (GPIO_InitStruct->GPIO_Mode == GPIO_Mode_IPU)
  161. {
  162. GPIOx->BSRR = (((uint32_t)0x01) << pinpos);
  163. }
  164. }
  165. }
  166. }
  167. GPIOx->CRL = tmpreg;
  168. }
  169. /*---------------------------- GPIO CRH Configuration ------------------------*/
  170. /* Configure the eight high port pins */
  171. if (GPIO_InitStruct->GPIO_Pin > 0x00FF)
  172. {
  173. tmpreg = GPIOx->CRH;
  174. for (pinpos = 0x00; pinpos < 0x08; pinpos++)
  175. {
  176. pos = (((uint32_t)0x01) << (pinpos + 0x08));
  177. /* Get the port pins position */
  178. currentpin = ((GPIO_InitStruct->GPIO_Pin) & pos);
  179. if (currentpin == pos)
  180. {
  181. pos = pinpos << 2;
  182. /* Clear the corresponding high control register bits */
  183. pinmask = ((uint32_t)0x0F) << pos;
  184. tmpreg &= ~pinmask;
  185. /* Write the mode configuration in the corresponding bits */
  186. tmpreg |= (currentmode << pos);
  187. /* Reset the corresponding ODR bit */
  188. if (GPIO_InitStruct->GPIO_Mode == GPIO_Mode_IPD)
  189. {
  190. GPIOx->BRR = (((uint32_t)0x01) << (pinpos + 0x08));
  191. }
  192. /* Set the corresponding ODR bit */
  193. if (GPIO_InitStruct->GPIO_Mode == GPIO_Mode_IPU)
  194. {
  195. GPIOx->BSRR = (((uint32_t)0x01) << (pinpos + 0x08));
  196. }
  197. }
  198. }
  199. GPIOx->CRH = tmpreg;
  200. }
  201. /*---------------------------- GPIOE_CRH_EXT Configuration ------------------------*/
  202. if(GPIO_InitStruct->GPIO_Pin>>16) //说明是GPIOE的16~23位
  203. {
  204. GPIO_InitStruct->GPIO_Pin = GPIO_InitStruct->GPIO_Pin>>16;
  205. tmpreg = GPIOE->CRH_EXT;
  206. for (pinpos = 0x00; pinpos < 0x08; pinpos++)
  207. {
  208. pos = ((uint32_t)0x01) << pinpos;
  209. /* Get the port pins position */
  210. currentpin = (GPIO_InitStruct->GPIO_Pin) & pos;
  211. if (currentpin == pos)
  212. {
  213. pos = pinpos << 2;
  214. /* Clear the corresponding low control register bits */
  215. pinmask = ((uint32_t)0x0F) << pos;
  216. tmpreg &= ~pinmask;
  217. /* Write the mode configuration in the corresponding bits */
  218. tmpreg |= (currentmode << pos);
  219. /* Reset the corresponding ODR bit */
  220. if (GPIO_InitStruct->GPIO_Mode == GPIO_Mode_IPD)
  221. {
  222. GPIOx->BRR = (((uint32_t)0x01) << pinpos);
  223. }
  224. else
  225. {
  226. /* Set the corresponding ODR bit */
  227. if (GPIO_InitStruct->GPIO_Mode == GPIO_Mode_IPU)
  228. {
  229. GPIOx->BSRR = (((uint32_t)0x01) << pinpos);
  230. }
  231. }
  232. }
  233. }
  234. GPIOE->CRH_EXT = tmpreg;
  235. }
  236. }
  237. /**
  238. * @brief Fills each GPIO_InitStruct member with its default value.
  239. * @param GPIO_InitStruct : pointer to a GPIO_InitTypeDef structure
  240. * which will be initialized.
  241. * @retval : None
  242. */
  243. void GPIO_StructInit(GPIO_InitTypeDef* GPIO_InitStruct)
  244. {
  245. /* Reset GPIO init structure parameters values */
  246. GPIO_InitStruct->GPIO_Pin = GPIO_Pin_All;
  247. GPIO_InitStruct->GPIO_Speed = GPIO_Speed_2MHz;
  248. GPIO_InitStruct->GPIO_Mode = GPIO_Mode_IN_FLOATING;
  249. }
  250. /**
  251. * @brief Reads the specified input port pin.
  252. * @param GPIOx: where x can be (A..G) to select the GPIO peripheral.
  253. * @param GPIO_Pin: specifies the port bit to read.
  254. * This parameter can be GPIO_Pin_x where x can be (0..15).
  255. * @retval : The input port pin value.
  256. */
  257. uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
  258. {
  259. uint8_t bitstatus = 0x00;
  260. /* Check the parameters */
  261. assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
  262. assert_param(IS_GET_GPIO_PIN(GPIO_Pin));
  263. if ((GPIOx->IDR & GPIO_Pin) != (uint32_t)Bit_RESET)
  264. {
  265. bitstatus = (uint8_t)Bit_SET;
  266. }
  267. else
  268. {
  269. bitstatus = (uint8_t)Bit_RESET;
  270. }
  271. return bitstatus;
  272. }
  273. /**
  274. * @brief Reads the specified GPIO input data port.
  275. * @param GPIOx: where x can be (A..G) to select the GPIO peripheral.
  276. * @retval : GPIO input data port value.
  277. */
  278. uint16_t GPIO_ReadInputData(GPIO_TypeDef* GPIOx)
  279. {
  280. /* Check the parameters */
  281. assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
  282. return ((uint16_t)GPIOx->IDR);
  283. }
  284. /**
  285. * @brief Reads the specified output data port bit.
  286. * @param GPIOx: where x can be (A..G) to select the GPIO peripheral.
  287. * @param GPIO_Pin: specifies the port bit to read.
  288. * This parameter can be GPIO_Pin_x where x can be (0..15).
  289. * @retval : The output port pin value.
  290. */
  291. uint8_t GPIO_ReadOutputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
  292. {
  293. uint8_t bitstatus = 0x00;
  294. /* Check the parameters */
  295. assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
  296. assert_param(IS_GET_GPIO_PIN(GPIO_Pin));
  297. if ((GPIOx->ODR & GPIO_Pin) != (uint32_t)Bit_RESET)
  298. {
  299. bitstatus = (uint8_t)Bit_SET;
  300. }
  301. else
  302. {
  303. bitstatus = (uint8_t)Bit_RESET;
  304. }
  305. return bitstatus;
  306. }
  307. /**
  308. * @brief Reads the specified GPIO output data port.
  309. * @param GPIOx: where x can be (A..G) to select the GPIO peripheral.
  310. * @retval : GPIO output data port value.
  311. */
  312. uint16_t GPIO_ReadOutputData(GPIO_TypeDef* GPIOx)
  313. {
  314. /* Check the parameters */
  315. assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
  316. return ((uint16_t)GPIOx->ODR);
  317. }
  318. /**
  319. * @brief Sets the selected data port bits.
  320. * @param GPIOx: where x can be (A..G) to select the GPIO peripheral.
  321. * @param GPIO_Pin: specifies the port bits to be written.
  322. * This parameter can be any combination of GPIO_Pin_x where
  323. * x can be (0..15).
  324. * @retval : None
  325. */
  326. void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint32_t GPIO_Pin)
  327. {
  328. /* Check the parameters */
  329. assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
  330. assert_param(IS_GPIO_PIN(GPIO_Pin));
  331. if(GPIO_Pin>GPIO_Pin_15)GPIOE->BSRR_EXT=GPIO_Pin>>16;
  332. else
  333. GPIOx->BSRR = GPIO_Pin;
  334. }
  335. /**
  336. * @brief Clears the selected data port bits.
  337. * @param GPIOx: where x can be (A..G) to select the GPIO peripheral.
  338. * @param GPIO_Pin: specifies the port bits to be written.
  339. * This parameter can be any combination of GPIO_Pin_x where
  340. * x can be (0..15).
  341. * @retval : None
  342. */
  343. void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint32_t GPIO_Pin)
  344. {
  345. /* Check the parameters */
  346. assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
  347. assert_param(IS_GPIO_PIN(GPIO_Pin));
  348. GPIOx->BRR = GPIO_Pin;
  349. }
  350. /**
  351. * @brief Sets or clears the selected data port bit.
  352. * @param GPIOx: where x can be (A..G) to select the GPIO peripheral.
  353. * @param GPIO_Pin: specifies the port bit to be written.
  354. * This parameter can be one of GPIO_Pin_x where x can be (0..15).
  355. * @param BitVal: specifies the value to be written to the selected bit.
  356. * This parameter can be one of the BitAction enum values:
  357. * @arg Bit_RESET: to clear the port pin
  358. * @arg Bit_SET: to set the port pin
  359. * @retval : None
  360. */
  361. void GPIO_WriteBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, BitAction BitVal)
  362. {
  363. /* Check the parameters */
  364. assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
  365. assert_param(IS_GET_GPIO_PIN(GPIO_Pin));
  366. assert_param(IS_GPIO_BIT_ACTION(BitVal));
  367. if (BitVal != Bit_RESET)
  368. {
  369. GPIOx->BSRR = GPIO_Pin;
  370. }
  371. else
  372. {
  373. GPIOx->BRR = GPIO_Pin;
  374. }
  375. }
  376. /**
  377. * @brief Writes data to the specified GPIO data port.
  378. * @param GPIOx: where x can be (A..G) to select the GPIO peripheral.
  379. * @param PortVal: specifies the value to be written to the port output
  380. * data register.
  381. * @retval : None
  382. */
  383. void GPIO_Write(GPIO_TypeDef* GPIOx, uint16_t PortVal)
  384. {
  385. /* Check the parameters */
  386. assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
  387. GPIOx->ODR = PortVal;
  388. }
  389. /**
  390. * @brief Locks GPIO Pins configuration registers.
  391. * @param GPIOx: where x can be (A..G) to select the GPIO peripheral.
  392. * @param GPIO_Pin: specifies the port bit to be written.
  393. * This parameter can be any combination of GPIO_Pin_x where
  394. * x can be (0..15).
  395. * @retval : None
  396. */
  397. void GPIO_PinLockConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
  398. {
  399. uint32_t tmp = 0x00010000;
  400. /* Check the parameters */
  401. assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
  402. assert_param(IS_GPIO_PIN(GPIO_Pin));
  403. tmp |= GPIO_Pin;
  404. /* Set LCKK bit */
  405. GPIOx->LCKR = tmp;
  406. /* Reset LCKK bit */
  407. GPIOx->LCKR = GPIO_Pin;
  408. /* Set LCKK bit */
  409. GPIOx->LCKR = tmp;
  410. /* Read LCKK bit*/
  411. tmp = GPIOx->LCKR;
  412. /* Read LCKK bit*/
  413. tmp = GPIOx->LCKR;
  414. }
  415. /**
  416. * @brief Writes data to the specified GPIO data port.
  417. * @param GPIOx: where x can be (A, B, C, D ) to select the GPIO peripheral.
  418. * @param GPIO_PinSource: specifies the pin for the Alternate function.
  419. * This parameter can be GPIO_PinSourcex where x can be (0..15) for GPIOA, GPIOB, GPIOD
  420. * and (0..12) for GPIOC .
  421. * @param GPIO_AF: selects the pin to used as Alternate function.
  422. * This parameter can be one of the following value:
  423. * @arg GPIO_AF_0: SPI1, MC0, TIM17_BKIN, SWDIO,SWCLK,
  424. UART1
  425. * @arg GPIO_AF_1: UART1, TIM3_CH1, TIM3_CH2, TIM3_CH3,
  426. TIM3_CH4, I2C1
  427. * @arg GPIO_AF_2: TIM2_CH1_ETR, TIM2_CH2, TIM2_CH3,
  428. TIM2_CH3, TIM2_CH4, TIM1_BKIN,
  429. TIM1_CH1N, TIM1_CH1, TIM1_CH2,
  430. TIM1_CH3, TIM1_CH4, TIM1_ETR,
  431. TIM1_CH2N, TIM1_CH3N, TIM2_CH2,
  432. TIM1 6_BKIN, TIM16_CH1N, TIM17_CH1N,
  433. TIM1 6_CH1, TIM17_CH1
  434. * @arg GPIO_AF_4: TIM14_CH1, I2C1
  435. * @note The pin should already been configured in Alternate Function mode(AF)
  436. * using GPIO_InitStruct->GPIO_Mode = GPIO_Mode_AF
  437. * @note Refer to the Alternate function mapping table in the device datasheet
  438. * for the detailed mapping of the system and peripherals'alternate
  439. * function I/O pins.
  440. * @retval None
  441. */
  442. void GPIO_PinAFConfig(GPIO_TypeDef* GPIOx, uint32_t GPIO_Pin, uint8_t GPIO_AF)
  443. {
  444. uint32_t temp;
  445. unsigned char i;
  446. /* Check the parameters */
  447. assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
  448. assert_param(IS_GPIO_PIN_SOURCE(GPIO_PinSource));
  449. assert_param(IS_GPIO_AF(GPIO_AF));
  450. if(GPIO_Pin>>16) //说明是GPIOE的16~23位
  451. {
  452. temp = GPIO_Pin>>16;
  453. for(i=0;i<8;i++)
  454. {
  455. if(temp&0x01)
  456. {
  457. GPIOE->AFRH_EXT &= ~((uint32_t)0xF << ((uint32_t)(i<<2))); //AF配置占半字节,要x4,即<<2
  458. GPIOE->AFRH_EXT |= ((uint32_t)GPIO_AF << ((uint32_t)(i<<2)));
  459. }
  460. temp = temp>>1;
  461. }
  462. }
  463. if(GPIO_Pin&0XFF00) //说明是GPIOE的8~15位
  464. {
  465. temp = GPIO_Pin>>8;
  466. for(i=0;i<8;i++)
  467. {
  468. if(temp&0x01)
  469. {
  470. GPIOx->AFRH &= ~((uint32_t)0xF << ((uint32_t)(i<<2))); //AF配置占半字节,要x4,即<<2
  471. GPIOx->AFRH |= ((uint32_t)GPIO_AF << ((uint32_t)(i<<2)));
  472. }
  473. temp = temp>>1;
  474. }
  475. }
  476. if(GPIO_Pin&0XFF) //说明是GPIOE的0~7位
  477. {
  478. for(i=0;i<8;i++)
  479. {
  480. if(temp&0x01)
  481. {
  482. GPIOx->AFRL &= ~((uint32_t)0xF << ((uint32_t)(i<<2))); //AF配置占半字节,要x4,即<<2
  483. GPIOx->AFRL |= ((uint32_t)GPIO_AF << ((uint32_t)(i<<2)));
  484. }
  485. temp = temp>>1;
  486. }
  487. }
  488. }
  489. /**
  490. * @}
  491. */
  492. /**
  493. * @}
  494. */
  495. /**
  496. * @}
  497. */
  498. /*-------------------------(C) COPYRIGHT 2016 HOLOCENE ----------------------*/