MCI_LPC18xx.c 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011
  1. /* --------------------------------------------------------------------------
  2. * Copyright (c) 2013-2016 ARM Limited. All rights reserved.
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Licensed under the Apache License, Version 2.0 (the License); you may
  7. * not use this file except in compliance with the License.
  8. * You may obtain a copy of the License at
  9. *
  10. * www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing, software
  13. * distributed under the License is distributed on an AS IS BASIS, WITHOUT
  14. * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. * See the License for the specific language governing permissions and
  16. * limitations under the License.
  17. *
  18. * $Date: 02. March 2016
  19. * $Revision: V2.5
  20. *
  21. * Driver: Driver_MCI0
  22. * Configured: via RTE_Device.h configuration file
  23. * Project: MCI Driver for NXP LPC18xx
  24. * --------------------------------------------------------------------------
  25. * Use the following configuration settings in the middleware component
  26. * to connect to this driver.
  27. *
  28. * Configuration Setting Value
  29. * --------------------- -----
  30. * Connect to hardware via Driver_MCI# = 0
  31. * -------------------------------------------------------------------------- */
  32. /* Note:
  33. For designs that need to support legacy MMC cards in open-drain mode,
  34. an external pull-up controlled with a general purpose output and FET
  35. will be needed for the CMD line.
  36. */
  37. /* History:
  38. * Version 2.5
  39. * - Corrected PowerControl function for conditional Power full (driver must be initialized)
  40. * Version 2.4
  41. * - Updated initialization, uninitialization and power procedures
  42. * - IRQ processing optimized
  43. * - Data timeout handling corrected
  44. * - Include file definitions moved to header file
  45. * Version 2.3
  46. * - FIFO Threshold Watermark Register values corrected
  47. * Version 2.2
  48. * - High speed enabled under capabilities
  49. * - Block size handling added to SetupTransfer function
  50. * Version 2.1
  51. * - DMA descriptor handling corrected
  52. * - Minor functional corrections
  53. * - Card Detect event handling added
  54. * - SD_RST pin handling added
  55. * Version 2.0
  56. * - Updated to CMSIS Driver API V2.01
  57. * Version 1.1
  58. * - Based on API V1.10 (namespace prefix ARM_ added)
  59. * Version 1.0
  60. * - Initial release
  61. */
  62. #include "MCI_LPC18xx.h"
  63. #define ARM_MCI_DRV_VERSION ARM_DRIVER_VERSION_MAJOR_MINOR(2,5) /* driver version */
  64. /* External function (system_LPC18xx.c) used to get SDMMC peripheral clock */
  65. extern uint32_t GetClockFreq (uint32_t clk_src);
  66. static SDMMC_DMA_DESC SDMMC_DMA_Descriptor[SDMMC_DMA_DESC_CNT];
  67. static MCI_INFO MCI;
  68. /* Driver Version */
  69. static const ARM_DRIVER_VERSION DriverVersion = {
  70. ARM_MCI_API_VERSION,
  71. ARM_MCI_DRV_VERSION
  72. };
  73. /* Driver Capabilities */
  74. static const ARM_MCI_CAPABILITIES DriverCapabilities = {
  75. RTE_SD_CD_PIN_EN, /* cd_state */
  76. RTE_SD_CD_PIN_EN, /* cd_event */
  77. RTE_SD_WP_PIN_EN, /* wp_state */
  78. RTE_SD_POW_PIN_EN, /* vdd */
  79. 0, /* vdd_1v8 */
  80. 0, /* vccq */
  81. 0, /* vccq_1v8 */
  82. 0, /* vccq_1v2 */
  83. RTE_SDMMC_BUS_WIDTH_4, /* data_width_4 */
  84. RTE_SDMMC_BUS_WIDTH_4 && RTE_SDMMC_BUS_WIDTH_8, /* data_width_8 */
  85. 0, /* data_width_4_ddr */
  86. 0, /* data_width_8_ddr */
  87. 1, /* high_speed */
  88. 0, /* uhs_signaling */
  89. 0, /* uhs_tuning */
  90. 0, /* uhs_sdr50 */
  91. 0, /* uhs_sdr104 */
  92. 0, /* uhs_ddr50 */
  93. 0, /* uhs_driver_type_a */
  94. 0, /* uhs_driver_type_c */
  95. 0, /* uhs_driver_type_d */
  96. 1, /* sdio_interrupt */
  97. 1, /* read_wait */
  98. 0, /* suspend_resume */
  99. 0, /* mmc_interrupt */
  100. 0, /* mmc_boot */
  101. RTE_SD_RST_PIN_EN, /* rst_n */
  102. 0, /* ccs */
  103. 0 /* ccs_timeout */
  104. };
  105. /**
  106. \fn void SetupDMADescriptor (MCI_XFER *xfer)
  107. \brief Setup Internal DMA descriptors for data transfer
  108. */
  109. static void SetupDMADescriptor (MCI_XFER *xfer, bool first) {
  110. uint32_t i, n;
  111. for (i = 0; (i < SDMMC_DMA_DESC_CNT) && (xfer->cnt); i++) {
  112. n = (xfer->cnt > 7680) ? (7680) : (xfer->cnt);
  113. SDMMC_DMA_Descriptor[i].CtrlStat = SDMMC_DMA_DESC_OWN;
  114. SDMMC_DMA_Descriptor[i].BufSize = n;
  115. SDMMC_DMA_Descriptor[i].BufAddr1 = (uint32_t)xfer->buf;
  116. SDMMC_DMA_Descriptor[i].BufAddr2 = (uint32_t)xfer->buf + n;
  117. xfer->buf += n;
  118. xfer->cnt -= n;
  119. n = (xfer->cnt > 7680) ? (7680) : (xfer->cnt);
  120. if (n) {
  121. SDMMC_DMA_Descriptor[i].BufSize |= n << 13;
  122. xfer->buf += n;
  123. xfer->cnt -= n;
  124. }
  125. }
  126. if (xfer->cnt == 0) {
  127. SDMMC_DMA_Descriptor[i-1].CtrlStat |= SDMMC_DMA_DESC_LD;
  128. }
  129. if (first) {
  130. SDMMC_DMA_Descriptor[0].CtrlStat |= SDMMC_DMA_DESC_FS;
  131. }
  132. SDMMC_DMA_Descriptor[SDMMC_DMA_DESC_CNT-1].CtrlStat |= SDMMC_DMA_DESC_ER;
  133. }
  134. /**
  135. \fn ARM_DRIVER_VERSION GetVersion (void)
  136. \brief Get driver version.
  137. \return \ref ARM_DRIVER_VERSION
  138. */
  139. static ARM_DRIVER_VERSION GetVersion (void) {
  140. return DriverVersion;
  141. }
  142. /**
  143. \fn ARM_MCI_CAPABILITIES GetCapabilities (void)
  144. \brief Get driver capabilities.
  145. \return \ref ARM_MCI_CAPABILITIES
  146. */
  147. static ARM_MCI_CAPABILITIES GetCapabilities (void) {
  148. return DriverCapabilities;
  149. }
  150. /**
  151. \fn int32_t Initialize (ARM_MCI_SignalEvent_t cb_event)
  152. \brief Initialize the Memory Card Interface
  153. \param[in] cb_event Pointer to \ref ARM_MCI_SignalEvent
  154. \return \ref execution_status
  155. */
  156. static int32_t Initialize (ARM_MCI_SignalEvent_t cb_event) {
  157. if (MCI.flags & MCI_INIT) { return ARM_DRIVER_OK; }
  158. /* Enable GPIO register interface clock */
  159. LPC_CCU1->CLK_M3_GPIO_CFG |= CCU_CLK_CFG_AUTO | CCU_CLK_CFG_RUN;
  160. while (!(LPC_CCU1->CLK_M3_GPIO_STAT & CCU_CLK_STAT_RUN));
  161. /* Configure SD_CLK, SD_CMD and SD_DAT0 */
  162. if (RTE_SD_CLK_PORT == 0x10) {
  163. SCU_CLK_PinConfigure (RTE_SD_CLK_PIN, RTE_SD_CLK_FUNC |
  164. SCU_PIN_CFG_PULLUP_DIS |
  165. SCU_PIN_CFG_INPUT_BUFFER_EN |
  166. SCU_PIN_CFG_INPUT_FILTER_DIS);
  167. }
  168. else {
  169. SCU_PinConfigure(RTE_SD_CLK_PORT, RTE_SD_CLK_PIN, RTE_SD_CLK_FUNC |
  170. SCU_PIN_CFG_PULLUP_DIS |
  171. SCU_PIN_CFG_INPUT_BUFFER_EN |
  172. SCU_PIN_CFG_INPUT_FILTER_DIS);
  173. }
  174. SCU_PinConfigure(RTE_SD_CMD_PORT, RTE_SD_CMD_PIN, RTE_SD_CMD_FUNC |
  175. SCU_PIN_CFG_PULLUP_DIS |
  176. SCU_PIN_CFG_INPUT_BUFFER_EN |
  177. SCU_PIN_CFG_INPUT_FILTER_DIS);
  178. SCU_PinConfigure(RTE_SD_DAT0_PORT, RTE_SD_DAT0_PIN, RTE_SD_DAT0_FUNC |
  179. SCU_PIN_CFG_PULLUP_DIS |
  180. SCU_PIN_CFG_INPUT_BUFFER_EN |
  181. SCU_PIN_CFG_INPUT_FILTER_DIS);
  182. #if (RTE_SDMMC_BUS_WIDTH_4)
  183. /* SD_DAT[3..1] */
  184. SCU_PinConfigure(RTE_SD_DAT3_PORT, RTE_SD_DAT3_PIN, RTE_SD_DAT3_FUNC |
  185. SCU_PIN_CFG_PULLUP_DIS |
  186. SCU_PIN_CFG_INPUT_BUFFER_EN |
  187. SCU_PIN_CFG_INPUT_FILTER_DIS);
  188. SCU_PinConfigure(RTE_SD_DAT2_PORT, RTE_SD_DAT2_PIN, RTE_SD_DAT2_FUNC |
  189. SCU_PIN_CFG_PULLUP_DIS |
  190. SCU_PIN_CFG_INPUT_BUFFER_EN |
  191. SCU_PIN_CFG_INPUT_FILTER_DIS);
  192. SCU_PinConfigure(RTE_SD_DAT1_PORT, RTE_SD_DAT1_PIN, RTE_SD_DAT1_FUNC |
  193. SCU_PIN_CFG_PULLUP_DIS |
  194. SCU_PIN_CFG_INPUT_BUFFER_EN |
  195. SCU_PIN_CFG_INPUT_FILTER_DIS);
  196. #if (RTE_SDMMC_BUS_WIDTH_8)
  197. /* SD_DAT[7..4] */
  198. SCU_PinConfigure(RTE_SD_DAT4_PORT, RTE_SD_DAT4_PIN, RTE_SD_DAT4_FUNC |
  199. SCU_PIN_CFG_PULLUP_DIS |
  200. SCU_PIN_CFG_INPUT_BUFFER_EN |
  201. SCU_PIN_CFG_INPUT_FILTER_DIS);
  202. SCU_PinConfigure(RTE_SD_DAT5_PORT, RTE_SD_DAT5_PIN, RTE_SD_DAT5_FUNC |
  203. SCU_PIN_CFG_PULLUP_DIS |
  204. SCU_PIN_CFG_INPUT_BUFFER_EN |
  205. SCU_PIN_CFG_INPUT_FILTER_DIS);
  206. SCU_PinConfigure(RTE_SD_DAT6_PORT, RTE_SD_DAT6_PIN, RTE_SD_DAT6_FUNC |
  207. SCU_PIN_CFG_PULLUP_DIS |
  208. SCU_PIN_CFG_INPUT_BUFFER_EN |
  209. SCU_PIN_CFG_INPUT_FILTER_DIS);
  210. SCU_PinConfigure(RTE_SD_DAT7_PORT, RTE_SD_DAT7_PIN, RTE_SD_DAT7_FUNC |
  211. SCU_PIN_CFG_PULLUP_DIS |
  212. SCU_PIN_CFG_INPUT_BUFFER_EN |
  213. SCU_PIN_CFG_INPUT_FILTER_DIS);
  214. #endif /* RTE_SDMMC_BUS_WIDTH_8 */
  215. #endif /* RTE_SDMMC_BUS_WIDTH_4 */
  216. #if (RTE_SD_CD_PIN_EN)
  217. /* Configure SD_CD (Card Detect) Pin */
  218. SCU_PinConfigure(RTE_SD_CD_PORT, RTE_SD_CD_PIN, RTE_SD_CD_FUNC |
  219. SCU_PIN_CFG_PULLUP_DIS |
  220. SCU_PIN_CFG_INPUT_BUFFER_EN |
  221. SCU_PIN_CFG_INPUT_FILTER_DIS);
  222. #endif
  223. #if (RTE_SDIO_WP_PIN_EN)
  224. /* Configure SD_WP (Write Protect) Pin */
  225. SCU_PinConfigure(RTE_SD_WP_PORT, RTE_SD_WP_PIN, RTE_SD_WP_FUNC |
  226. SCU_PIN_CFG_PULLUP_DIS |
  227. SCU_PIN_CFG_INPUT_BUFFER_EN |
  228. SCU_PIN_CFG_INPUT_FILTER_DIS);
  229. #endif
  230. /* Configure SD_POW Pin */
  231. #if (RTE_SD_POW_PIN_EN)
  232. SCU_PinConfigure(RTE_SD_POW_PORT, RTE_SD_POW_PIN, RTE_SD_POW_FUNC |
  233. SCU_PIN_CFG_PULLUP_DIS |
  234. SCU_PIN_CFG_INPUT_BUFFER_EN |
  235. SCU_PIN_CFG_INPUT_FILTER_DIS);
  236. #endif
  237. /* Configure SD_RST Pin */
  238. #if (RTE_SD_RST_PIN_EN)
  239. SCU_PinConfigure(RTE_SD_RST_PORT, RTE_SD_RST_PIN, RTE_SD_RST_FUNC |
  240. SCU_PIN_CFG_PULLUP_DIS |
  241. SCU_PIN_CFG_INPUT_BUFFER_EN |
  242. SCU_PIN_CFG_INPUT_FILTER_DIS);
  243. #endif
  244. /* Connect SDIO base clock to PLL1 */
  245. LPC_CGU->BASE_SDIO_CLK = (0x01 << 11) | (SDIO_CLK_SEL_PLL1 << 24);
  246. /* Clear control structure */
  247. memset (&MCI, 0, sizeof (MCI_INFO));
  248. MCI.cb_event = cb_event;
  249. MCI.flags = MCI_INIT;
  250. return ARM_DRIVER_OK;
  251. }
  252. /**
  253. \fn int32_t Uninitialize (void)
  254. \brief De-initialize Memory Card Interface.
  255. \return \ref execution_status
  256. */
  257. static int32_t Uninitialize (void) {
  258. /* Change SDIO base clock from PLL1 to IRC */
  259. LPC_CGU->BASE_SDIO_CLK = (0x01 << 11) | (0x01 << 24);
  260. /* Unconfigure SD_CLK and SD_CMD and SD_DAT0 */
  261. if (RTE_SD_CLK_PORT == 0x10) {
  262. SCU_CLK_PinConfigure (RTE_SD_CLK_PIN, 0);
  263. }
  264. else {
  265. SCU_PinConfigure(RTE_SD_CLK_PORT, RTE_SD_CLK_PIN, 0);
  266. }
  267. SCU_PinConfigure(RTE_SD_CMD_PORT, RTE_SD_CMD_PIN, 0);
  268. SCU_PinConfigure(RTE_SD_DAT0_PORT, RTE_SD_DAT0_PIN, 0);
  269. #if (RTE_SDMMC_BUS_WIDTH_4)
  270. /* SD_DAT[3..1] */
  271. SCU_PinConfigure(RTE_SD_DAT1_PORT, RTE_SD_DAT1_PIN, 0);
  272. SCU_PinConfigure(RTE_SD_DAT2_PORT, RTE_SD_DAT2_PIN, 0);
  273. SCU_PinConfigure(RTE_SD_DAT3_PORT, RTE_SD_DAT3_PIN, 0);
  274. #if (RTE_SDMMC_BUS_WIDTH_8)
  275. /* SD_DAT[7..4] */
  276. SCU_PinConfigure(RTE_SD_DAT4_PORT, RTE_SD_DAT4_PIN, 0);
  277. SCU_PinConfigure(RTE_SD_DAT5_PORT, RTE_SD_DAT5_PIN, 0);
  278. SCU_PinConfigure(RTE_SD_DAT6_PORT, RTE_SD_DAT6_PIN, 0);
  279. SCU_PinConfigure(RTE_SD_DAT7_PORT, RTE_SD_DAT7_PIN, 0);
  280. #endif /* RTE_SDMMC_BUS_WIDTH_8 */
  281. #endif /* RTE_SDMMC_BUS_WIDTH_4 */
  282. /* Unconfigure SD_CD (Card Detect) Pin */
  283. #if (RTE_SD_CD_PIN_EN)
  284. SCU_PinConfigure(RTE_SD_CD_PORT, RTE_SD_CD_PIN, 0);
  285. #endif
  286. /* Unconfigure SD_WP (Write Protect) Pin */
  287. #if (RTE_SD_WP_PIN_EN)
  288. SCU_PinConfigure(RTE_SD_WP_PORT, RTE_SD_WP_PIN, 0);
  289. #endif
  290. /* Unconfigure SD_POW Pin */
  291. #if (RTE_SD_POW_PIN_EN)
  292. SCU_PinConfigure(RTE_SD_POW_PORT, RTE_SD_POW_PIN, 0);
  293. #endif
  294. /* Unconfigure SD_RST Pin */
  295. #if (RTE_SD_RST_PIN_EN)
  296. SCU_PinConfigure(RTE_SD_RST_PORT, RTE_SD_RST_PIN, 0);
  297. #endif
  298. MCI.flags = 0;
  299. return ARM_DRIVER_OK;
  300. }
  301. /**
  302. \fn int32_t PowerControl (ARM_POWER_STATE state)
  303. \brief Control Memory Card Interface Power.
  304. \param[in] state Power state \ref ARM_POWER_STATE
  305. \return \ref execution_status
  306. */
  307. static int32_t PowerControl (ARM_POWER_STATE state) {
  308. switch (state) {
  309. case ARM_POWER_OFF:
  310. /* Disable SDIO interrupts */
  311. NVIC_DisableIRQ(SDIO_IRQn);
  312. MCI.flags &= ~MCI_POWER;
  313. /* Clear status */
  314. MCI.status.command_active = 0U;
  315. MCI.status.command_timeout = 0U;
  316. MCI.status.command_error = 0U;
  317. MCI.status.transfer_active = 0U;
  318. MCI.status.transfer_timeout = 0U;
  319. MCI.status.transfer_error = 0U;
  320. MCI.status.sdio_interrupt = 0U;
  321. MCI.status.ccs = 0U;
  322. /* Reset peripheral */
  323. LPC_RGU->RESET_CTRL0 = RGU_RESET_CTRL0_SDIO_RST;
  324. __NOP();
  325. /* Disable SDIO interface clock */
  326. LPC_CCU2->CLK_SDIO_CFG = 0;
  327. LPC_CCU1->CLK_M3_SDIO_CFG = 0;
  328. break;
  329. case ARM_POWER_FULL:
  330. if ((MCI.flags & MCI_INIT) == 0U) { return ARM_DRIVER_ERROR; }
  331. if ((MCI.flags & MCI_POWER) != 0U) { return ARM_DRIVER_OK; }
  332. /* Clear response and transfer variables */
  333. MCI.response = NULL;
  334. MCI.xfer.cnt = NULL;
  335. /* Enable SDIO clocks */
  336. LPC_CCU1->CLK_M3_SDIO_CFG |= CCU_CLK_CFG_AUTO | CCU_CLK_CFG_RUN;
  337. while (!(LPC_CCU1->CLK_M3_SDIO_CFG & CCU_CLK_STAT_RUN));
  338. LPC_CCU2->CLK_SDIO_CFG |= CCU_CLK_CFG_AUTO | CCU_CLK_CFG_RUN;
  339. while (!(LPC_CCU2->CLK_SDIO_CFG & CCU_CLK_STAT_RUN));
  340. /* Reset controller, FIFO and DMA and wait until reset done */
  341. LPC_SDMMC->CTRL = SDMMC_CTRL_RESET_BITMASK;
  342. while (LPC_SDMMC->CTRL & SDMMC_CTRL_RESET_BITMASK);
  343. LPC_SDMMC->BMOD = SDMMC_BMOD_SWR;
  344. while (LPC_SDMMC->BMOD & SDMMC_BMOD_SWR);
  345. /* Enable internal DMAC interrupts */
  346. LPC_SDMMC->IDINTEN = SDMMC_IDINTEN_FBE |
  347. SDMMC_IDINTEN_DU ;
  348. /* Enable SD/MMC peripheral interrupts */
  349. LPC_SDMMC->INTMASK = SDMMC_INTMASK_RE |
  350. #if (RTE_SD_CD_PIN_EN)
  351. SDMMC_INTMASK_CDET |
  352. #endif
  353. SDMMC_INTMASK_CDONE |
  354. SDMMC_INTMASK_DTO |
  355. SDMMC_INTMASK_RCRC |
  356. SDMMC_INTMASK_DCRC |
  357. SDMMC_INTMASK_RTO |
  358. SDMMC_INTMASK_DRTO |
  359. SDMMC_INTMASK_SBE |
  360. SDMMC_INTMASK_EBE ;
  361. /* Enable Global Interrupt and select internal DMA for data transfer */
  362. LPC_SDMMC->CTRL = SDMMC_CTRL_INT_ENABLE | SDMMC_CTRL_USE_INTERNAL_DMAC;
  363. /* Set FIFO Threshold watermark */
  364. LPC_SDMMC->FIFOTH = SDMMC_FIFOTH_DMA_MTS(0) |
  365. SDMMC_FIFOTH_RX_WMARK(14) |
  366. SDMMC_FIFOTH_TX_WMARK(15) ;
  367. /* Set Bus Mode */
  368. LPC_SDMMC->BMOD = SDMMC_BMOD_DE;
  369. /* Set descriptor address */
  370. LPC_SDMMC->DBADDR = (uint32_t)&SDMMC_DMA_Descriptor;
  371. /* Enable SDMMC peripheral interrupts in NVIC */
  372. NVIC_ClearPendingIRQ(SDIO_IRQn);
  373. NVIC_EnableIRQ(SDIO_IRQn);
  374. MCI.flags |= MCI_POWER;
  375. break;
  376. default:
  377. return ARM_DRIVER_ERROR_UNSUPPORTED;
  378. }
  379. return ARM_DRIVER_OK;
  380. }
  381. /**
  382. \fn int32_t CardPower (uint32_t voltage)
  383. \brief Set Memory Card supply voltage.
  384. \param[in] voltage Memory Card supply voltage
  385. \return \ref execution_status
  386. */
  387. static int32_t CardPower (uint32_t voltage) {
  388. if (!(MCI.flags & MCI_POWER)) { return ARM_DRIVER_ERROR; }
  389. #if (RTE_SD_POW_PIN_EN)
  390. /* Power on/off is supported */
  391. switch (voltage & ARM_MCI_POWER_VDD_Msk) {
  392. case ARM_MCI_POWER_VDD_OFF:
  393. LPC_SDMMC->PWREN &= ~SDMMC_PWREN_POWER_ENABLE;
  394. return ARM_DRIVER_OK;
  395. case ARM_MCI_POWER_VDD_3V3:
  396. LPC_SDMMC->PWREN |= SDMMC_PWREN_POWER_ENABLE;
  397. return ARM_DRIVER_OK;
  398. default:
  399. break;
  400. }
  401. #endif
  402. return ARM_DRIVER_ERROR_UNSUPPORTED;
  403. }
  404. /**
  405. \fn int32_t ReadCD (void)
  406. \brief Read Card Detect (CD) state.
  407. \return 1:card detected, 0:card not detected, or error
  408. */
  409. static int32_t ReadCD (void) {
  410. if (!(MCI.flags & MCI_POWER)) { return ARM_DRIVER_ERROR; }
  411. #if (RTE_SD_CD_PIN_EN)
  412. return !(LPC_SDMMC->CDETECT & 1);
  413. #else
  414. return (0);
  415. #endif
  416. }
  417. /**
  418. \fn int32_t ReadWP (void)
  419. \brief Read Write Protect (WP) state.
  420. \return 1:write protected, 0:not write protected, or error
  421. */
  422. static int32_t ReadWP (void) {
  423. if (!(MCI.flags & MCI_POWER)) { return ARM_DRIVER_ERROR; }
  424. #if (RTE_SD_WP_PIN_EN)
  425. return (LPC_SDMMC->WRTPRT & 1);
  426. #else
  427. return (0);
  428. #endif
  429. }
  430. /**
  431. \fn int32_t SendCommand (uint32_t cmd,
  432. uint32_t arg,
  433. uint32_t flags,
  434. uint32_t *response)
  435. \brief Send Command to card and get the response.
  436. \param[in] cmd Memory Card command
  437. \param[in] arg Command argument
  438. \param[in] flags Command flags
  439. \param[out] response Pointer to buffer for response
  440. \return \ref execution_status
  441. */
  442. static int32_t SendCommand (uint32_t cmd, uint32_t arg, uint32_t flags, uint32_t *response) {
  443. if ((flags & MCI_RESPONSE_EXPECTED_Msk) && (response == NULL)) {
  444. return ARM_DRIVER_ERROR_PARAMETER;
  445. }
  446. if (!(MCI.flags & MCI_SETUP)) {
  447. return ARM_DRIVER_ERROR;
  448. }
  449. if (MCI.status.command_active) {
  450. return ARM_DRIVER_ERROR_BUSY;
  451. }
  452. MCI.status.command_active = 1;
  453. /* Set command register value */
  454. cmd = SDMMC_CMD_CMD_INDEX(cmd) | SDMMC_CMD_WAIT_PRVDATA_COMPLETE | SDMMC_CMD_START_CMD;
  455. if (flags & ARM_MCI_CARD_INITIALIZE) {
  456. cmd |= SDMMC_CMD_SEND_INITIALIZATION;
  457. }
  458. MCI.response = response;
  459. MCI.flags &= ~MCI_RESP_LONG;
  460. switch (flags & ARM_MCI_RESPONSE_Msk) {
  461. case ARM_MCI_RESPONSE_NONE:
  462. /* No response expected */
  463. MCI.response = NULL;
  464. break;
  465. case ARM_MCI_RESPONSE_SHORT:
  466. case ARM_MCI_RESPONSE_SHORT_BUSY:
  467. /* Short response expected */
  468. cmd |= SDMMC_CMD_RESPONSE_EXPECT;
  469. break;
  470. case ARM_MCI_RESPONSE_LONG:
  471. MCI.flags |= MCI_RESP_LONG;
  472. /* Long response expected */
  473. cmd |= SDMMC_CMD_RESPONSE_EXPECT | SDMMC_CMD_RESPONSE_LENGTH;
  474. break;
  475. }
  476. if (flags & ARM_MCI_RESPONSE_CRC) {
  477. cmd |= SDMMC_CMD_CHECK_RESPONSE_CRC;
  478. }
  479. if (flags & ARM_MCI_TRANSFER_DATA) {
  480. cmd |= SDMMC_CMD_DATA_EXPECTED;
  481. if (MCI.flags & MCI_WRITE) { cmd |= SDMMC_CMD_READ_WRITE; }
  482. if (MCI.flags & MCI_STREAM) { cmd |= SDMMC_CMD_TRANSFER_MODE; }
  483. MCI.status.transfer_active = 1;
  484. }
  485. /* Send the command */
  486. LPC_SDMMC->CMDARG = arg;
  487. LPC_SDMMC->CMD = cmd;
  488. return ARM_DRIVER_OK;
  489. }
  490. /**
  491. \fn int32_t SetupTransfer (uint8_t *data,
  492. uint32_t block_count,
  493. uint32_t block_size,
  494. uint32_t mode)
  495. \brief Setup read or write transfer operation.
  496. \param[in,out] data Pointer to data block(s) to be written or read
  497. \param[in] block_count Number of blocks
  498. \param[in] block_size Size of a block in bytes
  499. \param[in] mode Transfer mode
  500. \return \ref execution_status
  501. */
  502. static int32_t SetupTransfer (uint8_t *data, uint32_t block_count, uint32_t block_size, uint32_t mode) {
  503. if ((data == NULL) || (block_count == 0) || (block_size == 0)) return ARM_DRIVER_ERROR_PARAMETER;
  504. if (!(MCI.flags & MCI_SETUP)) {
  505. return ARM_DRIVER_ERROR;
  506. }
  507. if (MCI.status.transfer_active) {
  508. return ARM_DRIVER_ERROR_BUSY;
  509. }
  510. /* Remember if write or read transfer requested */
  511. if (mode & ARM_MCI_TRANSFER_WRITE) { MCI.flags |= MCI_WRITE; }
  512. else { MCI.flags &= ~MCI_WRITE; }
  513. /* Remember if stream or block transfer mode requested */
  514. if (mode & ARM_MCI_TRANSFER_STREAM) { MCI.flags |= MCI_STREAM; }
  515. else { MCI.flags &= ~MCI_STREAM; }
  516. MCI.xfer.buf = data;
  517. MCI.xfer.cnt = block_count * block_size;
  518. LPC_SDMMC->BLKSIZ = block_size;
  519. LPC_SDMMC->BYTCNT = MCI.xfer.cnt;
  520. SetupDMADescriptor (&MCI.xfer, true);
  521. return ARM_DRIVER_OK;
  522. }
  523. /**
  524. \fn int32_t AbortTransfer (void)
  525. \brief Abort current read/write data transfer.
  526. \return \ref execution_status
  527. */
  528. static int32_t AbortTransfer (void) {
  529. if (!(MCI.flags & MCI_SETUP)) { return ARM_DRIVER_ERROR; }
  530. /* Disable global interrupt */
  531. LPC_SDMMC->CTRL &= ~SDMMC_CTRL_INT_ENABLE;
  532. /* Reset Controller, FIFO and internal DMA */
  533. LPC_SDMMC->CTRL |= SDMMC_CTRL_CONTROLLER_RESET |
  534. SDMMC_CTRL_FIFO_RESET |
  535. SDMMC_CTRL_DMA_RESET ;
  536. /* Clear DMA Interrupt flags */
  537. LPC_SDMMC->IDSTS = SDMMC_IDSTS_TI |
  538. SDMMC_IDSTS_RI |
  539. SDMMC_IDSTS_FBE |
  540. SDMMC_IDSTS_DU |
  541. SDMMC_IDSTS_CES |
  542. SDMMC_IDSTS_NIS |
  543. SDMMC_IDSTS_AIS ;
  544. /* Clear RAW Interrupt flags */
  545. LPC_SDMMC->RINTSTS = 0xFFFF;
  546. MCI.status.command_active = 0;
  547. MCI.status.transfer_active = 0;
  548. MCI.status.sdio_interrupt = 0;
  549. MCI.status.ccs = 0;
  550. /* Enable global interrupt */
  551. LPC_SDMMC->CTRL |= SDMMC_CTRL_INT_ENABLE;
  552. return ARM_DRIVER_OK;
  553. }
  554. /**
  555. \fn int32_t Control (uint32_t control, uint32_t arg)
  556. \brief Control MCI Interface.
  557. \param[in] control Operation
  558. \param[in] arg Argument of operation (optional)
  559. \return \ref execution_status
  560. */
  561. static int32_t Control (uint32_t control, uint32_t arg) {
  562. uint32_t div, bps, pclk;
  563. if (!(MCI.flags & MCI_POWER)) { return ARM_DRIVER_ERROR; }
  564. switch (control) {
  565. case ARM_MCI_BUS_SPEED:
  566. /* Get peripheral clock and calculate clock divider */
  567. pclk = GetClockFreq (SDIO_CLK_SEL_PLL1);
  568. bps = arg;
  569. LPC_SDMMC->CLKENA &= ~SDMMC_CLKENA_CCLK_ENABLE;
  570. if (bps) {
  571. /* bps = pclk / (2 * div) */
  572. div = (pclk + bps - 1) / bps;
  573. if (div & 1) { div += 1; }
  574. bps = pclk / div;
  575. LPC_SDMMC->CLKSRC = SDMMC_CLKSRC_CLK_SOURCE (0);
  576. LPC_SDMMC->CLKDIV = SDMMC_CLKDIV_CLK_DIVIDER0 (div >> 1);
  577. LPC_SDMMC->CLKENA |= SDMMC_CLKENA_CCLK_ENABLE |
  578. SDMMC_CLKENA_CCLK_LOW_POWER;
  579. }
  580. /* Send "update clock registers" command and wait until finished */
  581. LPC_SDMMC->CMD = SDMMC_CMD_UPDATE_CLOCK_REGISTERS_ONLY |
  582. SDMMC_CMD_WAIT_PRVDATA_COMPLETE |
  583. SDMMC_CMD_START_CMD ;
  584. while (LPC_SDMMC->CMD & SDMMC_CMD_START_CMD);
  585. /* Bus speed configured */
  586. MCI.flags |= MCI_SETUP;
  587. return (bps);
  588. case ARM_MCI_BUS_SPEED_MODE:
  589. switch (arg) {
  590. case ARM_MCI_BUS_DEFAULT_SPEED:
  591. /* Speed mode up to 25/26MHz */
  592. case ARM_MCI_BUS_HIGH_SPEED:
  593. /* Speed mode up to 50MHz */
  594. return ARM_DRIVER_OK;
  595. default:
  596. break;
  597. }
  598. return ARM_DRIVER_ERROR_UNSUPPORTED;
  599. case ARM_MCI_BUS_CMD_MODE:
  600. /* Implement external pull-up control to support MMC cards in open-drain mode */
  601. /* Default mode is push-pull and is configured in Driver_MCI0.Initialize() */
  602. if (arg == ARM_MCI_BUS_CMD_PUSH_PULL) {
  603. /* Configure external circuit to work in push-pull mode */
  604. }
  605. else if (arg == ARM_MCI_BUS_CMD_OPEN_DRAIN) {
  606. /* Configure external circuit to work in open-drain mode */
  607. }
  608. else {
  609. return ARM_DRIVER_ERROR_UNSUPPORTED;
  610. }
  611. break;
  612. case ARM_MCI_BUS_DATA_WIDTH:
  613. LPC_SDMMC->CTYPE &= ~(SDMMC_CTYPE_CARD_WIDTH0 | SDMMC_CTYPE_CARD_WIDTH1);
  614. switch (arg) {
  615. case ARM_MCI_BUS_DATA_WIDTH_1:
  616. break;
  617. case ARM_MCI_BUS_DATA_WIDTH_4:
  618. LPC_SDMMC->CTYPE |= SDMMC_CTYPE_CARD_WIDTH0;
  619. break;
  620. case ARM_MCI_BUS_DATA_WIDTH_8:
  621. LPC_SDMMC->CTYPE |= SDMMC_CTYPE_CARD_WIDTH1;
  622. break;
  623. default:
  624. return ARM_DRIVER_ERROR_UNSUPPORTED;
  625. }
  626. break;
  627. #if (RTE_SD_RST_PIN_EN)
  628. case ARM_MCI_CONTROL_RESET:
  629. if (arg) {
  630. /* Assert RST_n pin */
  631. LPC_SDMMC->RST_N = 0;
  632. }
  633. else {
  634. /* Deassert RST_n pin */
  635. LPC_SDMMC->RST_N = 1;
  636. }
  637. break;
  638. #endif
  639. case ARM_MCI_CONTROL_CLOCK_IDLE:
  640. if (arg) {
  641. /* Clock generation enabled when idle */
  642. LPC_SDMMC->CLKENA &= ~SDMMC_CLKENA_CCLK_LOW_POWER;
  643. }
  644. else {
  645. /* Clock generation disabled when idle */
  646. LPC_SDMMC->CLKENA |= SDMMC_CLKENA_CCLK_LOW_POWER;
  647. }
  648. /* Send "update clock registers" command and wait until finished */
  649. LPC_SDMMC->CMD = SDMMC_CMD_UPDATE_CLOCK_REGISTERS_ONLY |
  650. SDMMC_CMD_WAIT_PRVDATA_COMPLETE |
  651. SDMMC_CMD_START_CMD ;
  652. while (LPC_SDMMC->CMD & SDMMC_CMD_START_CMD);
  653. break;
  654. case ARM_MCI_DATA_TIMEOUT:
  655. if (arg > 0xFFFFFF) {
  656. /* Max timeout @ 50MHz is ~335ms: this could cause */
  657. /* data timeout issues on slow devices */
  658. arg = 0xFFFFFF;
  659. }
  660. LPC_SDMMC->TMOUT = (arg << 8) | 0x40;
  661. break;
  662. case ARM_MCI_MONITOR_SDIO_INTERRUPT:
  663. MCI.status.sdio_interrupt = 0;
  664. LPC_SDMMC->INTMASK |= SDMMC_INTMASK_SDIO_INT_MASK;
  665. break;
  666. case ARM_MCI_CONTROL_READ_WAIT:
  667. if (arg) {
  668. /* Assert read wait */
  669. LPC_SDMMC->CTRL |= SDMMC_CTRL_READ_WAIT;
  670. }
  671. else {
  672. /* Clear read wait */
  673. LPC_SDMMC->CTRL &= ~SDMMC_CTRL_READ_WAIT;
  674. }
  675. break;
  676. case ARM_MCI_DRIVER_STRENGTH:
  677. default: return ARM_DRIVER_ERROR_UNSUPPORTED;
  678. }
  679. return ARM_DRIVER_OK;
  680. }
  681. /**
  682. \fn ARM_MCI_STATUS GetStatus (void)
  683. \brief Get MCI status.
  684. \return MCI status \ref ARM_MCI_STATUS
  685. */
  686. static ARM_MCI_STATUS GetStatus (void) {
  687. return MCI.status;
  688. }
  689. /**
  690. \fn SDIO_IRQHandler (void)
  691. \brief Abort current read/write data transfer.
  692. \return \ref MCI_STATUS execution status
  693. */
  694. void SDIO_IRQHandler (void) {
  695. uint32_t rintsts, idsts;
  696. uint32_t rintclr, idclr;
  697. uint32_t event;
  698. event = 0;
  699. rintclr = 0;
  700. idclr = 0;
  701. rintsts = LPC_SDMMC->RINTSTS;
  702. idsts = LPC_SDMMC->IDSTS;
  703. /* Abnormal Interrupt Summary */
  704. if (idsts & SDMMC_IDSTS_DU) {
  705. idclr |= SDMMC_IDSTS_DU;
  706. /* Descriptor Unavailable Interrupt */
  707. if (MCI.xfer.cnt) {
  708. SetupDMADescriptor (&MCI.xfer, false);
  709. LPC_SDMMC->PLDMND = 1;
  710. }
  711. }
  712. if (idsts & SDMMC_IDSTS_FBE) {
  713. idclr |= SDMMC_IDSTS_FBE;
  714. /* Fatal Bus Error Interrupt */
  715. event |= ARM_MCI_EVENT_TRANSFER_ERROR;
  716. }
  717. #if (RTE_SD_CD_PIN_EN)
  718. if (rintsts & SDMMC_RINTSTS_CDET) {
  719. rintclr |= SDMMC_RINTSTS_CDET;
  720. /* Card detect */
  721. if (LPC_SDMMC->CDETECT & 1) {
  722. event |= ARM_MCI_EVENT_CARD_REMOVED;
  723. }
  724. else {
  725. event |= ARM_MCI_EVENT_CARD_INSERTED;
  726. }
  727. }
  728. #endif
  729. if (rintsts & SDMMC_RINT_ERR_SDIO_Msk) {
  730. if (rintsts & SDMMC_RINTSTS_RE) {
  731. rintclr |= SDMMC_RINTSTS_RE;
  732. /* Response error */
  733. event |= ARM_MCI_EVENT_COMMAND_ERROR;
  734. }
  735. if (rintsts & SDMMC_RINTSTS_RCRC) {
  736. rintclr |= SDMMC_RINTSTS_RCRC;
  737. /* Response CRC error */
  738. event |= ARM_MCI_EVENT_COMMAND_ERROR;
  739. }
  740. if (rintsts & SDMMC_RINTSTS_DCRC) {
  741. rintclr |= SDMMC_RINTSTS_DCRC;
  742. /* Data CRC error */
  743. event |= ARM_MCI_EVENT_TRANSFER_ERROR;
  744. }
  745. if (rintsts & SDMMC_RINTSTS_RTO_BAR) {
  746. rintclr |= SDMMC_RINTSTS_RTO_BAR;
  747. /* Response time-out/Boot Ack Received */
  748. event |= ARM_MCI_EVENT_COMMAND_TIMEOUT;
  749. }
  750. if (rintsts & SDMMC_RINTSTS_DRTO_BDS) {
  751. rintclr |= SDMMC_RINTSTS_DRTO_BDS;
  752. /* Data read time-out / Boot Data Start */
  753. /* Card has not sent data within the time-out period */
  754. event |= ARM_MCI_EVENT_TRANSFER_TIMEOUT;
  755. }
  756. if (rintsts & SDMMC_RINTSTS_HLE) {
  757. rintclr |= SDMMC_RINTSTS_HLE;
  758. /* Hardware locked error (command buffer full) */
  759. event |= ARM_MCI_EVENT_COMMAND_ERROR;
  760. }
  761. if (rintsts & SDMMC_RINTSTS_SBE) {
  762. rintclr |= SDMMC_RINTSTS_SBE;
  763. /* Start-bit error */
  764. event |= ARM_MCI_EVENT_TRANSFER_ERROR;
  765. }
  766. if (rintsts & SDMMC_RINTSTS_EBE) {
  767. rintclr |= SDMMC_RINTSTS_EBE;
  768. /* End-bit error (read)/write no CRC */
  769. event |= ARM_MCI_EVENT_TRANSFER_ERROR;
  770. }
  771. if (rintsts & SDMMC_RINTSTS_SDIO_INTERRUPT) {
  772. rintclr |= SDMMC_RINTSTS_SDIO_INTERRUPT;
  773. /* Interrupt from SDIO card */
  774. event |= ARM_MCI_EVENT_SDIO_INTERRUPT;
  775. MCI.status.sdio_interrupt = 1;
  776. /* Disable interrupt (must be re-enabled using Control) */
  777. LPC_SDMMC->INTMASK &= ~SDMMC_INTMASK_SDIO_INT_MASK;
  778. }
  779. }
  780. if (rintsts & SDMMC_RINTSTS_CDONE) {
  781. rintclr |= SDMMC_RINTSTS_CDONE;
  782. /* Command done */
  783. event |= ARM_MCI_EVENT_COMMAND_COMPLETE;
  784. if (MCI.response) {
  785. /* Read response registers */
  786. MCI.response[0] = LPC_SDMMC->RESP0;
  787. if (MCI.flags & MCI_RESP_LONG) {
  788. MCI.response[1] = LPC_SDMMC->RESP1;
  789. MCI.response[2] = LPC_SDMMC->RESP2;
  790. MCI.response[3] = LPC_SDMMC->RESP3;
  791. }
  792. }
  793. }
  794. if (rintsts & SDMMC_RINTSTS_DTO) {
  795. rintclr |= SDMMC_RINTSTS_DTO;
  796. /* Data transfer over */
  797. event |= ARM_MCI_EVENT_TRANSFER_COMPLETE;
  798. }
  799. LPC_SDMMC->RINTSTS = rintclr;
  800. LPC_SDMMC->IDSTS = idclr;
  801. if (event & MCI_TRANSFER_EVENT_Msk) {
  802. MCI.status.transfer_active = 0;
  803. if (MCI.cb_event) {
  804. if (event & ARM_MCI_EVENT_TRANSFER_ERROR) {
  805. (MCI.cb_event)(ARM_MCI_EVENT_TRANSFER_ERROR);
  806. }
  807. else if (event & ARM_MCI_EVENT_TRANSFER_TIMEOUT) {
  808. (MCI.cb_event)(ARM_MCI_EVENT_TRANSFER_TIMEOUT);
  809. }
  810. else {
  811. (MCI.cb_event)(ARM_MCI_EVENT_TRANSFER_COMPLETE);
  812. }
  813. }
  814. }
  815. if (event & MCI_COMMAND_EVENT_Msk) {
  816. MCI.status.command_active = 0;
  817. if (MCI.cb_event) {
  818. if (event & ARM_MCI_EVENT_COMMAND_ERROR) {
  819. (MCI.cb_event)(ARM_MCI_EVENT_COMMAND_ERROR);
  820. }
  821. else if (event & ARM_MCI_EVENT_COMMAND_TIMEOUT) {
  822. (MCI.cb_event)(ARM_MCI_EVENT_COMMAND_TIMEOUT);
  823. }
  824. else {
  825. (MCI.cb_event)(ARM_MCI_EVENT_COMMAND_COMPLETE);
  826. }
  827. }
  828. }
  829. if (event & MCI_CONTROL_EVENT_Msk) {
  830. if (MCI.cb_event) {
  831. (MCI.cb_event)(event & MCI_CONTROL_EVENT_Msk);
  832. }
  833. }
  834. }
  835. /* MCI Driver Control Block */
  836. ARM_DRIVER_MCI Driver_MCI0 = {
  837. GetVersion,
  838. GetCapabilities,
  839. Initialize,
  840. Uninitialize,
  841. PowerControl,
  842. CardPower,
  843. ReadCD,
  844. ReadWP,
  845. SendCommand,
  846. SetupTransfer,
  847. AbortTransfer,
  848. Control,
  849. GetStatus
  850. };