2 **************************************************************************
3 * @file at32f435_437_sdio.c
6 * @brief contains all the functions for the sdio firmware library
7 **************************************************************************
8 * Copyright notice & Disclaimer
10 * The software Board Support Package (BSP) that is made available to
11 * download from Artery official website is the copyrighted work of Artery.
12 * Artery authorizes customers to use, copy, and distribute the BSP
13 * software and its related documentation for the purpose of design and
14 * development in conjunction with Artery microcontrollers. Use of the
15 * software is governed by this copyright notice and the following disclaimer.
17 * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES,
18 * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS,
19 * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR
20 * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS,
21 * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
24 **************************************************************************
27 #include "at32f435_437_conf.h"
29 /** @addtogroup AT32F435_437_periph_driver
34 * @brief SDIO driver modules
38 #ifdef SDIO_MODULE_ENABLED
40 /** @defgroup SDIO_private_functions
45 * @brief reset the sdio register
46 * @param sdio_x: to select the sdio peripheral.
47 * this parameter can be one of the following values:
51 void sdio_reset(sdio_type
*sdio_x
)
53 sdio_x
->pwrctrl
= 0x0;
54 sdio_x
->clkctrl
= 0x0;
56 sdio_x
->cmdctrl
= 0x0;
61 sdio_x
->intclr
= 0x004007FF;
65 * @brief set the power status of the controller
66 * @param sdio_x: to select the sdio peripheral.
67 * this parameter can be one of the following values:
70 * this parameter can be one of the following values:
75 void sdio_power_set(sdio_type
*sdio_x
, sdio_power_state_type power_state
)
77 sdio_x
->pwrctrl_bit
.ps
= power_state
;
81 * @brief get power status.
82 * @param sdio_x: to select the sdio peripheral.
83 * this parameter can be one of the following values:
85 * @retval sdio_power_state_type (SDIO_POWER_ON or SDIO_POWER_OFF)
87 sdio_power_state_type
sdio_power_status_get(sdio_type
*sdio_x
)
89 return (sdio_power_state_type
)(sdio_x
->pwrctrl_bit
.ps
);
93 * @brief config sdio clock
94 * @param sdio_x: to select the sdio peripheral.
95 * this parameter can be one of the following values:
97 * @param clk_div: sdio clock divide factor(frequency = sdio_clk / [clk_psc + 2]).
99 * this parameter can be one of the following values:
100 * - SDIO_CLOCK_EDGE_RISING
101 * - SDIO_CLOCK_EDGE_FALLING
104 void sdio_clock_config(sdio_type
*sdio_x
, uint16_t clk_div
, sdio_edge_phase_type clk_edg
)
106 /* config clock edge */
107 sdio_x
->clkctrl_bit
.clkegs
= clk_edg
;
109 /* config clock divide [7:0] */
110 sdio_x
->clkctrl_bit
.clkdiv_l
= (clk_div
& 0xFF);
112 /* config clock divide [9:8] */
113 sdio_x
->clkctrl_bit
.clkdiv_h
= ((clk_div
& 0x300) >> 8);
117 * @brief config sdio bus width
118 * @param sdio_x: to select the sdio peripheral.
119 * this parameter can be one of the following values:
122 * this parameter can be one of the following values:
123 * - SDIO_BUS_WIDTH_D1
124 * - SDIO_BUS_WIDTH_D4
125 * - SDIO_BUS_WIDTH_D8
128 void sdio_bus_width_config(sdio_type
*sdio_x
, sdio_bus_width_type width
)
130 sdio_x
->clkctrl_bit
.busws
= width
;
134 * @brief enable or disable clock divider bypss
135 * @param sdio_x: to select the sdio peripheral.
136 * this parameter can be one of the following values:
138 * @param new_state (TRUE or FALSE)
141 void sdio_clock_bypass(sdio_type
*sdio_x
, confirm_state new_state
)
143 sdio_x
->clkctrl_bit
.bypsen
= new_state
;
147 * @brief enable or disable power saving mode, config sdio_ck clock output
148 * when the bus is idle.
149 * @param sdio_x: to select the sdio peripheral.
150 * this parameter can be one of the following values:
152 * @param new_state (TRUE or FALSE)
155 void sdio_power_saving_mode_enable(sdio_type
*sdio_x
, confirm_state new_state
)
157 sdio_x
->clkctrl_bit
.pwrsven
= new_state
;
161 * @brief enable or disable hardware flow control.
162 * @param sdio_x: to select the sdio peripheral.
163 * this parameter can be one of the following values:
165 * @param new_state (TRUE or FALSE)
168 void sdio_flow_control_enable(sdio_type
*sdio_x
, confirm_state new_state
)
170 sdio_x
->clkctrl_bit
.hfcen
= new_state
;
174 * @brief enable or disable sdio_ck output.
175 * @param sdio_x: to select the sdio peripheral.
176 * this parameter can be one of the following values:
178 * @param new_state (TRUE or FALSE)
181 void sdio_clock_enable(sdio_type
*sdio_x
, confirm_state new_state
)
183 sdio_x
->clkctrl_bit
.clkoen
= new_state
;
187 * @brief enable or disable dma.
188 * @param sdio_x: to select the sdio peripheral.
189 * this parameter can be one of the following values:
191 * @param new_state (TRUE or FALSE)
194 void sdio_dma_enable(sdio_type
*sdio_x
, confirm_state new_state
)
196 sdio_x
->dtctrl_bit
.dmaen
= new_state
;
200 * @brief config corresponding interrupt.
201 * @param sdio_x: to select the sdio peripheral.
202 * this parameter can be one of the following values:
205 * this parameter can be one of the following values:
208 * - SDIO_CMDTIMEOUT_INT
209 * - SDIO_DTTIMEOUT_INT
212 * - SDIO_CMDRSPCMPL_INT
216 * - SDIO_DTBLKCMPL_INT
229 * @param new_state (TRUE or FALSE)
232 void sdio_interrupt_enable(sdio_type
*sdio_x
, uint32_t int_opt
, confirm_state new_state
)
234 /* enable interrupt */
235 if(TRUE
== new_state
)
237 sdio_x
->inten
|= int_opt
;
239 /* disable interrupt */
242 sdio_x
->inten
&= ~(int_opt
);
247 * @brief get sdio flag.
248 * @param sdio_x: to select the sdio peripheral.
249 * this parameter can be one of the following values:
252 * this parameter can be one of the following values:
253 * - SDIO_CMDFAIL_FLAG
255 * - SDIO_CMDTIMEOUT_FLAG
256 * - SDIO_DTTIMEOUT_FLAG
259 * - SDIO_CMDRSPCMPL_FLAG
260 * - SDIO_CMDCMPL_FLAG
262 * - SDIO_SBITERR_FLAG
263 * - SDIO_DTBLKCMPL_FLAG
276 * @retval flag_status (SET or RESET)
278 flag_status
sdio_flag_get(sdio_type
*sdio_x
, uint32_t flag
)
280 flag_status status
= RESET
;
282 if((sdio_x
->sts
& flag
) == flag
)
295 * @brief clear sdio flag.
296 * @param sdio_x: to select the sdio peripheral.
297 * this parameter can be one of the following values:
300 * this parameter can be any combination of the following values:
301 * - SDIO_CMDFAIL_FLAG
303 * - SDIO_CMDTIMEOUT_FLAG
304 * - SDIO_DTTIMEOUT_FLAG
307 * - SDIO_CMDRSPCMPL_FLAG
308 * - SDIO_CMDCMPL_FLAG
310 * - SDIO_SBITERR_FLAG
311 * - SDIO_DTBLKCMPL_FLAG
315 void sdio_flag_clear(sdio_type
*sdio_x
, uint32_t flag
)
317 sdio_x
->intclr
= flag
;
321 * @brief config sdio command.
322 * @param sdio_x: to select the sdio peripheral.
323 * this parameter can be one of the following values:
325 * @param command_struct : pointer to a sdio_command_struct_type structure
326 * that contains the configuration information for the sdio command.
329 void sdio_command_config(sdio_type
*sdio_x
, sdio_command_struct_type
*command_struct
)
331 /* disable command path state machine */
332 sdio_x
->cmdctrl_bit
.ccsmen
= FALSE
;
334 /* config command argument */
335 sdio_x
->argu
= command_struct
->argument
;
337 /* config command register */
338 sdio_x
->cmdctrl_bit
.cmdidx
= command_struct
->cmd_index
;
339 sdio_x
->cmdctrl_bit
.rspwt
= command_struct
->rsp_type
;
340 sdio_x
->cmdctrl_bit
.intwt
= (command_struct
->wait_type
& 0x1); /* [1:0] -> [0] */
341 sdio_x
->cmdctrl_bit
.pndwt
= (command_struct
->wait_type
& 0x2)>>1; /* [1:0] -> [1] */
345 * @brief enable or disable command path state machine(CPSM).
346 * @param sdio_x: to select the sdio peripheral.
347 * this parameter can be one of the following values:
349 * @param new_state (TRUE or FALSE)
352 void sdio_command_state_machine_enable(sdio_type
*sdio_x
, confirm_state new_state
)
354 sdio_x
->cmdctrl_bit
.ccsmen
= new_state
;
358 * @brief get command index of last command for which response received.
359 * @param sdio_x: to select the sdio peripheral.
360 * this parameter can be one of the following values:
362 * @param new_state (TRUE or FALSE)
363 * @retval uint8_t: command index
365 uint8_t sdio_command_response_get(sdio_type
*sdio_x
)
367 return sdio_x
->rspcmd_bit
.rspcmd
;
371 * @brief get response received from the card for the last command.
372 * @param sdio_x: to select the sdio peripheral.
373 * this parameter can be one of the following values:
376 * this parameter can be one of the following values:
381 * @retval uint32_t: response register value
383 uint32_t sdio_response_get(sdio_type
*sdio_x
, sdio_rsp_index_type reg_index
)
385 uint32_t response_value
= 0;
389 case SDIO_RSP1_INDEX
:
390 response_value
= sdio_x
->rsp1
;
392 case SDIO_RSP2_INDEX
:
393 response_value
= sdio_x
->rsp2
;
395 case SDIO_RSP3_INDEX
:
396 response_value
= sdio_x
->rsp3
;
398 case SDIO_RSP4_INDEX
:
399 response_value
= sdio_x
->rsp4
;
404 return response_value
;
408 * @brief config sdio data.
409 * @param sdio_x: to select the sdio peripheral.
410 * this parameter can be one of the following values:
412 * @param data_struct : pointer to a sdio_data_struct_type structure
413 * that contains the configuration information for the sdio data.
416 void sdio_data_config(sdio_type
*sdio_x
, sdio_data_struct_type
*data_struct
)
418 /* disable data path state machine */
419 sdio_x
->dtctrl_bit
.tfren
= FALSE
;
421 /* config data block, transfer mode and transfer direction */
422 sdio_x
->dtctrl_bit
.blksize
= data_struct
->block_size
;
423 sdio_x
->dtctrl_bit
.tfrdir
= data_struct
->transfer_direction
;
424 sdio_x
->dtctrl_bit
.tfrmode
= data_struct
->transfer_mode
;
426 /* config data length */
427 sdio_x
->dtlen_bit
.dtlen
= data_struct
->data_length
;
429 /* config data transfer timeout */
430 sdio_x
->dttmr_bit
.timeout
= data_struct
->timeout
;
434 * @brief enable or disable data path state machine(DPSM).
435 * @param sdio_x: to select the sdio peripheral.
436 * this parameter can be one of the following values:
438 * @param new_state (TRUE or FALSE)
441 void sdio_data_state_machine_enable(sdio_type
*sdio_x
, confirm_state new_state
)
443 sdio_x
->dtctrl_bit
.tfren
= new_state
;
447 * @brief get the number of remaining data bytes to be transferred.
448 * @param sdio_x: to select the sdio peripheral.
449 * this parameter can be one of the following values:
451 * @retval uint32_t: number of bytes
453 uint32_t sdio_data_counter_get(sdio_type
*sdio_x
)
455 return sdio_x
->dtcnt
;
459 * @brief read a word data from sdio fifo.
460 * @param sdio_x: to select the sdio peripheral.
461 * this parameter can be one of the following values:
463 * @retval uint32_t: data received
465 uint32_t sdio_data_read(sdio_type
*sdio_x
)
471 * @brief get the number of words left to be written to or read from fifo..
472 * @param sdio_x: to select the sdio peripheral.
473 * this parameter can be one of the following values:
475 * @retval uint32_t: number of words
477 uint32_t sdio_buffer_counter_get(sdio_type
*sdio_x
)
479 return sdio_x
->bufcnt
;
483 * @brief write one word data to fifo.
484 * @param sdio_x: to select the sdio peripheral.
485 * this parameter can be one of the following values:
487 * @param data: data to be transferred.
490 void sdio_data_write(sdio_type
*sdio_x
, uint32_t data
)
496 * @brief set the read wait mode.
497 * @param sdio_x: to select the sdio peripheral.
498 * this parameter can be one of the following values:
501 * this parameter can be one of the following values:
502 * - SDIO_READ_WAIT_CONTROLLED_BY_D2
503 * - SDIO_READ_WAIT_CONTROLLED_BY_CK
506 void sdio_read_wait_mode_set(sdio_type
*sdio_x
, sdio_read_wait_mode_type mode
)
508 sdio_x
->dtctrl_bit
.rdwtmode
= mode
;
512 * @brief enable or disable to start sd i/o read wait operation.
513 * @param sdio_x: to select the sdio peripheral.
514 * this parameter can be one of the following values:
516 * @param new_state (TRUE or FALSE)
519 void sdio_read_wait_start(sdio_type
*sdio_x
, confirm_state new_state
)
521 sdio_x
->dtctrl_bit
.rdwtstart
= new_state
;
525 * @brief enable or disable to stop sd i/o read wait operation.
526 * @param sdio_x: to select the sdio peripheral.
527 * this parameter can be one of the following values:
529 * @param new_state (TRUE or FALSE)
532 void sdio_read_wait_stop(sdio_type
*sdio_x
, confirm_state new_state
)
534 sdio_x
->dtctrl_bit
.rdwtstop
= new_state
;
538 * @brief enable or disable the sd i/o function.
539 * @param sdio_x: to select the sdio peripheral.
540 * this parameter can be one of the following values:
542 * @param new_state (TRUE or FALSE)
545 void sdio_io_function_enable(sdio_type
*sdio_x
, confirm_state new_state
)
547 sdio_x
->dtctrl_bit
.ioen
= new_state
;
551 * @brief enable or disable sd i/o suspend command sending.
552 * @param sdio_x: to select the sdio peripheral.
553 * this parameter can be one of the following values:
555 * @param new_state (TRUE or FALSE)
558 void sdio_io_suspend_command_set(sdio_type
*sdio_x
, confirm_state new_state
)
560 sdio_x
->cmdctrl_bit
.iosusp
= new_state
;