hs_mmcsd.h 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304
  1. /**
  2. * \file hs_mmcsd.h
  3. *
  4. * \brief HS MMC/SD APIs and macros.
  5. *
  6. * This file contains the driver API prototypes and macro definitions.
  7. */
  8. /*
  9. * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/
  10. */
  11. /*
  12. * Redistribution and use in source and binary forms, with or without
  13. * modification, are permitted provided that the following conditions
  14. * are met:
  15. *
  16. * Redistributions of source code must retain the above copyright
  17. * notice, this list of conditions and the following disclaimer.
  18. *
  19. * Redistributions in binary form must reproduce the above copyright
  20. * notice, this list of conditions and the following disclaimer in the
  21. * documentation and/or other materials provided with the
  22. * distribution.
  23. *
  24. * Neither the name of Texas Instruments Incorporated nor the names of
  25. * its contributors may be used to endorse or promote products derived
  26. * from this software without specific prior written permission.
  27. *
  28. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  29. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  30. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  31. * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  32. * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  33. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  34. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  35. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  36. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  37. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  38. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  39. *
  40. */
  41. #ifndef __HS_MMCSD_H__
  42. #define __HS_MMCSD_H__
  43. #include "hw_hs_mmcsd.h"
  44. #include "hw_types.h"
  45. #ifdef __cplusplus
  46. extern "C" {
  47. #endif
  48. /*****************************************************************************/
  49. /*
  50. ** Macros that can be passed to configure Standby mode
  51. */
  52. #define HS_MMCSD_STANDBY_FORCE (MMCHS_SYSCONFIG_STANDBYMODE_FORCE << MMCHS_SYSCONFIG_STANDBYMODE_SHIFT)
  53. #define HS_MMCSD_STANDBY_NONE (MMCHS_SYSCONFIG_STANDBYMODE_NOIDLE << MMCHS_SYSCONFIG_STANDBYMODE_SHIFT)
  54. #define HS_MMCSD_STANDBY_SMART (MMCHS_SYSCONFIG_STANDBYMODE_SMART << MMCHS_SYSCONFIG_STANDBYMODE_SHIFT)
  55. #define HS_MMCSD_STANDBY_SMARTWAKE (MMCHS_SYSCONFIG_STANDBYMODE_SMARTWAKE << MMCHS_SYSCONFIG_STANDBYMODE_SHIFT)
  56. /*
  57. ** Macros that can be passed to configure clock activity during wake up period
  58. */
  59. #define HS_MMCSD_CLOCK_OFF (MMCHS_SYSCONFIG_CLOCKACTIVITY_NONE << MMCHS_SYSCONFIG_CLOCKACTIVITY_SHIFT)
  60. #define HS_MMCSD_FCLK_OFF (MMCHS_SYSCONFIG_CLOCKACTIVITY_OCP << MMCHS_SYSCONFIG_CLOCKACTIVITY_SHIFT)
  61. #define HS_MMCSD_ICLK_OFF (MMCHS_SYSCONFIG_CLOCKACTIVITY_FUNC << MMCHS_SYSCONFIG_CLOCKACTIVITY_SHIFT)
  62. #define HS_MMCSD_CLOCK_ON (MMCHS_SYSCONFIG_CLOCKACTIVITY_BOTH << MMCHS_SYSCONFIG_CLOCKACTIVITY_SHIFT)
  63. /*
  64. ** Macros that can be passed to configure idle modes
  65. */
  66. #define HS_MMCSD_SMARTIDLE_FORCE (MMCHS_SYSCONFIG_SIDLEMODE_FORCE << MMCHS_SYSCONFIG_SIDLEMODE_SHIFT)
  67. #define HS_MMCSD_SMARTIDLE_NONE (MMCHS_SYSCONFIG_SIDLEMODE_NOIDLE << MMCHS_SYSCONFIG_SIDLEMODE_SHIFT)
  68. #define HS_MMCSD_SMARTIDLE_SMART (MMCHS_SYSCONFIG_SIDLEMODE_SMART << MMCHS_SYSCONFIG_SIDLEMODE_SHIFT)
  69. #define HS_MMCSD_SMARTIDLE_SMARTWAKE (MMCHS_SYSCONFIG_SIDLEMODE_SMARTWAKE << MMCHS_SYSCONFIG_SIDLEMODE_SHIFT)
  70. /*
  71. ** Macros that can be passed to configure wakeup modes
  72. */
  73. #define HS_MMCSD_WAKEUP_ENABLE (MMCHS_SYSCONFIG_ENAWAKEUP_ENABLED << MMCHS_SYSCONFIG_ENAWAKEUP_SHIFT)
  74. #define HS_MMCSD_WAKEUP_DISABLE (MMCHS_SYSCONFIG_ENAWAKEUP_DISABLED << MMCHS_SYSCONFIG_ENAWAKEUP_SHIFT)
  75. /*
  76. ** Macros that can be passed to configure auto idle modes
  77. */
  78. #define HS_MMCSD_AUTOIDLE_ENABLE (MMCHS_SYSCONFIG_AUTOIDLE_ON << MMCHS_SYSCONFIG_AUTOIDLE_SHIFT)
  79. #define HS_MMCSD_AUTOIDLE_DISABLE (MMCHS_SYSCONFIG_AUTOIDLE_OFF << MMCHS_SYSCONFIG_AUTOIDLE_SHIFT)
  80. /*****************************************************************************/
  81. /*
  82. ** Macros that can be used for SD controller DMA request configuration
  83. */
  84. #define HS_MMCSD_DMAREQ_EDGETRIG (MMCHS_CON_SDMA_LNE_EARLYDEASSERT << MMCHS_CON_DMA_LNE_SHIFT)
  85. #define HS_MMCSD_DMAREQ_LVLTRIG (MMCHS_CON_SDMA_LNE_LATEDEASSERT << MMCHS_CON_DMA_LNE_SHIFT)
  86. /*
  87. ** Macros that can be used for SD controller dual rate configuration
  88. */
  89. #define HS_MMCSD_DUALRATE_ENABLE (MMCHS_CON_DDR_DDRMODE << MMCHS_CON_DDR_SHIFT)
  90. #define HS_MMCSD_DUALRATE_DISABLE (MMCHS_CON_DDR_NORMALMODE << MMCHS_CON_DDR_SHIFT)
  91. /*
  92. ** Macros that can be used for selecting the bus/data width
  93. */
  94. #define HS_MMCSD_BUS_WIDTH_8BIT (0x8)
  95. #define HS_MMCSD_BUS_WIDTH_4BIT (0x4)
  96. #define HS_MMCSD_BUS_WIDTH_1BIT (0x1)
  97. /*
  98. ** Macros that can be used for starting/stopping a init stream
  99. */
  100. #define HS_MMCSD_INIT_START (MMCHS_CON_INIT_INITSTREAM << MMCHS_CON_INIT_SHIFT)
  101. #define HS_MMCSD_INIT_STOP (MMCHS_CON_INIT_NOINIT << MMCHS_CON_INIT_SHIFT)
  102. /*
  103. ** Macros that can be used for setting drain type
  104. */
  105. #define HS_MMCSD_OPENDRAIN (MMCHS_CON_OD_OPENDRAIN << MMCHS_CON_OD_SHIFT)
  106. /*
  107. ** Macros that can be used for forming the MMC/SD command
  108. */
  109. /* Here\n
  110. ** cmd : SD/MMC command number enumeration
  111. ** type : specifies suspend upon CMD52 or resume upon CMD52 or abort upon CMD52/12.
  112. ** restype : no response, or response with or without busy
  113. ** rw : direction of data transfer
  114. */
  115. #define HS_MMCSD_CMD(cmd, type, restype, rw) (cmd << MMCHS_CMD_INDX_SHIFT | type | restype | rw )
  116. #define HS_MMCSD_NO_RESPONSE (MMCHS_CMD_RSP_TYPE_NORSP << MMCHS_CMD_RSP_TYPE_SHIFT)
  117. #define HS_MMCSD_136BITS_RESPONSE (MMCHS_CMD_RSP_TYPE_136BITS << MMCHS_CMD_RSP_TYPE_SHIFT)
  118. #define HS_MMCSD_48BITS_RESPONSE (MMCHS_CMD_RSP_TYPE_48BITS << MMCHS_CMD_RSP_TYPE_SHIFT)
  119. #define HS_MMCSD_48BITS_BUSY_RESPONSE (MMCHS_CMD_RSP_TYPE_48BITS_BUSY << MMCHS_CMD_RSP_TYPE_SHIFT)
  120. #define HS_MMCSD_CMD_TYPE_NORMAL (MMCHS_CMD_CMD_TYPE_NORMAL << MMCHS_CMD_CMD_TYPE_SHIFT)
  121. #define HS_MMCSD_CMD_TYPE_SUSPEND (MMCHS_CMD_CMD_TYPE_SUSPEND << MMCHS_CMD_CMD_TYPE_SHIFT)
  122. #define HS_MMCSD_CMD_TYPE_FUNCSEL (MMCHS_CMD_CMD_TYPE_FUNC_SELECT << MMCHS_CMD_CMD_TYPE_SHIFT)
  123. #define HS_MMCSD_CMD_TYPE_ABORT (MMCHS_CMD_CMD_TYPE_ABORT << MMCHS_CMD_CMD_TYPE_SHIFT)
  124. #define HS_MMCSD_CMD_DIR_READ (MMCHS_CMD_DDIR_READ << MMCHS_CMD_DDIR_SHIFT)
  125. #define HS_MMCSD_CMD_DIR_WRITE (MMCHS_CMD_DDIR_WRITE << MMCHS_CMD_DDIR_SHIFT)
  126. #define HS_MMCSD_CMD_DIR_DONTCARE (MMCHS_CMD_DDIR_WRITE << MMCHS_CMD_DDIR_SHIFT)
  127. /*
  128. ** Macros that can be used for checking the present state of the host controller
  129. */
  130. #define HS_MMCSD_CARD_WRITEPROT (MMCHS_PSTATE_WP)
  131. #define HS_MMCSD_CARD_INSERTED (MMCHS_PSTATE_CINS)
  132. #define HS_MMCSD_CARD_STABLE (MMCHS_PSTATE_CSS)
  133. #define HS_MMCSD_BUFFER_READABLE (MMCHS_PSTATE_BRE)
  134. #define HS_MMCSD_BUFFER_WRITEABLE (MMCHS_PSTATE_BWE)
  135. #define HS_MMCSD_READ_INPROGRESS (MMCHS_PSTATE_RTA)
  136. #define HS_MMCSD_WRITE_INPROGRESS (MMCHS_PSTATE_WTA)
  137. /*
  138. ** Macros that can be used for configuring the power and transfer parameters
  139. */
  140. #define HS_MMCSD_BUS_VOLT_1P8 (MMCHS_HCTL_SDVS_1V8 << MMCHS_HCTL_SDVS_SHIFT)
  141. #define HS_MMCSD_BUS_VOLT_3P0 (MMCHS_HCTL_SDVS_3V0 << MMCHS_HCTL_SDVS_SHIFT)
  142. #define HS_MMCSD_BUS_VOLT_3P3 (MMCHS_HCTL_SDVS_3V3 << MMCHS_HCTL_SDVS_SHIFT)
  143. #define HS_MMCSD_BUS_POWER_ON (MMCHS_HCTL_SDBP_PWRON << MMCHS_HCTL_SDBP_SHIFT)
  144. #define HS_MMCSD_BUS_POWER_OFF (MMCHS_HCTL_SDBP_PWROFF << MMCHS_HCTL_SDBP_SHIFT)
  145. #define HS_MMCSD_BUS_HIGHSPEED (MMCHS_HCTL_HSPE_HIGHSPEED << MMCHS_HCTL_HSPE_SHIFT)
  146. #define HS_MMCSD_BUS_STDSPEED (MMCHS_HCTL_HSPE_NORMALSPEED << MMCHS_HCTL_HSPE_SHIFT)
  147. /*
  148. ** Macros that can be used for setting the clock, timeout values
  149. */
  150. #define HS_MMCSD_DATA_TIMEOUT(n) ((((n) - 13) & 0xF) << MMCHS_SYSCTL_DTO_SHIFT)
  151. #define HS_MMCSD_CLK_DIVIDER(n) ((n & 0x3FF) << MMCHS_SYSCTL_CLKD_SHIFT)
  152. #define HS_MMCSD_CARDCLOCK_ENABLE (MMCHS_SYSCTL_CEN_ENABLE << MMCHS_SYSCTL_CEN_SHIFT)
  153. #define HS_MMCSD_CARDCLOCK_DISABLE (MMCHS_SYSCTL_CEN_DISABLE << MMCHS_SYSCTL_CEN_SHIFT)
  154. #define HS_MMCSD_INTCLOCK_ON (MMCHS_SYSCTL_ICE_OSCILLATE << MMCHS_SYSCTL_ICE_SHIFT)
  155. #define HS_MMCSD_INTCLOCK_OFF (MMCHS_SYSCTL_ICE_STOP << MMCHS_SYSCTL_ICE_SHIFT)
  156. /*
  157. ** Macros that can be used for resetting controller lines
  158. */
  159. #define HS_MMCSD_DATALINE_RESET (MMCHS_SYSCTL_SRD)
  160. #define HS_MMCSD_CMDLINE_RESET (MMCHS_SYSCTL_SRC)
  161. #define HS_MMCSD_ALL_RESET (MMCHS_SYSCTL_SRA)
  162. /*
  163. ** Macros that can be used for interrupt enable/disable and status get operations
  164. */
  165. #define HS_MMCSD_INTR_BADACCESS (MMCHS_IE_BADA_ENABLE)
  166. #define HS_MMCSD_INTR_CARDERROR (MMCHS_IE_CERR_ENABLE)
  167. #define HS_MMCSD_INTR_ADMAERROR (MMCHS_IE_ADMAE_ENABLE)
  168. #define HS_MMCSD_INTR_ACMD12ERR (MMCHS_IE_ACE_ENABLE)
  169. #define HS_MMCSD_INTR_DATABITERR (MMCHS_IE_DEB_ENABLE)
  170. #define HS_MMCSD_INTR_DATACRCERR (MMCHS_IE_DCRC_ENABLE)
  171. #define HS_MMCSD_INTR_DATATIMEOUT (MMCHS_IE_DTO_ENABLE)
  172. #define HS_MMCSD_INTR_CMDINDXERR (MMCHS_IE_CIE_ENABLE)
  173. #define HS_MMCSD_INTR_CMDBITERR (MMCHS_IE_CEB_ENABLE)
  174. #define HS_MMCSD_INTR_CMDCRCERR (MMCHS_IE_CCRC_ENABLE)
  175. #define HS_MMCSD_INTR_CMDTIMEOUT (MMCHS_IE_CTO_ENABLE)
  176. #define HS_MMCSD_INTR_CARDINS (MMCHS_IE_CINS_ENABLE)
  177. #define HS_MMCSD_INTR_BUFRDRDY (MMCHS_IE_BRR_ENABLE)
  178. #define HS_MMCSD_INTR_BUFWRRDY (MMCHS_IE_BWR_ENABLE)
  179. #define HS_MMCSD_INTR_TRNFCOMP (MMCHS_IE_TC_ENABLE)
  180. #define HS_MMCSD_INTR_CMDCOMP (MMCHS_IE_CC_ENABLE)
  181. #define HS_MMCSD_STAT_BADACCESS (MMCHS_STAT_BADA)
  182. #define HS_MMCSD_STAT_CARDERROR (MMCHS_STAT_CERR)
  183. #define HS_MMCSD_STAT_ADMAERROR (MMCHS_STAT_ADMAE)
  184. #define HS_MMCSD_STAT_ACMD12ERR (MMCHS_STAT_ACE)
  185. #define HS_MMCSD_STAT_DATABITERR (MMCHS_STAT_DEB)
  186. #define HS_MMCSD_STAT_DATACRCERR (MMCHS_STAT_DCRC)
  187. #define HS_MMCSD_STAT_ERR (MMCHS_STAT_ERRI)
  188. #define HS_MMCSD_STAT_DATATIMEOUT (MMCHS_STAT_DTO)
  189. #define HS_MMCSD_STAT_CMDINDXERR (MMCHS_STAT_CIE)
  190. #define HS_MMCSD_STAT_CMDBITERR (MMCHS_STAT_CEB)
  191. #define HS_MMCSD_STAT_CMDCRCERR (MMCHS_STAT_CCRC)
  192. #define HS_MMCSD_STAT_CMDTIMEOUT (MMCHS_STAT_CTO)
  193. #define HS_MMCSD_STAT_CARDINS (MMCHS_STAT_CINS)
  194. #define HS_MMCSD_STAT_BUFRDRDY (MMCHS_STAT_BRR)
  195. #define HS_MMCSD_STAT_BUFWRRDY (MMCHS_STAT_BWR)
  196. #define HS_MMCSD_STAT_TRNFCOMP (MMCHS_STAT_TC)
  197. #define HS_MMCSD_STAT_CMDCOMP (MMCHS_STAT_CC)
  198. #define HS_MMCSD_SIGEN_BADACCESS (MMCHS_ISE_BADA_SIGEN)
  199. #define HS_MMCSD_SIGEN_CARDERROR (MMCHS_ISE_CERR_SIGEN)
  200. #define HS_MMCSD_SIGEN_ADMAERROR (MMCHS_ISE_ADMAE_SIGEN)
  201. #define HS_MMCSD_SIGEN_ACMD12ERR (MMCHS_ISE_ACE_SIGEN)
  202. #define HS_MMCSD_SIGEN_DATABITERR (MMCHS_ISE_DEB_SIGEN)
  203. #define HS_MMCSD_SIGEN_DATACRCERR (MMCHS_ISE_DCRC_SIGEN)
  204. #define HS_MMCSD_SIGEN_DATATIMEOUT (MMCHS_ISE_DTO_SIGEN)
  205. #define HS_MMCSD_SIGEN_CMDINDXERR (MMCHS_ISE_CIE_SIGEN)
  206. #define HS_MMCSD_SIGEN_CMDBITERR (MMCHS_ISE_CEB_SIGEN)
  207. #define HS_MMCSD_SIGEN_CMDCRCERR (MMCHS_ISE_CCRC_SIGEN)
  208. #define HS_MMCSD_SIGEN_CMDTIMEOUT (MMCHS_ISE_CTO_SIGEN)
  209. #define HS_MMCSD_SIGEN_CARDINS (MMCHS_ISE_CINS_SIGEN)
  210. #define HS_MMCSD_SIGEN_BUFRDRDY (MMCHS_ISE_BRR_SIGEN)
  211. #define HS_MMCSD_SIGEN_BUFWRRDY (MMCHS_ISE_BWR_SIGEN)
  212. #define HS_MMCSD_SIGEN_TRNFCOMP (MMCHS_ISE_TC_SIGEN)
  213. #define HS_MMCSD_SIGEN_CMDCOMP (MMCHS_ISE_CC_SIGEN)
  214. /*
  215. ** Macros that can be used for checking the capabilites of the controller
  216. */
  217. #define HS_MMCSD_SUPPORT_VOLT_1P8 (MMCHS_CAPA_VS18)
  218. #define HS_MMCSD_SUPPORT_VOLT_3P0 (MMCHS_CAPA_VS30)
  219. #define HS_MMCSD_SUPPORT_VOLT_3P3 (MMCHS_CAPA_VS33)
  220. #define HS_MMCSD_SUPPORT_DMA (MMCHS_CAPA_DS)
  221. #define HS_MMCSD_SUPPORT_HIGHSPEED (MMCHS_CAPA_HSS)
  222. #define HS_MMCSD_SUPPORT_BLOCKLEN (MMCHS_CAPA_MBL)
  223. /*
  224. ** Structure to save the I2C context
  225. */
  226. typedef struct MMCSDContext {
  227. unsigned int capa;
  228. unsigned int systemConfig;
  229. unsigned int ctrlInfo;
  230. unsigned int hctl;
  231. unsigned int sysCtl;
  232. unsigned int pState;
  233. }MMCSDCONTEXT;
  234. /*
  235. ** Function prototypes
  236. */
  237. extern void HSMMCSDDataGet(unsigned int baseAddr, unsigned char *data, unsigned int len);
  238. extern unsigned int HSMMCSDIsIntClockStable(unsigned int baseAddr, unsigned int retry);
  239. extern unsigned int HSMMCSDIsXferComplete(unsigned int baseAddr, unsigned int retry);
  240. extern unsigned int HSMMCSDIsCmdComplete(unsigned int baseAddr, unsigned int retry);
  241. extern unsigned int HSMMCSDIntrStatusGet(unsigned int baseAddr, unsigned int flag);
  242. extern void HSMMCSDDataTimeoutSet(unsigned int baseAddr, unsigned int timeout);
  243. extern void HSMMCSDIntrStatusDisable(unsigned int baseAddr, unsigned int flag);
  244. extern void HSMMCSDIntrStatusEnable(unsigned int baseAddr, unsigned int flag);
  245. extern void HSMMCSDSupportedVoltSet(unsigned int baseAddr, unsigned int volt);
  246. extern void HSMMCSDIntrStatusClear(unsigned int baseAddr, unsigned int flag);
  247. extern void HSMMCSDSystemConfig(unsigned int baseAddr, unsigned int config);
  248. extern void HSMMCSDResponseGet(unsigned int baseAddr, unsigned int *rsp);
  249. extern void HSMMCSDBusWidthSet(unsigned int baseAddr, unsigned int width);
  250. extern void HSMMCSDBlkLenSet(unsigned int baseAddr, unsigned int blklen);
  251. extern void HSMMCSDBusVoltSet(unsigned int baseAddr, unsigned int volt);
  252. extern void HSMMCSDIntrEnable(unsigned int baseAddr, unsigned int flag);
  253. extern unsigned int HSMMCSDIsCardWriteProtected(unsigned int baseAddr);
  254. extern int HSMMCSDLinesReset(unsigned int baseAddr, unsigned int flag);
  255. extern int HSMMCSDBusPower(unsigned int baseAddr, unsigned int pwr);
  256. extern unsigned int HSMMCSDIsCardInserted(unsigned int baseAddr);
  257. extern unsigned int HSMMCSDIsHSupported(unsigned int baseAddr);
  258. extern int HSMMCSDInitStreamSend(unsigned int baseAddr);
  259. extern int HSMMCSDSoftReset(unsigned int baseAddr);
  260. extern int HSMMCSDBusFreqSet(unsigned int baseAddr, unsigned int freq_in,
  261. unsigned int freq_out, unsigned int bypass);
  262. extern void HSMMCSDCommandSend(unsigned int baseAddr, unsigned int cmd,
  263. unsigned int cmdarg, void *data,
  264. unsigned int nblks, unsigned int dmaEn);
  265. extern void MMCSDContextRestore(unsigned int mmcsdBase,
  266. MMCSDCONTEXT *contextPtr);
  267. extern void MMCSDContextSave(unsigned int mmcsdBase,
  268. MMCSDCONTEXT *contextPtr);
  269. #ifdef __cplusplus
  270. }
  271. #endif
  272. #endif