before merging master
[inav.git] / lib / main / AT32F43x / Drivers / AT32F43x_StdPeriph_Driver / src / at32f435_437_sdio.c
blob2cff6dc727f6ab63c40e7a48769b37a55b6f2bd7
1 /**
2 **************************************************************************
3 * @file at32f435_437_sdio.c
4 * @version v2.1.0
5 * @date 2022-08-16
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
30 * @{
33 /** @defgroup SDIO
34 * @brief SDIO driver modules
35 * @{
38 #ifdef SDIO_MODULE_ENABLED
40 /** @defgroup SDIO_private_functions
41 * @{
44 /**
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:
48 * SDIO1, SDIO2.
49 * @retval none
51 void sdio_reset(sdio_type *sdio_x)
53 sdio_x->pwrctrl = 0x0;
54 sdio_x->clkctrl = 0x0;
55 sdio_x->argu = 0x0;
56 sdio_x->cmdctrl = 0x0;
57 sdio_x->dttmr = 0x0;
58 sdio_x->dtlen = 0x0;
59 sdio_x->dtctrl = 0x0;
60 sdio_x->inten = 0x0;
61 sdio_x->intclr = 0x004007FF;
64 /**
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:
68 * SDIO1, SDIO2.
69 * @param power_state
70 * this parameter can be one of the following values:
71 * - SDIO_POWER_OFF
72 * - SDIO_POWER_ON
73 * @retval none
75 void sdio_power_set(sdio_type *sdio_x, sdio_power_state_type power_state)
77 sdio_x->pwrctrl_bit.ps = power_state;
80 /**
81 * @brief get power status.
82 * @param sdio_x: to select the sdio peripheral.
83 * this parameter can be one of the following values:
84 * SDIO1, SDIO2.
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);
92 /**
93 * @brief config sdio clock
94 * @param sdio_x: to select the sdio peripheral.
95 * this parameter can be one of the following values:
96 * SDIO1, SDIO2.
97 * @param clk_div: sdio clock divide factor(frequency = sdio_clk / [clk_psc + 2]).
98 * @param clk_edg
99 * this parameter can be one of the following values:
100 * - SDIO_CLOCK_EDGE_RISING
101 * - SDIO_CLOCK_EDGE_FALLING
102 * @retval none
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:
120 * SDIO1, SDIO2.
121 * @param width
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
126 * @retval none
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:
137 * SDIO1, SDIO2.
138 * @param new_state (TRUE or FALSE)
139 * @retval none
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:
151 * SDIO1, SDIO2.
152 * @param new_state (TRUE or FALSE)
153 * @retval none
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:
164 * SDIO1, SDIO2.
165 * @param new_state (TRUE or FALSE)
166 * @retval none
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:
177 * SDIO1, SDIO2.
178 * @param new_state (TRUE or FALSE)
179 * @retval none
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:
190 * SDIO1, SDIO2.
191 * @param new_state (TRUE or FALSE)
192 * @retval none
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:
203 * SDIO1, SDIO2.
204 * @param int_opt
205 * this parameter can be one of the following values:
206 * - SDIO_CMDFAIL_INT
207 * - SDIO_DTFAIL_INT
208 * - SDIO_CMDTIMEOUT_INT
209 * - SDIO_DTTIMEOUT_INT
210 * - SDIO_TXERRU_INT
211 * - SDIO_RXERRO_INT
212 * - SDIO_CMDRSPCMPL_INT
213 * - SDIO_CMDCMPL_INT
214 * - SDIO_DTCMP_INT
215 * - SDIO_SBITERR_INT
216 * - SDIO_DTBLKCMPL_INT
217 * - SDIO_DOCMD_INT
218 * - SDIO_DOTX_INT
219 * - SDIO_DORX_INT
220 * - SDIO_TXBUFH_INT
221 * - SDIO_RXBUFH_INT
222 * - SDIO_TXBUFF_INT
223 * - SDIO_RXBUFF_INT
224 * - SDIO_TXBUFE_INT
225 * - SDIO_RXBUFE_INT
226 * - SDIO_TXBUF_INT
227 * - SDIO_RXBUF_INT
228 * - SDIO_SDIOIF_INT
229 * @param new_state (TRUE or FALSE)
230 * @retval none
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 */
240 else
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:
250 * SDIO1, SDIO2.
251 * @param flag
252 * this parameter can be one of the following values:
253 * - SDIO_CMDFAIL_FLAG
254 * - SDIO_DTFAIL_FLAG
255 * - SDIO_CMDTIMEOUT_FLAG
256 * - SDIO_DTTIMEOUT_FLAG
257 * - SDIO_TXERRU_FLAG
258 * - SDIO_RXERRO_FLAG
259 * - SDIO_CMDRSPCMPL_FLAG
260 * - SDIO_CMDCMPL_FLAG
261 * - SDIO_DTCMPL_FLAG
262 * - SDIO_SBITERR_FLAG
263 * - SDIO_DTBLKCMPL_FLAG
264 * - SDIO_DOCMD_FLAG
265 * - SDIO_DOTX_FLAG
266 * - SDIO_DORX_FLAG
267 * - SDIO_TXBUFH_FLAG
268 * - SDIO_RXBUFH_FLAG
269 * - SDIO_TXBUFF_FLAG
270 * - SDIO_RXBUFF_FLAG
271 * - SDIO_TXBUFE_FLAG
272 * - SDIO_RXBUFE_FLAG
273 * - SDIO_TXBUF_FLAG
274 * - SDIO_RXBUF_FLAG
275 * - SDIO_SDIOIF_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)
284 status = SET;
286 else
288 status = RESET;
291 return status;
295 * @brief clear sdio flag.
296 * @param sdio_x: to select the sdio peripheral.
297 * this parameter can be one of the following values:
298 * SDIO1, SDIO2.
299 * @param int_opt
300 * this parameter can be any combination of the following values:
301 * - SDIO_CMDFAIL_FLAG
302 * - SDIO_DTFAIL_FLAG
303 * - SDIO_CMDTIMEOUT_FLAG
304 * - SDIO_DTTIMEOUT_FLAG
305 * - SDIO_TXERRU_FLAG
306 * - SDIO_RXERRO_FLAG
307 * - SDIO_CMDRSPCMPL_FLAG
308 * - SDIO_CMDCMPL_FLAG
309 * - SDIO_DTCMPL_FLAG
310 * - SDIO_SBITERR_FLAG
311 * - SDIO_DTBLKCMPL_FLAG
312 * - SDIO_SDIOIF_FLAG
313 * @retval none
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:
324 * SDIO1, SDIO2.
325 * @param command_struct : pointer to a sdio_command_struct_type structure
326 * that contains the configuration information for the sdio command.
327 * @retval none
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:
348 * SDIO1, SDIO2.
349 * @param new_state (TRUE or FALSE)
350 * @retval none
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:
361 * SDIO1, SDIO2.
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:
374 * SDIO1, SDIO2.
375 * @param reg_index
376 * this parameter can be one of the following values:
377 * - SDIO_RSP1_INDEX
378 * - SDIO_RSP2_INDEX
379 * - SDIO_RSP3_INDEX
380 * - SDIO_RSP4_INDEX
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;
387 switch(reg_index)
389 case SDIO_RSP1_INDEX:
390 response_value = sdio_x->rsp1;
391 break;
392 case SDIO_RSP2_INDEX:
393 response_value = sdio_x->rsp2;
394 break;
395 case SDIO_RSP3_INDEX:
396 response_value = sdio_x->rsp3;
397 break;
398 case SDIO_RSP4_INDEX:
399 response_value = sdio_x->rsp4;
400 break;
401 default: break;
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:
411 * SDIO1, SDIO2.
412 * @param data_struct : pointer to a sdio_data_struct_type structure
413 * that contains the configuration information for the sdio data.
414 * @retval none
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:
437 * SDIO1, SDIO2.
438 * @param new_state (TRUE or FALSE)
439 * @retval none
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:
450 * SDIO1, SDIO2.
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:
462 * SDIO1, SDIO2.
463 * @retval uint32_t: data received
465 uint32_t sdio_data_read(sdio_type *sdio_x)
467 return sdio_x->buf;
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:
474 * SDIO1, SDIO2.
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:
486 * SDIO1, SDIO2.
487 * @param data: data to be transferred.
488 * @retval none
490 void sdio_data_write(sdio_type *sdio_x, uint32_t data)
492 sdio_x->buf = 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:
499 * SDIO1, SDIO2.
500 * @param mode
501 * this parameter can be one of the following values:
502 * - SDIO_READ_WAIT_CONTROLLED_BY_D2
503 * - SDIO_READ_WAIT_CONTROLLED_BY_CK
504 * @retval none
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:
515 * SDIO1, SDIO2.
516 * @param new_state (TRUE or FALSE)
517 * @retval none
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:
528 * SDIO1, SDIO2.
529 * @param new_state (TRUE or FALSE)
530 * @retval none
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:
541 * SDIO1, SDIO2.
542 * @param new_state (TRUE or FALSE)
543 * @retval none
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:
554 * SDIO1, SDIO2.
555 * @param new_state (TRUE or FALSE)
556 * @retval none
558 void sdio_io_suspend_command_set(sdio_type *sdio_x, confirm_state new_state)
560 sdio_x->cmdctrl_bit.iosusp = new_state;
564 * @}
567 #endif
570 * @}
574 * @}