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