|
| 1 | +/****************************************************************************** |
| 2 | + * |
| 3 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
| 4 | + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
| 5 | + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
| 6 | + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS |
| 7 | + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN |
| 8 | + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN |
| 9 | + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
| 10 | + * SOFTWARE. |
| 11 | + *****************************************************************************/ |
| 12 | + |
| 13 | +/** |
| 14 | + * @file sdio.h |
| 15 | + * @brief Secure digital input/output interface. |
| 16 | + */ |
| 17 | + |
| 18 | +#ifndef _SDIO_H_ |
| 19 | +#define _SDIO_H_ |
| 20 | + |
| 21 | +#include <libmaple/libmaple_types.h> |
| 22 | +#include <libmaple/stm32.h> |
| 23 | +#include <libmaple/gpio.h> |
| 24 | + |
| 25 | + |
| 26 | +/* |
| 27 | +#include <libmaple/rcc.h> |
| 28 | +#include <libmaple/nvic.h> |
| 29 | +
|
| 30 | +//#include <boards.h> |
| 31 | +#include <stdint.h> |
| 32 | +//#include <wirish.h> |
| 33 | + */ |
| 34 | + |
| 35 | +#if defined(STM32_HIGH_DENSITY) || defined(STM32_XL_DENSITY) |
| 36 | + |
| 37 | +/* |
| 38 | + * DMA controller and channel used in STM32F103 |
| 39 | + */ |
| 40 | + |
| 41 | +#define SDIO_DMA_DEV DMA2 |
| 42 | +#define SDIO_DMA_CHANNEL DMA_CH4 |
| 43 | +/* |
| 44 | +#ifdef __cplusplus |
| 45 | +extern "C" { |
| 46 | +#endif |
| 47 | +*/ |
| 48 | + |
| 49 | +/* |
| 50 | + * Register maps and devices |
| 51 | + */ |
| 52 | + |
| 53 | +// SDIO register map type |
| 54 | +typedef struct sdio_reg_map { |
| 55 | + __io uint32 POWER; // 0x00 |
| 56 | + __io uint32 CLKCR; // 0x04 |
| 57 | + __io uint32 ARG; // 0x08 |
| 58 | + __io uint32 CMD; // 0x0C |
| 59 | + __io uint32 RESPCMD; // 0x10 (0x3F) |
| 60 | + const uint32 RESP[4]; // 0x14 - contain the card status, which is part of the received response. |
| 61 | + __io uint32 DTIMER; // 0x24 - contains the data timeout period, in card bus clock periods. |
| 62 | + __io uint32 DLEN; // 0x28 (0x01FF FFFF) - contains the number of data bytes to be transferred |
| 63 | + __io uint32 DCTRL; // 0x2C |
| 64 | + __io uint32 DCOUNT; // 0x30 (0x01FF FFFF) |
| 65 | + __io uint32 STA; // 0x34 |
| 66 | + __io uint32 ICR; // 0x38 |
| 67 | + __io uint32 MASK; // 0x3C |
| 68 | + const uint32 RESERVED1[2]; |
| 69 | + __io uint32 FIFOCNT; // 0x48 (0x01FF FFFF) |
| 70 | + const uint32 RESERVED2[13]; |
| 71 | + __io uint32 FIFO; // 0x80 |
| 72 | +} sdio_reg_map; |
| 73 | +#define sdio_dev sdio_reg_map |
| 74 | + |
| 75 | +/** SDIO register map base pointer */ |
| 76 | +#define SDIO_BASE ((struct sdio_reg_map*)0x40018000) |
| 77 | + |
| 78 | +extern sdio_dev * SDIO; |
| 79 | + |
| 80 | +/* |
| 81 | + * Register bit definitions |
| 82 | + */ |
| 83 | + |
| 84 | +/* NOR/PSRAM chip-select control registers */ |
| 85 | + |
| 86 | +// SDIO_POWER register bits |
| 87 | +// At least seven HCLK clock periods are needed between two write accesses to this register. |
| 88 | +// After a data write, data cannot be written to this register for three SDIOCLK clock periods |
| 89 | +// plus two PCLK2 clock periods. |
| 90 | +#define SDIO_POWER_PWRCTRL_OFF 0x00 |
| 91 | +#define SDIO_POWER_PWRCTRL_ON 0x03 |
| 92 | + |
| 93 | +// SDIO_CLKCR register bits |
| 94 | +// Controls the SDIO_CK output clock. |
| 95 | +// After a data write, data cannot be written to this register for three SDIOCLK clock periods |
| 96 | +// plus two PCLK2 clock periods. SDIO_CK can also be stopped during the read wait interval |
| 97 | +// for SD I/O cards: in this case the SDIO_CLKCR register does not control SDIO_CK. |
| 98 | +#define SDIO_CLKCR_HWFC_EN (1<<14) // HW Flow Control enable - DON'T USE!!! (see errata sheet 2.12.1) |
| 99 | + // Overrun errors (Rx mode) and FIFO underrun (Tx mode) |
| 100 | + // should be managed by the application software. |
| 101 | +#define SDIO_CLKCR_NEGEDGE (1<<13) // SDIO_CK de-phasing selection bit - DON'T USE!!! (see errata sheet 2.12.4) |
| 102 | +#define SDIO_CLKCR_WIDBUS (3<<11) // Data bus width |
| 103 | +#define SDIO_CLKCR_WIDBUS_1BIT (0<<11) // 1 bit (SDIO_D0 used) |
| 104 | +#define SDIO_CLKCR_WIDBUS_4BIT (1<<11) // 4-bit (SDIO_D[3:0] used) |
| 105 | +#define SDIO_CLKCR_BYPASS (1<<10) // Clock divider bypass enable bit - SDIO_CK = SDIOCLK, CLKDIV not relevant. |
| 106 | +#define SDIO_CLKCR_PWRSAV (1<<9) // 0: SDIO_CK clock is always enabled, 1: SDIO_CK is only enabled when the bus is active |
| 107 | +#define SDIO_CLKCR_CLKEN (1<<8) // Clock enable |
| 108 | +#define SDIO_CLKCR_CLKDIV (0xFF) // SDIO_CK = SDIOCLK / [CLKDIV + 2] |
| 109 | +#define SDIOCLK 72000000UL // SDIO master clock frequency |
| 110 | + |
| 111 | +// SDIO_CMD register bits |
| 112 | +// After a data write, data cannot be written to this register for three SDIOCLK clock periods |
| 113 | +// plus two PCLK2 clock periods. |
| 114 | +// MultiMediaCards can send two kinds of response: short responses, 48 bits long, or long |
| 115 | +// responses,136 bits long. SD card and SD I/O card can send only short responses, the |
| 116 | +// argument can vary according to the type of response: the software will distinguish the type |
| 117 | +// of response according to the sent command. CE-ATA devices send only short responses. |
| 118 | +#define SDIO_CMD_ATACMD (1<<14) |
| 119 | +#define SDIO_CMD_NIEN (1<<13) |
| 120 | +#define SDIO_CMD_ENCMDCOMPL (1<<12) |
| 121 | +#define SDIO_CMD_SDIOSUSPEND (1<<11) |
| 122 | +#define SDIO_CMD_CPSMEN (1<<10) |
| 123 | +#define SDIO_CMD_WAITPEND (1<<9) |
| 124 | +#define SDIO_CMD_WAITINT (1<<8) |
| 125 | +#define SDIO_CMD_WAITRESP (3<<6) |
| 126 | +#define SDIO_CMD_WAIT_NO_RESP (0<<6) |
| 127 | +#define SDIO_CMD_WAIT_SHORT_RESP (1<<6) |
| 128 | +#define SDIO_CMD_WAIT_LONG_RESP (3<<6) |
| 129 | +#define SDIO_CMD_CMDINDEX (0x3F) |
| 130 | + |
| 131 | +// SDIO_DLEN register bits |
| 132 | +// For a block data transfer, the value in the data length register must be a multiple of the block |
| 133 | +// size (see SDIO_DCTRL). A data transfer must be written to the data timer register and the |
| 134 | +// data length register before being written to the data control register. |
| 135 | +// For an SDIO multibyte transfer the value in the data length register must be between 1 and 512. |
| 136 | +#define SDIO_DLEN_DATALENGTH (0x01FFFFFF) |
| 137 | + |
| 138 | +// SDIO_DCTRL register bits |
| 139 | +// Controls the data path state machine (DPSM). |
| 140 | +// After a data write, data cannot be written to this register for three SDIOCLK clock periods |
| 141 | +// plus two PCLK2 clock periods. |
| 142 | +#define SDIO_DCTRL_SDIOEN (1<<11) // the DPSM performs an SD I/O-card-specific operation. |
| 143 | +#define SDIO_DCTRL_RWMODE (1<<10) // 0: Read Wait control stopping SDIO_D2, 1:Read Wait control using SDIO_CK |
| 144 | +#define SDIO_DCTRL_RWSTOP (1<<9) // 0: Read wait in progress if RWSTART bit is set, 1: Enable for read wait stop if RWSTART bit is set |
| 145 | +#define SDIO_DCTRL_RWSTART (1<<8) // read wait operation starts |
| 146 | +#define SDIO_DCTRL_DBLOCKSIZE (0xF<<4) // Define the data block length when the block data transfer mode is selected: 2^N bytes |
| 147 | +#define SDIO_BLOCKSIZE_64 (6<<4) |
| 148 | +#define SDIO_BLOCKSIZE_512 (9<<4) |
| 149 | +#define SDIO_DCTRL_DMAEN (1<<3) // DMA enable |
| 150 | +#define SDIO_DCTRL_DTMODE (1<<2) // Data transfer mode selection: 0: Block data transfer, 1: Stream or SDIO multi-byte data transfer |
| 151 | +#define SDIO_DCTRL_DTDIR (1<<1) // Data transfer direction selection: 0: From controller to card, 1: From card to controller. |
| 152 | +#define SDIO_DIR_TX (0<<1) |
| 153 | +#define SDIO_DIR_RX (1<<1) |
| 154 | +#define SDIO_DCTRL_DTEN (1<<0) // Start data transfer. Depending on the direction bit, DTDIR, |
| 155 | + // the DPSM moves to the Wait_S, Wait_R state or Readwait if RW Start is set immediately at |
| 156 | + // the beginning of the transfer. It is not necessary to clear the enable bit after the end of a data |
| 157 | + // transfer but the SDIO_DCTRL must be updated to enable a new data transfer |
| 158 | +// The meaning of the DTMODE bit changes according to the value of the SDIOEN bit: |
| 159 | +// When DTEN=0 and DTMODE=1, the MultiMediaCard stream mode is enabled. |
| 160 | +// When DTEN=1 and DTMODE=1, the peripheral enables an SDIO multi-byte transfer. |
| 161 | + |
| 162 | +// SDIO_STA register bits |
| 163 | +#define SDIO_STA_CEATAEND (1<<23) // CE-ATA command completion signal received for CMD61 |
| 164 | +#define SDIO_STA_SDIOIT (1<<22) // SDIO interrupt received |
| 165 | +#define SDIO_STA_RXDAVL (1<<21) // Data available in receive FIFO |
| 166 | +#define SDIO_STA_TXDAVL (1<<20) // Data available in transmit FIFO |
| 167 | +#define SDIO_STA_RXFIFOE (1<<19) // Receive FIFO empty |
| 168 | +#define SDIO_STA_TXFIFOE (1<<18) // Transmit FIFO empty (2 words) |
| 169 | +#define SDIO_STA_RXFIFOF (1<<17) // Receive FIFO full (2 words before the FIFO is full.) |
| 170 | +#define SDIO_STA_TXFIFOF (1<<16) // Transmit FIFO full |
| 171 | +#define SDIO_STA_RXFIFOHF (1<<15) // Receive FIFO half full: there are at least 8 words in the FIFO |
| 172 | +#define SDIO_STA_TXFIFOHE (1<<14) // Transmit FIFO half empty: at least 8 words can be written into the FIFO |
| 173 | +#define SDIO_STA_RXACT (1<<13) // Data receive in progress |
| 174 | +#define SDIO_STA_TXACT (1<<12) // Data transmit in progress |
| 175 | +#define SDIO_STA_CMDACT (1<<11) // Command transfer in progress |
| 176 | +#define SDIO_STA_DBCKEND (1<<10) // Data block sent/received (CRC check passed) |
| 177 | +#define SDIO_STA_STBITERR (1<<9) // Start bit not detected on all data signals in wide bus mode |
| 178 | +#define SDIO_STA_DATAEND (1<<8) // Data end (data counter SDIOCOUNT is zero) |
| 179 | +#define SDIO_STA_CMDSENT (1<<7) // Command sent (no response required) |
| 180 | +#define SDIO_STA_CMDREND (1<<6) // Command response received (CRC check passed) |
| 181 | +#define SDIO_STA_RXOVERR (1<<5) // Received FIFO overrun error |
| 182 | +#define SDIO_STA_TXUNDERR (1<<4) // Transmit FIFO underrun error |
| 183 | +#define SDIO_STA_DTIMEOUT (1<<3) // Data timeout |
| 184 | +#define SDIO_STA_CTIMEOUT (1<<2) // Command response timeout. The Command TimeOut period has a fixed value of 64 SDIO_CK clock periods. |
| 185 | +#define SDIO_STA_DCRCFAIL (1<<1) // Data block sent/received (CRC check failed) |
| 186 | +#define SDIO_STA_CCRCFAIL (1<<0) // Command response received (CRC check failed) |
| 187 | + |
| 188 | +#define SDIO_STA_CMD_ERROR_FLAGS (SDIO_STA_CTIMEOUT | SDIO_STA_CCRCFAIL) |
| 189 | +#define SDIO_STA_TRX_ERROR_FLAGS (SDIO_STA_STBITERR | SDIO_STA_RXOVERR | SDIO_STA_TXUNDERR | SDIO_STA_DTIMEOUT | SDIO_STA_DCRCFAIL) |
| 190 | +#define SDIO_STA_TRX_ACT_FLAGS (SDIO_STA_RXACT|SDIO_STA_TXACT) |
| 191 | + |
| 192 | +// SDIO_ICR register bits (WO - write only) |
| 193 | +#define SDIO_ICR_CEATAENDC (1<<23) // clear CEATAEND flag |
| 194 | +#define SDIO_ICR_SDIOITC (1<<22) // clear SDIOIT flag |
| 195 | +#define SDIO_ICR_DBCKENDC (1<<10) // clear DBCKENDC flag |
| 196 | +#define SDIO_ICR_STBITERRC (1<<9) // clear STBITERRC flag |
| 197 | +#define SDIO_ICR_DATAENDC (1<<8) // clear DATAENDC flag |
| 198 | +#define SDIO_ICR_CMDSENTC (1<<7) // clear CMDSENTC flag |
| 199 | +#define SDIO_ICR_CMDRENDC (1<<6) // clear CMDREND flag |
| 200 | +#define SDIO_ICR_RXOVERRC (1<<5) // clear RXOVERR flag |
| 201 | +#define SDIO_ICR_TXUNDERRC (1<<4) // clear TXUNDERR flag |
| 202 | +#define SDIO_ICR_DTIMEOUTC (1<<3) // clear DTIMEOUT flag |
| 203 | +#define SDIO_ICR_CTIMEOUTC (1<<2) // clear CTIMEOUT flag |
| 204 | +#define SDIO_ICR_DCRCFAILC (1<<1) // clear DCRCFAIL flag |
| 205 | +#define SDIO_ICR_CCRCFAILC (1<<0) // clear CCRCFAIL flag |
| 206 | + |
| 207 | +#define SDIO_ICR_CMD_FLAGS (SDIO_ICR_CEATAENDC | SDIO_ICR_SDIOITC | SDIO_ICR_CMDSENTC | SDIO_ICR_CMDRENDC | SDIO_ICR_CTIMEOUTC | SDIO_ICR_CCRCFAILC) |
| 208 | +#define SDIO_ICR_DATA_FLAGS (SDIO_ICR_DBCKENDC | SDIO_ICR_STBITERRC | SDIO_ICR_DATAENDC | SDIO_ICR_RXOVERRC | SDIO_ICR_TXUNDERRC | SDIO_ICR_DTIMEOUTC | SDIO_ICR_DCRCFAILC) |
| 209 | + |
| 210 | +// SDIO_MASK register bits |
| 211 | +// Determines which status flags generate an interrupt request by setting the corresponding bit to 1b. |
| 212 | +#define SDIO_MASK_CEATAENDIE (1<<23) // enable CEATAEND interrupt |
| 213 | +#define SDIO_MASK_SDIOITIE (1<<22) // enable SDIOIT interrupt |
| 214 | +#define SDIO_MASK_RXDAVLIE (1<<21) // enable RXDAVL interrupt |
| 215 | +#define SDIO_MASK_TXDAVLIE (1<<20) // enable TXDAVL interrupt |
| 216 | +#define SDIO_MASK_RXFIFOEIE (1<<19) // enable RXFIFOE interrupt |
| 217 | +#define SDIO_MASK_TXFIFOEIE (1<<18) // enable TXFIFOE interrupt |
| 218 | +#define SDIO_MASK_RXFIFOFIE (1<<17) // enable RXFIFOF interrupt |
| 219 | +#define SDIO_MASK_TXFIFOFIE (1<<16) // enable TXFIFOF interrupt |
| 220 | +#define SDIO_MASK_RXFIFOHFIE (1<<15) // enable RXFIFOHF interrupt |
| 221 | +#define SDIO_MASK_TXFIFOHEIE (1<<14) // enable TXFIFOHE interrupt |
| 222 | +#define SDIO_MASK_RXACTIE (1<<13) // enable RXACT interrupt |
| 223 | +#define SDIO_MASK_TXACTIE (1<<12) // enable TXACT interrupt |
| 224 | +#define SDIO_MASK_CMDACTIE (1<<11) // enable CMDACT interrupt |
| 225 | +#define SDIO_MASK_DBCKENDIE (1<<10) // enable DBCKENDC interrupt |
| 226 | +#define SDIO_MASK_STBITERRIE (1<<9) // enable STBITERR interrupt |
| 227 | +#define SDIO_MASK_DATAENDIE (1<<8) // enable DATAENDC interrupt |
| 228 | +#define SDIO_MASK_CMDSENTIE (1<<7) // enable CMDSENTC interrupt |
| 229 | +#define SDIO_MASK_CMDRENDIE (1<<6) // enable CMDREND interrupt |
| 230 | +#define SDIO_MASK_RXOVERRIE (1<<5) // enable RXOVERR interrupt |
| 231 | +#define SDIO_MASK_TXUNDERRIE (1<<4) // enable TXUNDERR interrupt |
| 232 | +#define SDIO_MASK_DTIMEOUTIE (1<<3) // enable DTIMEOUT interrupt |
| 233 | +#define SDIO_MASK_CTIMEOUTIE (1<<2) // enable CTIMEOUT interrupt |
| 234 | +#define SDIO_MASK_DCRCFAILIE (1<<1) // enable DCRCFAIL interrupt |
| 235 | +#define SDIO_MASK_CCRCFAILIE (1<<0) // enable CCRCFAIL interrupt |
| 236 | + |
| 237 | + |
| 238 | +void sdio_enable(void); |
| 239 | +void sdio_disable(void); |
| 240 | +void sdio_begin(void); |
| 241 | +uint8_t sdio_cmd_send(uint16_t cmd_index_resp_type, uint32_t arg); |
| 242 | +void sdio_set_clock(uint32_t clk); |
| 243 | +void sdio_set_dbus_width(uint16_t bus_w); |
| 244 | +void sdio_set_dblock_size(uint8_t dbsize); |
| 245 | +//void sdio_trx_enable(uint8_t dir); |
| 246 | +inline void sdio_trx_enable(void) |
| 247 | +{ |
| 248 | + SDIO->DCTRL |= SDIO_DCTRL_DTEN; // enable data transfer |
| 249 | +} |
| 250 | + |
| 251 | +inline uint32_t sdio_cmd_xfer_ongoing(void) { return (SDIO->STA&SDIO_STA_CMDACT); } |
| 252 | +inline uint32_t sdio_cmd_complete(void) { return (SDIO->STA&SDIO_STA_CMDSENT); } |
| 253 | + |
| 254 | +inline void sdio_setup_transfer(uint32_t dtimer, uint32_t dlen, uint16_t flags) |
| 255 | +{ |
| 256 | + SDIO->ICR = SDIO_ICR_DATA_FLAGS; // clear data access relevant flags |
| 257 | + SDIO->DTIMER = dtimer; |
| 258 | + SDIO->DLEN = dlen; |
| 259 | + SDIO->DCTRL = flags;// | SDIO_DCTRL_DTEN; // enable data transfer |
| 260 | +} |
| 261 | + |
| 262 | +/* |
| 263 | +#ifdef __cplusplus |
| 264 | +} // extern "C" |
| 265 | +#endif |
| 266 | +*/ |
| 267 | + |
| 268 | +#endif /* (STM32_HIGH_DENSITY) || (STM32_XL_DENSITY) */ |
| 269 | + |
| 270 | +#endif |
0 commit comments