at32f413_sdio.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573
  1. /**
  2. **************************************************************************
  3. * @file at32f413_sdio.c
  4. * @brief contains all the functions for the sdio firmware library
  5. **************************************************************************
  6. * Copyright notice & Disclaimer
  7. *
  8. * The software Board Support Package (BSP) that is made available to
  9. * download from Artery official website is the copyrighted work of Artery.
  10. * Artery authorizes customers to use, copy, and distribute the BSP
  11. * software and its related documentation for the purpose of design and
  12. * development in conjunction with Artery microcontrollers. Use of the
  13. * software is governed by this copyright notice and the following disclaimer.
  14. *
  15. * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES,
  16. * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS,
  17. * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR
  18. * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS,
  19. * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
  20. * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
  21. *
  22. **************************************************************************
  23. */
  24. #include "at32f413_conf.h"
  25. /** @addtogroup AT32F413_periph_driver
  26. * @{
  27. */
  28. /** @defgroup SDIO
  29. * @brief SDIO driver modules
  30. * @{
  31. */
  32. #ifdef SDIO_MODULE_ENABLED
  33. /** @defgroup SDIO_private_functions
  34. * @{
  35. */
  36. /**
  37. * @brief reset the sdio register
  38. * @param sdio_x: to select the sdio peripheral.
  39. * this parameter can be one of the following values:
  40. * SDIO1.
  41. * @retval none
  42. */
  43. void sdio_reset(sdio_type *sdio_x)
  44. {
  45. sdio_x->pwrctrl = 0x0;
  46. sdio_x->clkctrl = 0x0;
  47. sdio_x->argu = 0x0;
  48. sdio_x->cmdctrl = 0x0;
  49. sdio_x->dttmr = 0x0;
  50. sdio_x->dtlen = 0x0;
  51. sdio_x->dtctrl = 0x0;
  52. sdio_x->inten = 0x0;
  53. sdio_x->intclr = 0x004007FF;
  54. }
  55. /**
  56. * @brief set the power status of the controller
  57. * @param sdio_x: to select the sdio peripheral.
  58. * this parameter can be one of the following values:
  59. * SDIO1.
  60. * @param power_state
  61. * this parameter can be one of the following values:
  62. * - SDIO_POWER_OFF
  63. * - SDIO_POWER_ON
  64. * @retval none
  65. */
  66. void sdio_power_set(sdio_type *sdio_x, sdio_power_state_type power_state)
  67. {
  68. sdio_x->pwrctrl_bit.ps = power_state;
  69. }
  70. /**
  71. * @brief get power status.
  72. * @param sdio_x: to select the sdio peripheral.
  73. * this parameter can be one of the following values:
  74. * SDIO1.
  75. * @retval sdio_power_state_type (SDIO_POWER_ON or SDIO_POWER_OFF)
  76. */
  77. sdio_power_state_type sdio_power_status_get(sdio_type *sdio_x)
  78. {
  79. return (sdio_power_state_type)(sdio_x->pwrctrl_bit.ps);
  80. }
  81. /**
  82. * @brief config sdio clock
  83. * @param sdio_x: to select the sdio peripheral.
  84. * this parameter can be one of the following values:
  85. * SDIO1.
  86. * @param clk_div: sdio clock divide factor(frequency = sdio_clk / [clk_psc + 2]).
  87. * @param clk_edg
  88. * this parameter can be one of the following values:
  89. * - SDIO_CLOCK_EDGE_RISING
  90. * - SDIO_CLOCK_EDGE_FALLING
  91. * @retval none
  92. */
  93. void sdio_clock_config(sdio_type *sdio_x, uint16_t clk_div, sdio_edge_phase_type clk_edg)
  94. {
  95. /* config clock edge */
  96. sdio_x->clkctrl_bit.clkegs = clk_edg;
  97. /* config clock divide [7:0] */
  98. sdio_x->clkctrl_bit.clkdiv_l = (clk_div & 0xFF);
  99. /* config clock divide [9:8] */
  100. sdio_x->clkctrl_bit.clkdiv_h = ((clk_div & 0x300) >> 8);
  101. }
  102. /**
  103. * @brief config sdio bus width
  104. * @param sdio_x: to select the sdio peripheral.
  105. * this parameter can be one of the following values:
  106. * SDIO1.
  107. * @param width
  108. * this parameter can be one of the following values:
  109. * - SDIO_BUS_WIDTH_D1
  110. * - SDIO_BUS_WIDTH_D4
  111. * - SDIO_BUS_WIDTH_D8
  112. * @retval none
  113. */
  114. void sdio_bus_width_config(sdio_type *sdio_x, sdio_bus_width_type width)
  115. {
  116. sdio_x->clkctrl_bit.busws = width;
  117. }
  118. /**
  119. * @brief enable or disable clock divider bypss
  120. * @param sdio_x: to select the sdio peripheral.
  121. * this parameter can be one of the following values:
  122. * SDIO1.
  123. * @param new_state (TRUE or FALSE)
  124. * @retval none
  125. */
  126. void sdio_clock_bypass(sdio_type *sdio_x, confirm_state new_state)
  127. {
  128. sdio_x->clkctrl_bit.bypsen = new_state;
  129. }
  130. /**
  131. * @brief enable or disable power saving mode, config sdio_ck clock output
  132. * when the bus is idle.
  133. * @param sdio_x: to select the sdio peripheral.
  134. * this parameter can be one of the following values:
  135. * SDIO1.
  136. * @param new_state (TRUE or FALSE)
  137. * @retval none
  138. */
  139. void sdio_power_saving_mode_enable(sdio_type *sdio_x, confirm_state new_state)
  140. {
  141. sdio_x->clkctrl_bit.pwrsven = new_state;
  142. }
  143. /**
  144. * @brief enable or disable hardware flow control.
  145. * @param sdio_x: to select the sdio peripheral.
  146. * this parameter can be one of the following values:
  147. * SDIO1.
  148. * @param new_state (TRUE or FALSE)
  149. * @retval none
  150. */
  151. void sdio_flow_control_enable(sdio_type *sdio_x, confirm_state new_state)
  152. {
  153. sdio_x->clkctrl_bit.hfcen = new_state;
  154. }
  155. /**
  156. * @brief enable or disable sdio_ck output.
  157. * @param sdio_x: to select the sdio peripheral.
  158. * this parameter can be one of the following values:
  159. * SDIO1.
  160. * @param new_state (TRUE or FALSE)
  161. * @retval none
  162. */
  163. void sdio_clock_enable(sdio_type *sdio_x, confirm_state new_state)
  164. {
  165. sdio_x->clkctrl_bit.clkoen = new_state;
  166. }
  167. /**
  168. * @brief enable or disable dma.
  169. * @param sdio_x: to select the sdio peripheral.
  170. * this parameter can be one of the following values:
  171. * SDIO1.
  172. * @param new_state (TRUE or FALSE)
  173. * @retval none
  174. */
  175. void sdio_dma_enable(sdio_type *sdio_x, confirm_state new_state)
  176. {
  177. sdio_x->dtctrl_bit.dmaen = new_state;
  178. }
  179. /**
  180. * @brief config corresponding interrupt.
  181. * @param sdio_x: to select the sdio peripheral.
  182. * this parameter can be one of the following values:
  183. * SDIO1.
  184. * @param int_opt
  185. * this parameter can be one of the following values:
  186. * - SDIO_CMDFAIL_INT
  187. * - SDIO_DTFAIL_INT
  188. * - SDIO_CMDTIMEOUT_INT
  189. * - SDIO_DTTIMEOUT_INT
  190. * - SDIO_TXERRU_INT
  191. * - SDIO_RXERRO_INT
  192. * - SDIO_CMDRSPCMPL_INT
  193. * - SDIO_CMDCMPL_INT
  194. * - SDIO_DTCMP_INT
  195. * - SDIO_SBITERR_INT
  196. * - SDIO_DTBLKCMPL_INT
  197. * - SDIO_DOCMD_INT
  198. * - SDIO_DOTX_INT
  199. * - SDIO_DORX_INT
  200. * - SDIO_TXBUFH_INT
  201. * - SDIO_RXBUFH_INT
  202. * - SDIO_TXBUFF_INT
  203. * - SDIO_RXBUFF_INT
  204. * - SDIO_TXBUFE_INT
  205. * - SDIO_RXBUFE_INT
  206. * - SDIO_TXBUF_INT
  207. * - SDIO_RXBUF_INT
  208. * - SDIO_SDIOIF_INT
  209. * @param new_state (TRUE or FALSE)
  210. * @retval none
  211. */
  212. void sdio_interrupt_enable(sdio_type *sdio_x, uint32_t int_opt, confirm_state new_state)
  213. {
  214. /* enable interrupt */
  215. if(TRUE == new_state)
  216. {
  217. sdio_x->inten |= int_opt;
  218. }
  219. /* disable interrupt */
  220. else
  221. {
  222. sdio_x->inten &= ~(int_opt);
  223. }
  224. }
  225. /**
  226. * @brief get sdio flag.
  227. * @param sdio_x: to select the sdio peripheral.
  228. * this parameter can be one of the following values:
  229. * SDIO1.
  230. * @param flag
  231. * this parameter can be one of the following values:
  232. * - SDIO_CMDFAIL_FLAG
  233. * - SDIO_DTFAIL_FLAG
  234. * - SDIO_CMDTIMEOUT_FLAG
  235. * - SDIO_DTTIMEOUT_FLAG
  236. * - SDIO_TXERRU_FLAG
  237. * - SDIO_RXERRO_FLAG
  238. * - SDIO_CMDRSPCMPL_FLAG
  239. * - SDIO_CMDCMPL_FLAG
  240. * - SDIO_DTCMPL_FLAG
  241. * - SDIO_SBITERR_FLAG
  242. * - SDIO_DTBLKCMPL_FLAG
  243. * - SDIO_DOCMD_FLAG
  244. * - SDIO_DOTX_FLAG
  245. * - SDIO_DORX_FLAG
  246. * - SDIO_TXBUFH_FLAG
  247. * - SDIO_RXBUFH_FLAG
  248. * - SDIO_TXBUFF_FLAG
  249. * - SDIO_RXBUFF_FLAG
  250. * - SDIO_TXBUFE_FLAG
  251. * - SDIO_RXBUFE_FLAG
  252. * - SDIO_TXBUF_FLAG
  253. * - SDIO_RXBUF_FLAG
  254. * - SDIO_SDIOIF_FLAG
  255. * @retval flag_status (SET or RESET)
  256. */
  257. flag_status sdio_flag_get(sdio_type *sdio_x, uint32_t flag)
  258. {
  259. flag_status status = RESET;
  260. if((sdio_x->sts & flag) == flag)
  261. {
  262. status = SET;
  263. }
  264. else
  265. {
  266. status = RESET;
  267. }
  268. return status;
  269. }
  270. /**
  271. * @brief clear sdio flag.
  272. * @param sdio_x: to select the sdio peripheral.
  273. * this parameter can be one of the following values:
  274. * SDIO1.
  275. * @param int_opt
  276. * this parameter can be any combination of the following values:
  277. * - SDIO_CMDFAIL_FLAG
  278. * - SDIO_DTFAIL_FLAG
  279. * - SDIO_CMDTIMEOUT_FLAG
  280. * - SDIO_DTTIMEOUT_FLAG
  281. * - SDIO_TXERRU_FLAG
  282. * - SDIO_RXERRO_FLAG
  283. * - SDIO_CMDRSPCMPL_FLAG
  284. * - SDIO_CMDCMPL_FLAG
  285. * - SDIO_DTCMPL_FLAG
  286. * - SDIO_SBITERR_FLAG
  287. * - SDIO_DTBLKCMPL_FLAG
  288. * - SDIO_SDIOIF_FLAG
  289. * @retval none
  290. */
  291. void sdio_flag_clear(sdio_type *sdio_x, uint32_t flag)
  292. {
  293. sdio_x->intclr = flag;
  294. }
  295. /**
  296. * @brief config sdio command.
  297. * @param sdio_x: to select the sdio peripheral.
  298. * this parameter can be one of the following values:
  299. * SDIO1.
  300. * @param command_struct : pointer to a sdio_command_struct_type structure
  301. * that contains the configuration information for the sdio command.
  302. * @retval none
  303. */
  304. void sdio_command_config(sdio_type *sdio_x, sdio_command_struct_type *command_struct)
  305. {
  306. /* disable command path state machine */
  307. sdio_x->cmdctrl_bit.ccsmen = FALSE;
  308. /* config command argument */
  309. sdio_x->argu = command_struct->argument;
  310. /* config command register */
  311. sdio_x->cmdctrl_bit.cmdidx = command_struct->cmd_index;
  312. sdio_x->cmdctrl_bit.rspwt = command_struct->rsp_type;
  313. sdio_x->cmdctrl_bit.intwt = (command_struct->wait_type & 0x1); /* [1:0] -> [0] */
  314. sdio_x->cmdctrl_bit.pndwt = (command_struct->wait_type & 0x2)>>1; /* [1:0] -> [1] */
  315. }
  316. /**
  317. * @brief enable or disable command path state machine(CPSM).
  318. * @param sdio_x: to select the sdio peripheral.
  319. * this parameter can be one of the following values:
  320. * SDIO1.
  321. * @param new_state (TRUE or FALSE)
  322. * @retval none
  323. */
  324. void sdio_command_state_machine_enable(sdio_type *sdio_x, confirm_state new_state)
  325. {
  326. sdio_x->cmdctrl_bit.ccsmen = new_state;
  327. }
  328. /**
  329. * @brief get command index of last command for which response received.
  330. * @param sdio_x: to select the sdio peripheral.
  331. * this parameter can be one of the following values:
  332. * SDIO1.
  333. * @param new_state (TRUE or FALSE)
  334. * @retval uint8_t: command index
  335. */
  336. uint8_t sdio_command_response_get(sdio_type *sdio_x)
  337. {
  338. return sdio_x->rspcmd_bit.rspcmd;
  339. }
  340. /**
  341. * @brief get response received from the card for the last command.
  342. * @param sdio_x: to select the sdio peripheral.
  343. * this parameter can be one of the following values:
  344. * SDIO1.
  345. * @param reg_index
  346. * this parameter can be one of the following values:
  347. * - SDIO_RSP1_INDEX
  348. * - SDIO_RSP2_INDEX
  349. * - SDIO_RSP3_INDEX
  350. * - SDIO_RSP4_INDEX
  351. * @retval uint32_t: response register value
  352. */
  353. uint32_t sdio_response_get(sdio_type *sdio_x, sdio_rsp_index_type reg_index)
  354. {
  355. uint32_t response_value = 0;
  356. switch(reg_index)
  357. {
  358. case SDIO_RSP1_INDEX:
  359. response_value = sdio_x->rsp1;
  360. break;
  361. case SDIO_RSP2_INDEX:
  362. response_value = sdio_x->rsp2;
  363. break;
  364. case SDIO_RSP3_INDEX:
  365. response_value = sdio_x->rsp3;
  366. break;
  367. case SDIO_RSP4_INDEX:
  368. response_value = sdio_x->rsp4;
  369. break;
  370. default: break;
  371. }
  372. return response_value;
  373. }
  374. /**
  375. * @brief config sdio data.
  376. * @param sdio_x: to select the sdio peripheral.
  377. * this parameter can be one of the following values:
  378. * SDIO1.
  379. * @param data_struct : pointer to a sdio_data_struct_type structure
  380. * that contains the configuration information for the sdio data.
  381. * @retval none
  382. */
  383. void sdio_data_config(sdio_type *sdio_x, sdio_data_struct_type *data_struct)
  384. {
  385. /* disable data path state machine */
  386. sdio_x->dtctrl_bit.tfren = FALSE;
  387. /* config data block, transfer mode and transfer direction */
  388. sdio_x->dtctrl_bit.blksize = data_struct->block_size;
  389. sdio_x->dtctrl_bit.tfrdir = data_struct->transfer_direction;
  390. sdio_x->dtctrl_bit.tfrmode = data_struct->transfer_mode;
  391. /* config data length */
  392. sdio_x->dtlen_bit.dtlen = data_struct->data_length;
  393. /* config data transfer timeout */
  394. sdio_x->dttmr_bit.timeout = data_struct->timeout;
  395. }
  396. /**
  397. * @brief enable or disable data path state machine(DPSM).
  398. * @param sdio_x: to select the sdio peripheral.
  399. * this parameter can be one of the following values:
  400. * SDIO1.
  401. * @param new_state (TRUE or FALSE)
  402. * @retval none
  403. */
  404. void sdio_data_state_machine_enable(sdio_type *sdio_x, confirm_state new_state)
  405. {
  406. sdio_x->dtctrl_bit.tfren = new_state;
  407. }
  408. /**
  409. * @brief get the number of remaining data bytes to be transferred.
  410. * @param sdio_x: to select the sdio peripheral.
  411. * this parameter can be one of the following values:
  412. * SDIO1.
  413. * @retval uint32_t: number of bytes
  414. */
  415. uint32_t sdio_data_counter_get(sdio_type *sdio_x)
  416. {
  417. return sdio_x->dtcnt;
  418. }
  419. /**
  420. * @brief read a word data from sdio fifo.
  421. * @param sdio_x: to select the sdio peripheral.
  422. * this parameter can be one of the following values:
  423. * SDIO1.
  424. * @retval uint32_t: data received
  425. */
  426. uint32_t sdio_data_read(sdio_type *sdio_x)
  427. {
  428. return sdio_x->buf;
  429. }
  430. /**
  431. * @brief get the number of words left to be written to or read from fifo..
  432. * @param sdio_x: to select the sdio peripheral.
  433. * this parameter can be one of the following values:
  434. * SDIO1.
  435. * @retval uint32_t: number of words
  436. */
  437. uint32_t sdio_buffer_counter_get(sdio_type *sdio_x)
  438. {
  439. return sdio_x->bufcnt;
  440. }
  441. /**
  442. * @brief write one word data to fifo.
  443. * @param sdio_x: to select the sdio peripheral.
  444. * this parameter can be one of the following values:
  445. * SDIO1.
  446. * @param data: data to be transferred.
  447. * @retval none
  448. */
  449. void sdio_data_write(sdio_type *sdio_x, uint32_t data)
  450. {
  451. sdio_x->buf = data;
  452. }
  453. /**
  454. * @brief set the read wait mode.
  455. * @param sdio_x: to select the sdio peripheral.
  456. * this parameter can be one of the following values:
  457. * SDIO1.
  458. * @param mode
  459. * this parameter can be one of the following values:
  460. * - SDIO_READ_WAIT_CONTROLLED_BY_D2
  461. * - SDIO_READ_WAIT_CONTROLLED_BY_CK
  462. * @retval none
  463. */
  464. void sdio_read_wait_mode_set(sdio_type *sdio_x, sdio_read_wait_mode_type mode)
  465. {
  466. sdio_x->dtctrl_bit.rdwtmode = mode;
  467. }
  468. /**
  469. * @brief enable or disable to start sd i/o read wait operation.
  470. * @param sdio_x: to select the sdio peripheral.
  471. * this parameter can be one of the following values:
  472. * SDIO1.
  473. * @param new_state (TRUE or FALSE)
  474. * @retval none
  475. */
  476. void sdio_read_wait_start(sdio_type *sdio_x, confirm_state new_state)
  477. {
  478. sdio_x->dtctrl_bit.rdwtstart = new_state;
  479. }
  480. /**
  481. * @brief enable or disable to stop sd i/o read wait operation.
  482. * @param sdio_x: to select the sdio peripheral.
  483. * this parameter can be one of the following values:
  484. * SDIO1.
  485. * @param new_state (TRUE or FALSE)
  486. * @retval none
  487. */
  488. void sdio_read_wait_stop(sdio_type *sdio_x, confirm_state new_state)
  489. {
  490. sdio_x->dtctrl_bit.rdwtstop = new_state;
  491. }
  492. /**
  493. * @brief enable or disable the sd i/o function.
  494. * @param sdio_x: to select the sdio peripheral.
  495. * this parameter can be one of the following values:
  496. * SDIO1.
  497. * @param new_state (TRUE or FALSE)
  498. * @retval none
  499. */
  500. void sdio_io_function_enable(sdio_type *sdio_x, confirm_state new_state)
  501. {
  502. sdio_x->dtctrl_bit.ioen = new_state;
  503. }
  504. /**
  505. * @brief enable or disable sd i/o suspend command sending.
  506. * @param sdio_x: to select the sdio peripheral.
  507. * this parameter can be one of the following values:
  508. * SDIO1.
  509. * @param new_state (TRUE or FALSE)
  510. * @retval none
  511. */
  512. void sdio_io_suspend_command_set(sdio_type *sdio_x, confirm_state new_state)
  513. {
  514. sdio_x->cmdctrl_bit.iosusp = new_state;
  515. }
  516. /**
  517. * @}
  518. */
  519. #endif
  520. /**
  521. * @}
  522. */
  523. /**
  524. * @}
  525. */