|
当前提供的这个MCI_STM32H7XXX驱动文件仅支持SD卡,实际测试并不支持eMMC。
这个自己修改还是有点难度的,而使用老版本的RL-FlashFS好修改些。
之前F4的驱动写法:- #define __DRV_ID mci0_drv
- #define __SDIOCLK 48000000
- #define __CPUCLK 168000000
- /* MCI Driver Interface functions */
- static BOOL Init (void);
- static BOOL UnInit (void);
- static void Delay (U32 us);
- static BOOL BusMode (U32 mode);
- static BOOL BusWidth (U32 width);
- static BOOL BusSpeed (U32 kbaud);
- static BOOL Command (U8 cmd, U32 arg, U32 resp_type, U32 *rp);
- static BOOL ReadBlock (U32 bl, U8 *buf, U32 cnt);
- static BOOL WriteBlock (U32 bl, U8 *buf, U32 cnt);
- static BOOL SetDma (U32 mode, U8 *buf, U32 cnt);
- static U32 CheckMedia (void); /* Optional function for SD card check */
- void SD_Link_EXTIConfig(void);
- /* MCI Device Driver Control Block */
- MCI_DRV __DRV_ID = {
- Init,
- UnInit,
- Delay,
- BusMode,
- BusWidth,
- BusSpeed,
- Command,
- ReadBlock,
- WriteBlock,
- SetDma,
- CheckMedia /* Can be NULL if not existing */
- };
- /* Wait time in for loop cycles */
- #define DMA_TOUT 10000000
- /*--------------------------- Init -------------------------------------------*/
- static BOOL Init (void) {
- /* Initialize SDIO interface. */
- /* Enable GPIOE (card detect), GPIOD (command), GPIOC (data) clock */
- RCC->AHB1ENR |= RCC_AHB1ENR_GPIOEEN |
- RCC_AHB1ENR_GPIODEN |
- RCC_AHB1ENR_GPIOCEN;
- RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN;
- /* Enable IO compensation cell */
- SYSCFG->CMPCR |= SYSCFG_CMPCR_CMP_PD;
- while (!(SYSCFG->CMPCR & SYSCFG_CMPCR_READY));
- /* PC.08, PC.09, PC.10, PC.11, PC.12 pin: D0, D1, D2, D3, CLK pin */
- GPIOC->MODER &= ~0x03FF0000;
- GPIOC->MODER |= 0x02AA0000; /* Pins to alternate function */
- GPIOC->OTYPER &= ~0x00001F00; /* Configure as push-pull pins */
- GPIOC->PUPDR &= ~0x03FF0000;
- GPIOC->PUPDR |= 0x01550000; /* Pull-ups on pins */
- GPIOC->OSPEEDR |= 0x03FF0000; /* Pins output speed to 100MHz */
- GPIOC->AFR[1] &= ~0x000FFFFF;
- GPIOC->AFR[1] |= 0x000CCCCC; /* Pins assigned to AF12 (SDIO) */
- /* Configure PD.02 CMD line */
- GPIOD->MODER &= ~0x0000030;
- GPIOD->MODER |= 0x0000020; /* Pins to alternate function */
- GPIOD->OTYPER &= ~0x0000004; /* Configure as push-pull pin */
- GPIOD->PUPDR &= ~0x0000030;
- GPIOD->PUPDR |= 0x0000010; /* Pull-up on pin */
- GPIOD->OSPEEDR |= 0x0000030; /* Pins output speed to 100MHz */
- GPIOD->AFR[0] &= ~0x00000F00;
- GPIOD->AFR[0] |= 0x00000C00; /* Pin assigned to AF12 (SDIO) */
- /* Configure PE.2 Card Detect input */
- SD_Link_EXTIConfig();
- /* Enable SDIO clock */
- RCC->APB2ENR |= RCC_APB2ENR_SDIOEN;
- /* Reset/Dereset SDIO */
- RCC->APB2RSTR |= RCC_APB2RSTR_SDIORST;
- RCC->APB2RSTR &= ~RCC_APB2RSTR_SDIORST;
- /* Power-on, the card is clocked */
- SDIO->POWER = SDIO_POWER_PWRCTRL_1 | SDIO_POWER_PWRCTRL_0;
- /* Enable DMA2 clock */
- RCC->AHB1ENR |= RCC_AHB1ENR_DMA2EN;
- /* Success, SDIO initialized. */
- return (__TRUE);
- }
- /*--------------------------- UnInit -----------------------------------------*/
- static BOOL UnInit (void) {
- /* Reset PC.8, PC.9, PC.10, PC.11, PC.12 pins */
- GPIOC->MODER &= ~0x03FF0000;
- /* Reset PD.2 */
- GPIOD->MODER &= ~(3 << 4);
- /* Disable SDIO module clock */
- RCC->APB2ENR &= ~RCC_APB2ENR_SDIOEN;
- return (__TRUE);
- }
- /*--------------------------- Delay ------------------------------------------*/
- static void Delay (U32 us) {
- /* Approximate delay in micro seconds. */
- U32 i;
- for (i = WAIT_CNT(__CPUCLK, us); i; i--);
- }
- /*--------------------------- BusMode ----------------------------------------*/
- static BOOL BusMode (U32 mode) {
- /* Set SDIO Bus mode to Open Drain or Push Pull. */
- switch (mode) {
- case BUS_OPEN_DRAIN:
- GPIOD->OTYPER |= 0x00000010; /* Configure as open-drain */
- return (__TRUE);
- case BUS_PUSH_PULL:
- GPIOD->OTYPER &= ~0x00000010; /* Configure as push-pull pin */
- return (__TRUE);
-
- default:
- return (__FALSE);
- }
- }
- /*--------------------------- BusWidth ---------------------------------------*/
- static BOOL BusWidth (U32 width) {
- /* Set SDIO Bus width. */
- switch (width) {
- case 1:
- SDIO->CLKCR &= ~SDIO_CLKCR_WIDBUS;
- return (__TRUE);
- case 4:
- #ifdef __XYNERGY
- return (__FALSE);
- #else
- SDIO->CLKCR |= SDIO_CLKCR_WIDBUS_0;
- return (__TRUE);
- #endif
-
- default:
- return (__FALSE);
- }
- }
- /*--------------------------- BusSpeed ---------------------------------------*/
- static BOOL BusSpeed (U32 kbaud) {
- /* Set SDIO clock speed to desired value. */
- U32 div;
- /* baud = SDIOCLK / (div + 2) */
- div = (__SDIOCLK/1000 + kbaud - 1) / kbaud;
- if (div < 2) div = 0;
- else div -= 2;
- if (div > 0xFF) div = 0xFF;
- SDIO->CLKCR = (SDIO->CLKCR & ~0xFF) | SDIO_CLKCR_PWRSAV | SDIO_CLKCR_CLKEN | div;
- return (__TRUE);
- }
- /*--------------------------- Command ----------------------------------------*/
- static BOOL Command (U8 cmd, U32 arg, U32 resp_type, U32 *rp) {
- /* Send a Command to Flash card and get a Response. */
- U32 cmdval,stat;
- cmd &= SDIO_CMD_CMDINDEX;
- cmdval = SDIO_CMD_CPSMEN | cmd;
- switch (resp_type) {
- case RESP_SHORT:
- cmdval |= SDIO_CMD_WAITRESP_0;
- break;
- case RESP_LONG:
- cmdval |= SDIO_CMD_WAITRESP_1 | SDIO_CMD_WAITRESP_0;
- break;
- }
- /* Send the command. */
- SDIO->ARG = arg;
- SDIO->CMD = cmdval;
- if (resp_type == RESP_NONE) {
- /* Wait until command finished. */
- while (SDIO->STA & SDIO_STA_CMDACT);
- stat = SDIO->STA;
- SDIO->ICR = 0x00C007FF;
- if (stat & SDIO_STA_CMDSENT) {
- return (__TRUE);
- }
- return (__FALSE);
- }
- for (;;) {
- stat = SDIO->STA;
- if (stat & SDIO_STA_CTIMEOUT) {
- SDIO->ICR = stat & SDIO_STA_CLEAR_MASK;
- return (__FALSE);
- }
- if (stat & SDIO_STA_CCRCFAIL) {
- SDIO->ICR = stat & SDIO_STA_CLEAR_MASK;
- if ((cmd == SEND_OP_COND) ||
- (cmd == SEND_APP_OP_COND) ||
- (cmd == STOP_TRANS)) {
- SDIO->CMD = 0;
- break;
- }
- return (__FALSE);
- }
- if (stat & SDIO_STA_CMDREND) {
- SDIO->ICR = stat & SDIO_STA_CLEAR_MASK;
- break;
- }
- }
- if ((SDIO->RESPCMD & 0x3F) != cmd) {
- if ((SDIO->RESPCMD & 0x3F) != 0x3F) {
- return (__FALSE);
- }
- }
- /* Read MCI response registers */
- rp[0] = SDIO->RESP1;
- if (resp_type == RESP_LONG) {
- rp[1] = SDIO->RESP2;
- rp[2] = SDIO->RESP3;
- rp[3] = SDIO->RESP4;
- }
- return (__TRUE);
- }
- /*--------------------------- ReadBlock --------------------------------------*/
- static BOOL ReadBlock (U32 bl, U8 *buf, U32 cnt) {
- /* Read one or more 512 byte blocks from Flash Card. */
- U32 i;
- SDIO->DLEN = cnt * 512;
- SDIO->DTIMER = cnt * DATA_RD_TOUT_VALUE;
- SDIO->DCTRL = SDIO_DCTRL_DBLOCKSIZE_3 | SDIO_DCTRL_DBLOCKSIZE_0 |
- SDIO_DCTRL_DMAEN | SDIO_DCTRL_DTDIR |
- SDIO_DCTRL_DTEN ;
- for (i = DMA_TOUT; i; i--) {
- if (DMA2->LISR & DMA_LISR_TEIF3) {
- break;
- }
-
- if (DMA2->LISR & DMA_LISR_TCIF3) {
- if ((SDIO->STA & (SDIO_STA_DBCKEND|SDIO_STA_DATAEND)) == (SDIO_STA_DBCKEND|SDIO_STA_DATAEND)) {
- /* Data transfer finished. */
- return (__TRUE);
- }
- }
- }
- /* DMA Transfer timeout. */
- return (__FALSE);
- }
- /*--------------------------- WriteBlock -------------------------------------*/
- static BOOL WriteBlock (U32 bl, U8 *buf, U32 cnt) {
- /* Write a cnt number of 512 byte blocks to Flash Card. */
- U32 i;
- SDIO->DLEN = cnt * 512;
- SDIO->DTIMER = cnt * DATA_WR_TOUT_VALUE;
- SDIO->DCTRL = SDIO_DCTRL_DBLOCKSIZE_3 | SDIO_DCTRL_DBLOCKSIZE_0 |
- SDIO_DCTRL_DMAEN | SDIO_DCTRL_DTEN ;
- for (i = DMA_TOUT; i; i--) {
- if (DMA2->LISR & DMA_LISR_TEIF3) {
- break;
- }
-
- if (DMA2->LISR & DMA_LISR_TCIF3) {
- if ((SDIO->STA & (SDIO_STA_DBCKEND|SDIO_STA_DATAEND)) == (SDIO_STA_DBCKEND|SDIO_STA_DATAEND)) {
- /* Data transfer finished. */
- return (__TRUE);
- }
- }
- }
- /* DMA Transfer timeout. */
- return (__FALSE);
- }
- /*--------------------------- DmaStart ---------------------------------------*/
- static BOOL SetDma (U32 mode, U8 *buf, U32 cnt) {
- /* Configure DMA Channel 4, Stream 3 for read or write */
- DMA2->LIFCR = 0x0F4 << 20; /* Clear all IRQs */
- DMA2_Stream3->CR &= ~DMA_SxCR_EN; /* Disable stream 3 */
- while (DMA2_Stream3->CR & DMA_SxCR_EN); /* Wait until stream disabled */
- DMA2_Stream3->FCR |= DMA_SxFCR_DMDIS | /* Disable direct mode */
- DMA_SxFCR_FTH ; /* FIFO threshold full */
- DMA2_Stream3->PAR = (U32)&(SDIO->FIFO);
- DMA2_Stream3->M0AR = (U32)buf;
- if (mode == DMA_READ) {
- /* Transfer from SDIO-FIFO to memory. */
- DMA2_Stream3->CR = (4 << 25) | /* Use channel 4 */
- (1 << 23) | /* Memory burst 4 beats */
- (1 << 21) | /* Peripheral burst 4 beats */
- (3 << 16) | /* Priority level high */
- (2 << 13) | /* Memory size 32-bits */
- (2 << 11) | /* Peripheral size 32-bits */
- (1 << 10) | /* Memory addr increment */
- (1 << 5) ; /* Peripheral flow control */
- }
- else {
- /* Transfer from memory to SDIO-FIFO. */
- DMA2_Stream3->CR = (4 << 25) | /* Use channel 4 */
- (1 << 23) | /* Memory burst 4 beats */
- (1 << 21) | /* Peripheral burst 4 beats */
- (3 << 16) | /* Priority level very high */
- (2 << 13) | /* Memory size 32-bits */
- (2 << 11) | /* Peripheral size 32-bits */
- (1 << 10) | /* Memory addr increment */
- (1 << 6) | /* Memory-to-peripheral */
- (1 << 5) ; /* Peripheral flow control */
- }
- /* Enable DMA channels, little endian */
- DMA2_Stream3->CR |= DMA_SxCR_EN; /* Enable stream 3 */
- return __TRUE;
- }
- /*--------------------------- CheckMedia -------------------------------------*/
- static U32 CheckMedia (void) {
- /* Read CardDetect and WriteProtect SD card socket pins. */
- U32 stat = 0;
- if (!(GPIOE->IDR & (1 << 2))) {
- /* Card is inserted (CD=0). */
- stat |= M_INSERTED;
- }
- #if 0
- if (/* Write protect switch is active */) {
- stat |= M_PROTECTED;
- }
- #endif
- return (stat);
- }
复制代码
|
|