mmcsd_core.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753
  1. /*
  2. * File : mmcsd_core.c
  3. * This file is part of RT-Thread RTOS
  4. * COPYRIGHT (C) 2006, RT-Thread Development Team
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation; either version 2 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License along
  17. * with this program; if not, write to the Free Software Foundation, Inc.,
  18. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  19. *
  20. * Change Logs:
  21. * Date Author Notes
  22. * 2011-07-25 weety first version
  23. */
  24. #include <rtthread.h>
  25. #include <drivers/mmcsd_core.h>
  26. #include <drivers/sd.h>
  27. #include <drivers/mmc.h>
  28. #include <drivers/sdio.h>
  29. #ifndef RT_MMCSD_STACK_SIZE
  30. #define RT_MMCSD_STACK_SIZE 1024
  31. #endif
  32. #ifndef RT_MMCSD_THREAD_PREORITY
  33. #if (RT_THREAD_PRIORITY_MAX == 32)
  34. #define RT_MMCSD_THREAD_PREORITY 0x16
  35. #else
  36. #define RT_MMCSD_THREAD_PREORITY 0x40
  37. #endif
  38. #endif
  39. //static struct rt_semaphore mmcsd_sem;
  40. static struct rt_thread mmcsd_detect_thread;
  41. static rt_uint8_t mmcsd_stack[RT_MMCSD_STACK_SIZE];
  42. static struct rt_mailbox mmcsd_detect_mb;
  43. static rt_uint32_t mmcsd_detect_mb_pool[4];
  44. static struct rt_mailbox mmcsd_hotpluge_mb;
  45. static rt_uint32_t mmcsd_hotpluge_mb_pool[4];
  46. void mmcsd_host_lock(struct rt_mmcsd_host *host)
  47. {
  48. rt_mutex_take(&host->bus_lock, RT_WAITING_FOREVER);
  49. }
  50. void mmcsd_host_unlock(struct rt_mmcsd_host *host)
  51. {
  52. rt_mutex_release(&host->bus_lock);
  53. }
  54. void mmcsd_req_complete(struct rt_mmcsd_host *host)
  55. {
  56. rt_sem_release(&host->sem_ack);
  57. }
  58. void mmcsd_send_request(struct rt_mmcsd_host *host, struct rt_mmcsd_req *req)
  59. {
  60. do {
  61. req->cmd->retries--;
  62. req->cmd->err = 0;
  63. req->cmd->mrq = req;
  64. if (req->data)
  65. {
  66. req->cmd->data = req->data;
  67. req->data->err = 0;
  68. req->data->mrq = req;
  69. if (req->stop)
  70. {
  71. req->data->stop = req->stop;
  72. req->stop->err = 0;
  73. req->stop->mrq = req;
  74. }
  75. }
  76. host->ops->request(host, req);
  77. rt_sem_take(&host->sem_ack, RT_WAITING_FOREVER);
  78. } while(req->cmd->err && (req->cmd->retries > 0));
  79. }
  80. rt_int32_t mmcsd_send_cmd(struct rt_mmcsd_host *host,
  81. struct rt_mmcsd_cmd *cmd,
  82. int retries)
  83. {
  84. struct rt_mmcsd_req req;
  85. rt_memset(&req, 0, sizeof(struct rt_mmcsd_req));
  86. rt_memset(cmd->resp, 0, sizeof(cmd->resp));
  87. cmd->retries = retries;
  88. req.cmd = cmd;
  89. cmd->data = RT_NULL;
  90. mmcsd_send_request(host, &req);
  91. return cmd->err;
  92. }
  93. rt_int32_t mmcsd_go_idle(struct rt_mmcsd_host *host)
  94. {
  95. rt_int32_t err;
  96. struct rt_mmcsd_cmd cmd;
  97. if (!controller_is_spi(host))
  98. {
  99. mmcsd_set_chip_select(host, MMCSD_CS_HIGH);
  100. mmcsd_delay_ms(1);
  101. }
  102. rt_memset(&cmd, 0, sizeof(struct rt_mmcsd_cmd));
  103. cmd.cmd_code = GO_IDLE_STATE;
  104. cmd.arg = 0;
  105. cmd.flags = RESP_SPI_R1 | RESP_NONE | CMD_BC;
  106. err = mmcsd_send_cmd(host, &cmd, 0);
  107. mmcsd_delay_ms(1);
  108. if (!controller_is_spi(host))
  109. {
  110. mmcsd_set_chip_select(host, MMCSD_CS_IGNORE);
  111. mmcsd_delay_ms(1);
  112. }
  113. return err;
  114. }
  115. rt_int32_t mmcsd_spi_read_ocr(struct rt_mmcsd_host *host,
  116. rt_int32_t high_capacity,
  117. rt_uint32_t *ocr)
  118. {
  119. struct rt_mmcsd_cmd cmd;
  120. rt_int32_t err;
  121. rt_memset(&cmd, 0, sizeof(struct rt_mmcsd_cmd));
  122. cmd.cmd_code = SPI_READ_OCR;
  123. cmd.arg = high_capacity ? (1 << 30) : 0;
  124. cmd.flags = RESP_SPI_R3;
  125. err = mmcsd_send_cmd(host, &cmd, 0);
  126. *ocr = cmd.resp[1];
  127. return err;
  128. }
  129. rt_int32_t mmcsd_all_get_cid(struct rt_mmcsd_host *host, rt_uint32_t *cid)
  130. {
  131. rt_int32_t err;
  132. struct rt_mmcsd_cmd cmd;
  133. rt_memset(&cmd, 0, sizeof(struct rt_mmcsd_cmd));
  134. cmd.cmd_code = ALL_SEND_CID;
  135. cmd.arg = 0;
  136. cmd.flags = RESP_R2 | CMD_BCR;
  137. err = mmcsd_send_cmd(host, &cmd, 3);
  138. if (err)
  139. return err;
  140. rt_memcpy(cid, cmd.resp, sizeof(rt_uint32_t) * 4);
  141. return 0;
  142. }
  143. rt_int32_t mmcsd_get_cid(struct rt_mmcsd_host *host, rt_uint32_t *cid)
  144. {
  145. rt_int32_t err, i;
  146. struct rt_mmcsd_req req;
  147. struct rt_mmcsd_cmd cmd;
  148. struct rt_mmcsd_data data;
  149. rt_uint32_t *buf = RT_NULL;
  150. if (!controller_is_spi(host))
  151. {
  152. if (!host->card)
  153. return -RT_ERROR;
  154. rt_memset(&cmd, 0, sizeof(struct rt_mmcsd_cmd));
  155. cmd.cmd_code = SEND_CID;
  156. cmd.arg = host->card->rca << 16;
  157. cmd.flags = RESP_R2 | CMD_AC;
  158. err = mmcsd_send_cmd(host, &cmd, 3);
  159. if (err)
  160. return err;
  161. rt_memcpy(cid, cmd.resp, sizeof(rt_uint32_t) * 4);
  162. return 0;
  163. }
  164. buf = (rt_uint32_t *)rt_malloc(16);
  165. if (!buf)
  166. {
  167. rt_kprintf("allocate memory failed\n");
  168. return -RT_ENOMEM;
  169. }
  170. rt_memset(&req, 0, sizeof(struct rt_mmcsd_req));
  171. rt_memset(&cmd, 0, sizeof(struct rt_mmcsd_cmd));
  172. rt_memset(&data, 0, sizeof(struct rt_mmcsd_data));
  173. req.cmd = &cmd;
  174. req.data = &data;
  175. cmd.cmd_code = SEND_CID;
  176. cmd.arg = 0;
  177. /* NOTE HACK: the RESP_SPI_R1 is always correct here, but we
  178. * rely on callers to never use this with "native" calls for reading
  179. * CSD or CID. Native versions of those commands use the R2 type,
  180. * not R1 plus a data block.
  181. */
  182. cmd.flags = RESP_SPI_R1 | RESP_R1 | CMD_ADTC;
  183. data.blksize = 16;
  184. data.blks = 1;
  185. data.flags = DATA_DIR_READ;
  186. data.buf = buf;
  187. /*
  188. * The spec states that CSR and CID accesses have a timeout
  189. * of 64 clock cycles.
  190. */
  191. data.timeout_ns = 0;
  192. data.timeout_clks = 64;
  193. mmcsd_send_request(host, &req);
  194. if (cmd.err || data.err)
  195. {
  196. rt_free(buf);
  197. return -RT_ERROR;
  198. }
  199. for (i = 0;i < 4;i++)
  200. cid[i] = buf[i];
  201. rt_free(buf);
  202. return 0;
  203. }
  204. rt_int32_t mmcsd_get_csd(struct rt_mmcsd_card *card, rt_uint32_t *csd)
  205. {
  206. rt_int32_t err, i;
  207. struct rt_mmcsd_req req;
  208. struct rt_mmcsd_cmd cmd;
  209. struct rt_mmcsd_data data;
  210. rt_uint32_t *buf = RT_NULL;
  211. if (!controller_is_spi(card->host))
  212. {
  213. rt_memset(&cmd, 0, sizeof(struct rt_mmcsd_cmd));
  214. cmd.cmd_code = SEND_CSD;
  215. cmd.arg = card->rca << 16;
  216. cmd.flags = RESP_R2 | CMD_AC;
  217. err = mmcsd_send_cmd(card->host, &cmd, 3);
  218. if (err)
  219. return err;
  220. rt_memcpy(csd, cmd.resp, sizeof(rt_uint32_t) * 4);
  221. return 0;
  222. }
  223. buf = (rt_uint32_t*)rt_malloc(16);
  224. if (!buf)
  225. {
  226. rt_kprintf("allocate memory failed\n");
  227. return -RT_ENOMEM;
  228. }
  229. rt_memset(&req, 0, sizeof(struct rt_mmcsd_req));
  230. rt_memset(&cmd, 0, sizeof(struct rt_mmcsd_cmd));
  231. rt_memset(&data, 0, sizeof(struct rt_mmcsd_data));
  232. req.cmd = &cmd;
  233. req.data = &data;
  234. cmd.cmd_code = SEND_CSD;
  235. cmd.arg = 0;
  236. /* NOTE HACK: the RESP_SPI_R1 is always correct here, but we
  237. * rely on callers to never use this with "native" calls for reading
  238. * CSD or CID. Native versions of those commands use the R2 type,
  239. * not R1 plus a data block.
  240. */
  241. cmd.flags = RESP_SPI_R1 | RESP_R1 | CMD_ADTC;
  242. data.blksize = 16;
  243. data.blks = 1;
  244. data.flags = DATA_DIR_READ;
  245. data.buf = buf;
  246. /*
  247. * The spec states that CSR and CID accesses have a timeout
  248. * of 64 clock cycles.
  249. */
  250. data.timeout_ns = 0;
  251. data.timeout_clks = 64;
  252. mmcsd_send_request(card->host, &req);
  253. if (cmd.err || data.err)
  254. {
  255. rt_free(buf);
  256. return -RT_ERROR;
  257. }
  258. for (i = 0;i < 4;i++)
  259. csd[i] = buf[i];
  260. rt_free(buf);
  261. return 0;
  262. }
  263. static rt_int32_t _mmcsd_select_card(struct rt_mmcsd_host *host,
  264. struct rt_mmcsd_card *card)
  265. {
  266. rt_int32_t err;
  267. struct rt_mmcsd_cmd cmd;
  268. rt_memset(&cmd, 0, sizeof(struct rt_mmcsd_cmd));
  269. cmd.cmd_code = SELECT_CARD;
  270. if (card)
  271. {
  272. cmd.arg = card->rca << 16;
  273. cmd.flags = RESP_R1 | CMD_AC;
  274. }
  275. else
  276. {
  277. cmd.arg = 0;
  278. cmd.flags = RESP_NONE | CMD_AC;
  279. }
  280. err = mmcsd_send_cmd(host, &cmd, 3);
  281. if (err)
  282. return err;
  283. return 0;
  284. }
  285. rt_int32_t mmcsd_select_card(struct rt_mmcsd_card *card)
  286. {
  287. return _mmcsd_select_card(card->host, card);
  288. }
  289. rt_int32_t mmcsd_deselect_cards(struct rt_mmcsd_card *card)
  290. {
  291. return _mmcsd_select_card(card->host, RT_NULL);
  292. }
  293. rt_int32_t mmcsd_spi_use_crc(struct rt_mmcsd_host *host, rt_int32_t use_crc)
  294. {
  295. struct rt_mmcsd_cmd cmd;
  296. rt_int32_t err;
  297. rt_memset(&cmd, 0, sizeof(struct rt_mmcsd_cmd));
  298. cmd.cmd_code = SPI_CRC_ON_OFF;
  299. cmd.flags = RESP_SPI_R1;
  300. cmd.arg = use_crc;
  301. err = mmcsd_send_cmd(host, &cmd, 0);
  302. if (!err)
  303. host->spi_use_crc = use_crc;
  304. return err;
  305. }
  306. rt_inline void mmcsd_set_iocfg(struct rt_mmcsd_host *host)
  307. {
  308. struct rt_mmcsd_io_cfg *io_cfg = &host->io_cfg;
  309. mmcsd_dbg("clock %uHz busmode %u powermode %u cs %u Vdd %u "
  310. "width %u \n",
  311. io_cfg->clock, io_cfg->bus_mode,
  312. io_cfg->power_mode, io_cfg->chip_select, io_cfg->vdd,
  313. io_cfg->bus_width);
  314. host->ops->set_iocfg(host, io_cfg);
  315. }
  316. /*
  317. * Control chip select pin on a host.
  318. */
  319. void mmcsd_set_chip_select(struct rt_mmcsd_host *host, rt_int32_t mode)
  320. {
  321. host->io_cfg.chip_select = mode;
  322. mmcsd_set_iocfg(host);
  323. }
  324. /*
  325. * Sets the host clock to the highest possible frequency that
  326. * is below "hz".
  327. */
  328. void mmcsd_set_clock(struct rt_mmcsd_host *host, rt_uint32_t clk)
  329. {
  330. if (clk < host->freq_min)
  331. {
  332. rt_kprintf("clock too low\n");
  333. }
  334. host->io_cfg.clock = clk;
  335. mmcsd_set_iocfg(host);
  336. }
  337. /*
  338. * Change the bus mode (open drain/push-pull) of a host.
  339. */
  340. void mmcsd_set_bus_mode(struct rt_mmcsd_host *host, rt_uint32_t mode)
  341. {
  342. host->io_cfg.bus_mode = mode;
  343. mmcsd_set_iocfg(host);
  344. }
  345. /*
  346. * Change data bus width of a host.
  347. */
  348. void mmcsd_set_bus_width(struct rt_mmcsd_host *host, rt_uint32_t width)
  349. {
  350. host->io_cfg.bus_width = width;
  351. mmcsd_set_iocfg(host);
  352. }
  353. void mmcsd_set_data_timeout(struct rt_mmcsd_data *data,
  354. const struct rt_mmcsd_card *card)
  355. {
  356. rt_uint32_t mult;
  357. if (card->card_type == CARD_TYPE_SDIO)
  358. {
  359. data->timeout_ns = 1000000000; /* SDIO card 1s */
  360. data->timeout_clks = 0;
  361. return;
  362. }
  363. /*
  364. * SD cards use a 100 multiplier rather than 10
  365. */
  366. mult = (card->card_type == CARD_TYPE_SD) ? 100 : 10;
  367. /*
  368. * Scale up the multiplier (and therefore the timeout) by
  369. * the r2w factor for writes.
  370. */
  371. if (data->flags & DATA_DIR_WRITE)
  372. mult <<= card->csd.r2w_factor;
  373. data->timeout_ns = card->tacc_ns * mult;
  374. data->timeout_clks = card->tacc_clks * mult;
  375. /*
  376. * SD cards also have an upper limit on the timeout.
  377. */
  378. if (card->card_type == CARD_TYPE_SD)
  379. {
  380. rt_uint32_t timeout_us, limit_us;
  381. timeout_us = data->timeout_ns / 1000;
  382. timeout_us += data->timeout_clks * 1000 /
  383. (card->host->io_cfg.clock / 1000);
  384. if (data->flags & DATA_DIR_WRITE)
  385. /*
  386. * The limit is really 250 ms, but that is
  387. * insufficient for some crappy cards.
  388. */
  389. limit_us = 300000;
  390. else
  391. limit_us = 100000;
  392. /*
  393. * SDHC cards always use these fixed values.
  394. */
  395. if (timeout_us > limit_us || card->flags & CARD_FLAG_SDHC)
  396. {
  397. data->timeout_ns = limit_us * 1000; /* SDHC card fixed 250ms */
  398. data->timeout_clks = 0;
  399. }
  400. }
  401. if (controller_is_spi(card->host))
  402. {
  403. if (data->flags & DATA_DIR_WRITE)
  404. {
  405. if (data->timeout_ns < 1000000000)
  406. data->timeout_ns = 1000000000; /* 1s */
  407. }
  408. else
  409. {
  410. if (data->timeout_ns < 100000000)
  411. data->timeout_ns = 100000000; /* 100ms */
  412. }
  413. }
  414. }
  415. /*
  416. * Mask off any voltages we don't support and select
  417. * the lowest voltage
  418. */
  419. rt_uint32_t mmcsd_select_voltage(struct rt_mmcsd_host *host, rt_uint32_t ocr)
  420. {
  421. int bit;
  422. extern int __rt_ffs(int value);
  423. ocr &= host->valid_ocr;
  424. bit = __rt_ffs(ocr);
  425. if (bit)
  426. {
  427. bit -= 1;
  428. ocr &= 3 << bit;
  429. host->io_cfg.vdd = bit;
  430. mmcsd_set_iocfg(host);
  431. }
  432. else
  433. {
  434. rt_kprintf("host doesn't support card's voltages\n");
  435. ocr = 0;
  436. }
  437. return ocr;
  438. }
  439. static void mmcsd_power_up(struct rt_mmcsd_host *host)
  440. {
  441. int bit = fls(host->valid_ocr) - 1;
  442. host->io_cfg.vdd = bit;
  443. if (controller_is_spi(host))
  444. {
  445. host->io_cfg.chip_select = MMCSD_CS_HIGH;
  446. host->io_cfg.bus_mode = MMCSD_BUSMODE_PUSHPULL;
  447. }
  448. else
  449. {
  450. host->io_cfg.chip_select = MMCSD_CS_IGNORE;
  451. host->io_cfg.bus_mode = MMCSD_BUSMODE_OPENDRAIN;
  452. }
  453. host->io_cfg.power_mode = MMCSD_POWER_UP;
  454. host->io_cfg.bus_width = MMCSD_BUS_WIDTH_1;
  455. mmcsd_set_iocfg(host);
  456. /*
  457. * This delay should be sufficient to allow the power supply
  458. * to reach the minimum voltage.
  459. */
  460. mmcsd_delay_ms(10);
  461. host->io_cfg.clock = host->freq_min;
  462. host->io_cfg.power_mode = MMCSD_POWER_ON;
  463. mmcsd_set_iocfg(host);
  464. /*
  465. * This delay must be at least 74 clock sizes, or 1 ms, or the
  466. * time required to reach a stable voltage.
  467. */
  468. mmcsd_delay_ms(10);
  469. }
  470. static void mmcsd_power_off(struct rt_mmcsd_host *host)
  471. {
  472. host->io_cfg.clock = 0;
  473. host->io_cfg.vdd = 0;
  474. if (!controller_is_spi(host))
  475. {
  476. host->io_cfg.bus_mode = MMCSD_BUSMODE_OPENDRAIN;
  477. host->io_cfg.chip_select = MMCSD_CS_IGNORE;
  478. }
  479. host->io_cfg.power_mode = MMCSD_POWER_OFF;
  480. host->io_cfg.bus_width = MMCSD_BUS_WIDTH_1;
  481. mmcsd_set_iocfg(host);
  482. }
  483. int mmcsd_wait_cd_changed(rt_int32_t timeout)
  484. {
  485. struct rt_mmcsd_host *host;
  486. if (rt_mb_recv(&mmcsd_hotpluge_mb, (rt_uint32_t*)&host, timeout) == RT_EOK)
  487. {
  488. if(host->card == RT_NULL)
  489. {
  490. return MMCSD_HOST_UNPLUGED;
  491. }
  492. else
  493. {
  494. return MMCSD_HOST_PLUGED;
  495. }
  496. }
  497. return -RT_ETIMEOUT;
  498. }
  499. RTM_EXPORT(mmcsd_wait_cd_changed);
  500. void mmcsd_change(struct rt_mmcsd_host *host)
  501. {
  502. rt_mb_send(&mmcsd_detect_mb, (rt_uint32_t)host);
  503. }
  504. void mmcsd_detect(void *param)
  505. {
  506. struct rt_mmcsd_host *host;
  507. rt_uint32_t ocr;
  508. rt_int32_t err;
  509. while (1)
  510. {
  511. if (rt_mb_recv(&mmcsd_detect_mb, (rt_uint32_t*)&host, RT_WAITING_FOREVER) == RT_EOK)
  512. {
  513. if (host->card == RT_NULL)
  514. {
  515. mmcsd_host_lock(host);
  516. mmcsd_power_up(host);
  517. mmcsd_go_idle(host);
  518. mmcsd_send_if_cond(host, host->valid_ocr);
  519. err = sdio_io_send_op_cond(host, 0, &ocr);
  520. if (!err)
  521. {
  522. if (init_sdio(host, ocr))
  523. mmcsd_power_off(host);
  524. mmcsd_host_unlock(host);
  525. continue;
  526. }
  527. /*
  528. * detect SD card
  529. */
  530. err = mmcsd_send_app_op_cond(host, 0, &ocr);
  531. if (!err)
  532. {
  533. if (init_sd(host, ocr))
  534. mmcsd_power_off(host);
  535. mmcsd_host_unlock(host);
  536. continue;
  537. }
  538. /*
  539. * detect mmc card
  540. */
  541. err = mmc_send_op_cond(host, 0, &ocr);
  542. if (!err)
  543. {
  544. if (init_mmc(host, ocr))
  545. mmcsd_power_off(host);
  546. mmcsd_host_unlock(host);
  547. rt_mb_send(&mmcsd_hotpluge_mb, (rt_uint32_t)host);
  548. continue;
  549. }
  550. mmcsd_host_unlock(host);
  551. }
  552. else
  553. {
  554. /* card removed */
  555. mmcsd_host_lock(host);
  556. if (host->card->sdio_function_num != 0)
  557. {
  558. rt_kprintf("unsupport sdio card plug out!\n");
  559. }
  560. else
  561. {
  562. rt_mmcsd_blk_remove(host->card);
  563. rt_free(host->card);
  564. host->card = RT_NULL;
  565. }
  566. mmcsd_host_unlock(host);
  567. rt_mb_send(&mmcsd_hotpluge_mb, (rt_uint32_t)host);
  568. }
  569. }
  570. }
  571. }
  572. struct rt_mmcsd_host *mmcsd_alloc_host(void)
  573. {
  574. struct rt_mmcsd_host *host;
  575. host = rt_malloc(sizeof(struct rt_mmcsd_host));
  576. if (!host)
  577. {
  578. rt_kprintf("alloc host failed\n");
  579. return RT_NULL;
  580. }
  581. rt_memset(host, 0, sizeof(struct rt_mmcsd_host));
  582. host->max_seg_size = 65535;
  583. host->max_dma_segs = 1;
  584. host->max_blk_size = 512;
  585. host->max_blk_count = 4096;
  586. rt_mutex_init(&host->bus_lock, "sd_bus_lock", RT_IPC_FLAG_FIFO);
  587. rt_sem_init(&host->sem_ack, "sd_ack", 0, RT_IPC_FLAG_FIFO);
  588. return host;
  589. }
  590. void mmcsd_free_host(struct rt_mmcsd_host *host)
  591. {
  592. rt_mutex_detach(&host->bus_lock);
  593. rt_sem_detach(&host->sem_ack);
  594. rt_free(host);
  595. }
  596. void rt_mmcsd_core_init(void)
  597. {
  598. rt_err_t ret;
  599. /* initialize detect SD cart thread */
  600. /* initialize mailbox and create detect SD card thread */
  601. ret = rt_mb_init(&mmcsd_detect_mb, "mmcsdmb",
  602. &mmcsd_detect_mb_pool[0], sizeof(mmcsd_detect_mb_pool) / sizeof(mmcsd_detect_mb_pool[0]),
  603. RT_IPC_FLAG_FIFO);
  604. RT_ASSERT(ret == RT_EOK);
  605. ret = rt_mb_init(&mmcsd_hotpluge_mb, "mmcsdhotplugmb",
  606. &mmcsd_hotpluge_mb_pool[0], sizeof(mmcsd_hotpluge_mb_pool) / sizeof(mmcsd_hotpluge_mb_pool[0]),
  607. RT_IPC_FLAG_FIFO);
  608. RT_ASSERT(ret == RT_EOK);
  609. ret = rt_thread_init(&mmcsd_detect_thread, "mmcsd_detect", mmcsd_detect, RT_NULL,
  610. &mmcsd_stack[0], RT_MMCSD_STACK_SIZE, RT_MMCSD_THREAD_PREORITY, 20);
  611. if (ret == RT_EOK)
  612. {
  613. rt_thread_startup(&mmcsd_detect_thread);
  614. }
  615. rt_sdio_init();
  616. }