1 /* 2 * Copyright (c) 2006-2021, RT-Thread Development Team 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 * 6 * Change Logs: 7 * Date Author Notes 8 * 2022-05-16 shelton first version 9 */ 10 11 #ifndef _DRV_SDIO_H 12 #define _DRV_SDIO_H 13 #include <rtthread.h> 14 #include "rtdevice.h" 15 #include <rthw.h> 16 #include <string.h> 17 #include <drivers/dev_mmcsd_core.h> 18 #include <drivers/dev_sdio.h> 19 #include "drv_common.h" 20 21 #define SDCARD_INSTANCE_TYPE sdio_type 22 23 #define SDCARD_INSTANCE SDIO1 24 25 #define SDIO_BUFF_SIZE 4096 26 #define SDIO_ALIGN_LEN 32 27 28 #ifndef SDIO_BASE_ADDRESS 29 #define SDIO_BASE_ADDRESS SDIO1_BASE 30 #endif 31 32 #ifndef SDIO_CLOCK_FREQ 33 #define SDIO_CLOCK_FREQ (48U * 1000 * 1000) 34 #endif 35 36 #ifndef SDIO_BUFF_SIZE 37 #define SDIO_BUFF_SIZE (4096) 38 #endif 39 40 #ifndef SDIO_ALIGN_LEN 41 #define SDIO_ALIGN_LEN (32) 42 #endif 43 44 #ifndef SDIO_MAX_FREQ 45 #define SDIO_MAX_FREQ (24 * 1000 * 1000) 46 #endif 47 48 #define HW_SDIO_IT_CCRCFAIL (0x01U << 0) 49 #define HW_SDIO_IT_DCRCFAIL (0x01U << 1) 50 #define HW_SDIO_IT_CTIMEOUT (0x01U << 2) 51 #define HW_SDIO_IT_DTIMEOUT (0x01U << 3) 52 #define HW_SDIO_IT_TXUNDERR (0x01U << 4) 53 #define HW_SDIO_IT_RXOVERR (0x01U << 5) 54 #define HW_SDIO_IT_CMDREND (0x01U << 6) 55 #define HW_SDIO_IT_CMDSENT (0x01U << 7) 56 #define HW_SDIO_IT_DATAEND (0x01U << 8) 57 #define HW_SDIO_IT_STBITERR (0x01U << 9) 58 #define HW_SDIO_IT_DBCKEND (0x01U << 10) 59 #define HW_SDIO_IT_CMDACT (0x01U << 11) 60 #define HW_SDIO_IT_TXACT (0x01U << 12) 61 #define HW_SDIO_IT_RXACT (0x01U << 13) 62 #define HW_SDIO_IT_TXFIFOHE (0x01U << 14) 63 #define HW_SDIO_IT_RXFIFOHF (0x01U << 15) 64 #define HW_SDIO_IT_TXFIFOF (0x01U << 16) 65 #define HW_SDIO_IT_RXFIFOF (0x01U << 17) 66 #define HW_SDIO_IT_TXFIFOE (0x01U << 18) 67 #define HW_SDIO_IT_RXFIFOE (0x01U << 19) 68 #define HW_SDIO_IT_TXDAVL (0x01U << 20) 69 #define HW_SDIO_IT_RXDAVL (0x01U << 21) 70 #define HW_SDIO_IT_SDIOIT (0x01U << 22) 71 72 #define HW_SDIO_ERRORS \ 73 (HW_SDIO_IT_CCRCFAIL | HW_SDIO_IT_CTIMEOUT | \ 74 HW_SDIO_IT_DCRCFAIL | HW_SDIO_IT_DTIMEOUT | \ 75 HW_SDIO_IT_RXOVERR | HW_SDIO_IT_TXUNDERR) 76 77 #define HW_SDIO_POWER_OFF (0x00U) 78 #define HW_SDIO_POWER_UP (0x02U) 79 #define HW_SDIO_POWER_ON (0x03U) 80 81 #define HW_SDIO_FLOW_ENABLE (0x01U << 14) 82 #define HW_SDIO_BUSWIDE_1B (0x00U << 11) 83 #define HW_SDIO_BUSWIDE_4B (0x01U << 11) 84 #define HW_SDIO_BUSWIDE_8B (0x02U << 11) 85 #define HW_SDIO_BYPASS_ENABLE (0x01U << 10) 86 #define HW_SDIO_IDLE_ENABLE (0x01U << 9) 87 #define HW_SDIO_CLK_ENABLE (0x01U << 8) 88 89 #define HW_SDIO_SUSPEND_CMD (0x01U << 11) 90 #define HW_SDIO_CPSM_ENABLE (0x01U << 10) 91 #define HW_SDIO_WAIT_END (0x01U << 9) 92 #define HW_SDIO_WAIT_INT (0x01U << 8) 93 #define HW_SDIO_RESPONSE_NO (0x00U << 6) 94 #define HW_SDIO_RESPONSE_SHORT (0x01U << 6) 95 #define HW_SDIO_RESPONSE_LONG (0x03U << 6) 96 97 #define HW_SDIO_DATA_LEN_MASK (0x01FFFFFFU) 98 99 #define HW_SDIO_IO_ENABLE (0x01U << 11) 100 #define HW_SDIO_RWMOD_CK (0x01U << 10) 101 #define HW_SDIO_RWSTOP_ENABLE (0x01U << 9) 102 #define HW_SDIO_RWSTART_ENABLE (0x01U << 8) 103 #define HW_SDIO_DBLOCKSIZE_1 (0x00U << 4) 104 #define HW_SDIO_DBLOCKSIZE_2 (0x01U << 4) 105 #define HW_SDIO_DBLOCKSIZE_4 (0x02U << 4) 106 #define HW_SDIO_DBLOCKSIZE_8 (0x03U << 4) 107 #define HW_SDIO_DBLOCKSIZE_16 (0x04U << 4) 108 #define HW_SDIO_DBLOCKSIZE_32 (0x05U << 4) 109 #define HW_SDIO_DBLOCKSIZE_64 (0x06U << 4) 110 #define HW_SDIO_DBLOCKSIZE_128 (0x07U << 4) 111 #define HW_SDIO_DBLOCKSIZE_256 (0x08U << 4) 112 #define HW_SDIO_DBLOCKSIZE_512 (0x09U << 4) 113 #define HW_SDIO_DBLOCKSIZE_1024 (0x0AU << 4) 114 #define HW_SDIO_DBLOCKSIZE_2048 (0x0BU << 4) 115 #define HW_SDIO_DBLOCKSIZE_4096 (0x0CU << 4) 116 #define HW_SDIO_DBLOCKSIZE_8192 (0x0DU << 4) 117 #define HW_SDIO_DBLOCKSIZE_16384 (0x0EU << 4) 118 #define HW_SDIO_DMA_ENABLE (0x01U << 3) 119 #define HW_SDIO_STREAM_ENABLE (0x01U << 2) 120 #define HW_SDIO_TO_HOST (0x01U << 1) 121 #define HW_SDIO_DPSM_ENABLE (0x01U << 0) 122 123 #define HW_SDIO_DATATIMEOUT (0xF0000000U) 124 125 struct at32_sdio 126 { 127 volatile rt_uint32_t power; 128 volatile rt_uint32_t clkcr; 129 volatile rt_uint32_t arg; 130 volatile rt_uint32_t cmd; 131 volatile rt_uint32_t respcmd; 132 volatile rt_uint32_t resp1; 133 volatile rt_uint32_t resp2; 134 volatile rt_uint32_t resp3; 135 volatile rt_uint32_t resp4; 136 volatile rt_uint32_t dtimer; 137 volatile rt_uint32_t dlen; 138 volatile rt_uint32_t dctrl; 139 volatile rt_uint32_t dcount; 140 volatile rt_uint32_t sta; 141 volatile rt_uint32_t icr; 142 volatile rt_uint32_t mask; 143 volatile rt_uint32_t reserved0[2]; 144 volatile rt_uint32_t fifocnt; 145 volatile rt_uint32_t reserved1[13]; 146 volatile rt_uint32_t fifo; 147 }; 148 149 typedef rt_err_t (*dma_txconfig)(rt_uint32_t *src, rt_uint32_t *dst, int size); 150 typedef rt_err_t (*dma_rxconfig)(rt_uint32_t *src, rt_uint32_t *dst, int size); 151 typedef rt_uint32_t (*sdio_clk_get)(struct at32_sdio *hw_sdio); 152 153 #if defined (SOC_SERIES_AT32F435) || defined (SOC_SERIES_AT32F437) || \ 154 defined (SOC_SERIES_AT32F455) || defined (SOC_SERIES_AT32F456) || \ 155 defined (SOC_SERIES_AT32F457) 156 #define SDIO_BUS_CONFIG \ 157 { \ 158 .sdio_x = SDIO1, \ 159 .dma_rx.dma_x = DMA2, \ 160 .dma_tx.dma_x = DMA2, \ 161 .dma_rx.dma_crm = CRM_DMA2_PERIPH_CLOCK, \ 162 .dma_tx.dma_crm = CRM_DMA2_PERIPH_CLOCK, \ 163 .dma_rx.dma_channel = DMA2_CHANNEL4, \ 164 .dma_tx.dma_channel = DMA2_CHANNEL4, \ 165 .dma_rx.dma_irq = DMA2_Channel4_IRQn, \ 166 .dma_tx.dma_irq = DMA2_Channel4_IRQn, \ 167 .dma_rx.dmamux_channel = DMA2MUX_CHANNEL4, \ 168 .dma_tx.dmamux_channel = DMA2MUX_CHANNEL4, \ 169 .dma_rx.dmamux_id = DMAMUX_DMAREQ_ID_SDIO1, \ 170 .dma_tx.dmamux_id = DMAMUX_DMAREQ_ID_SDIO1, \ 171 } 172 #else 173 #define SDIO_BUS_CONFIG \ 174 { \ 175 .sdio_x = SDIO1, \ 176 .dma_rx.dma_crm = CRM_DMA2_PERIPH_CLOCK, \ 177 .dma_tx.dma_crm = CRM_DMA2_PERIPH_CLOCK, \ 178 .dma_rx.dma_channel = DMA2_CHANNEL4, \ 179 .dma_rx.dma_irq = DMA2_Channel4_5_IRQn, \ 180 .dma_tx.dma_channel = DMA2_CHANNEL4, \ 181 .dma_tx.dma_irq = DMA2_Channel4_5_IRQn, \ 182 } 183 #endif 184 185 struct dma_config { 186 dma_type *dma_x; 187 dma_channel_type *dma_channel; 188 #if defined (SOC_SERIES_AT32F435) || defined (SOC_SERIES_AT32F437) || \ 189 defined (SOC_SERIES_AT32F455) || defined (SOC_SERIES_AT32F456) || \ 190 defined (SOC_SERIES_AT32F457) 191 dmamux_channel_type *dmamux_channel; 192 dmamux_requst_id_sel_type dmamux_id; 193 #endif 194 crm_periph_clock_type dma_crm; 195 IRQn_Type dma_irq; 196 }; 197 198 struct at32_sdio_des 199 { 200 struct at32_sdio *hw_sdio; 201 dma_txconfig txconfig; 202 dma_rxconfig rxconfig; 203 sdio_clk_get clk_get; 204 }; 205 206 struct at32_sdio_config 207 { 208 SDCARD_INSTANCE_TYPE *sdio_x; 209 struct dma_config dma_rx, dma_tx; 210 }; 211 212 /* at32 sdio dirver class */ 213 struct at32_sdio_class 214 { 215 struct at32_sdio_des *des; 216 const struct at32_sdio_config *cfg; 217 struct rt_mmcsd_host host; 218 struct 219 { 220 dma_channel_type* handle_rx; 221 dma_channel_type* handle_tx; 222 } dma; 223 }; 224 225 extern void at32_mmcsd_change(void); 226 227 #endif 228