硬汉嵌入式论坛

 找回密码
 立即注册
查看: 1867|回复: 2
收起左侧

[SD/SDIO] RL-FlashFS V6.X提供的H7版CMSIS-Driver驱动并不支持eMMC,得自己修改实现

[复制链接]

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107077
QQ
发表于 2019-12-13 10:44:26 | 显示全部楼层 |阅读模式
当前提供的这个MCI_STM32H7XXX驱动文件仅支持SD卡,实际测试并不支持eMMC。

这个自己修改还是有点难度的,而使用老版本的RL-FlashFS好修改些。

之前F4的驱动写法:
  1. #define __DRV_ID   mci0_drv
  2. #define __SDIOCLK  48000000
  3. #define __CPUCLK  168000000

  4. /* MCI Driver Interface functions */
  5. static BOOL Init (void);
  6. static BOOL UnInit (void);
  7. static void Delay (U32 us);
  8. static BOOL BusMode (U32 mode);
  9. static BOOL BusWidth (U32 width);
  10. static BOOL BusSpeed (U32 kbaud);
  11. static BOOL Command (U8 cmd, U32 arg, U32 resp_type, U32 *rp);
  12. static BOOL ReadBlock (U32 bl, U8 *buf, U32 cnt);
  13. static BOOL WriteBlock (U32 bl, U8 *buf, U32 cnt);
  14. static BOOL SetDma (U32 mode, U8 *buf, U32 cnt);
  15. static U32  CheckMedia (void);        /* Optional function for SD card check  */
  16. void SD_Link_EXTIConfig(void);

  17. /* MCI Device Driver Control Block */
  18. MCI_DRV __DRV_ID = {
  19.   Init,
  20.   UnInit,
  21.   Delay,
  22.   BusMode,
  23.   BusWidth,
  24.   BusSpeed,
  25.   Command,
  26.   ReadBlock,
  27.   WriteBlock,
  28.   SetDma,
  29.   CheckMedia                            /* Can be NULL if not existing        */
  30. };


  31. /* Wait time in for loop cycles */
  32. #define DMA_TOUT  10000000

  33. /*--------------------------- Init -------------------------------------------*/

  34. static BOOL Init (void) {
  35.   /* Initialize SDIO interface. */
  36.   /* Enable GPIOE (card detect), GPIOD (command), GPIOC (data) clock */
  37.   RCC->AHB1ENR |= RCC_AHB1ENR_GPIOEEN |
  38.                   RCC_AHB1ENR_GPIODEN |
  39.                   RCC_AHB1ENR_GPIOCEN;

  40.   RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN;
  41.   /* Enable IO compensation cell */
  42.   SYSCFG->CMPCR |= SYSCFG_CMPCR_CMP_PD;
  43.   while (!(SYSCFG->CMPCR & SYSCFG_CMPCR_READY));

  44.   /* PC.08, PC.09, PC.10, PC.11, PC.12 pin: D0, D1, D2, D3, CLK pin */
  45.   GPIOC->MODER   &= ~0x03FF0000;
  46.   GPIOC->MODER   |=  0x02AA0000;        /* Pins to alternate function         */
  47.   GPIOC->OTYPER  &= ~0x00001F00;        /* Configure as push-pull pins        */
  48.   GPIOC->PUPDR   &= ~0x03FF0000;
  49.   GPIOC->PUPDR   |=  0x01550000;        /* Pull-ups on pins                   */
  50.   GPIOC->OSPEEDR |=  0x03FF0000;        /* Pins output speed to 100MHz        */

  51.   GPIOC->AFR[1]  &= ~0x000FFFFF;
  52.   GPIOC->AFR[1]  |=  0x000CCCCC;        /* Pins assigned to AF12 (SDIO)       */

  53.   /* Configure PD.02 CMD line */
  54.   GPIOD->MODER   &= ~0x0000030;
  55.   GPIOD->MODER   |=  0x0000020;         /* Pins to alternate function         */
  56.   GPIOD->OTYPER  &= ~0x0000004;         /* Configure as push-pull pin         */
  57.   GPIOD->PUPDR   &= ~0x0000030;
  58.   GPIOD->PUPDR   |=  0x0000010;         /* Pull-up on pin                     */      
  59.   GPIOD->OSPEEDR |=  0x0000030;         /* Pins output speed to 100MHz        */

  60.   GPIOD->AFR[0]  &= ~0x00000F00;
  61.   GPIOD->AFR[0]  |=  0x00000C00;        /* Pin assigned to AF12 (SDIO)        */

  62.   /* Configure PE.2 Card Detect input */
  63.   SD_Link_EXTIConfig();

  64.   /* Enable SDIO clock */
  65.   RCC->APB2ENR  |=  RCC_APB2ENR_SDIOEN;

  66.   /* Reset/Dereset SDIO */
  67.   RCC->APB2RSTR |=  RCC_APB2RSTR_SDIORST;
  68.   RCC->APB2RSTR &= ~RCC_APB2RSTR_SDIORST;

  69.   /* Power-on, the card is clocked */
  70.   SDIO->POWER  = SDIO_POWER_PWRCTRL_1 | SDIO_POWER_PWRCTRL_0;

  71.     /* Enable DMA2 clock */
  72.   RCC->AHB1ENR |= RCC_AHB1ENR_DMA2EN;

  73.   /* Success, SDIO initialized. */
  74.   return (__TRUE);
  75. }


  76. /*--------------------------- UnInit -----------------------------------------*/

  77. static BOOL UnInit (void) {

  78.   /* Reset PC.8, PC.9, PC.10, PC.11, PC.12 pins */
  79.   GPIOC->MODER &= ~0x03FF0000;
  80.   /* Reset PD.2 */
  81.   GPIOD->MODER &= ~(3 <<  4);

  82.   /* Disable SDIO module clock */
  83.   RCC->APB2ENR &= ~RCC_APB2ENR_SDIOEN;

  84.   return (__TRUE);
  85. }


  86. /*--------------------------- Delay ------------------------------------------*/

  87. static void Delay (U32 us) {
  88.   /* Approximate delay in micro seconds. */
  89.   U32 i;

  90.   for (i = WAIT_CNT(__CPUCLK, us); i; i--);
  91. }


  92. /*--------------------------- BusMode ----------------------------------------*/

  93. static BOOL BusMode (U32 mode) {
  94.   /* Set SDIO Bus mode to Open Drain or Push Pull. */

  95.   switch (mode) {
  96.     case BUS_OPEN_DRAIN:
  97.       GPIOD->OTYPER  |=  0x00000010;    /* Configure as open-drain            */
  98.       return (__TRUE);

  99.     case BUS_PUSH_PULL:
  100.       GPIOD->OTYPER  &= ~0x00000010;    /* Configure as push-pull pin         */
  101.       return (__TRUE);
  102.    
  103.     default:
  104.       return (__FALSE);
  105.   }
  106. }


  107. /*--------------------------- BusWidth ---------------------------------------*/

  108. static BOOL BusWidth (U32 width) {
  109.   /* Set SDIO Bus width. */

  110.   switch (width) {
  111.     case 1:
  112.       SDIO->CLKCR &= ~SDIO_CLKCR_WIDBUS;
  113.       return (__TRUE);

  114.     case 4:
  115. #ifdef __XYNERGY
  116.       return (__FALSE);
  117. #else
  118.       SDIO->CLKCR |=  SDIO_CLKCR_WIDBUS_0;
  119.       return (__TRUE);
  120. #endif
  121.    
  122.     default:
  123.       return (__FALSE);
  124.   }
  125. }


  126. /*--------------------------- BusSpeed ---------------------------------------*/

  127. static BOOL BusSpeed (U32 kbaud) {
  128.   /* Set SDIO clock speed to desired value. */
  129.   U32 div;

  130.   /* baud = SDIOCLK / (div + 2) */
  131.   div = (__SDIOCLK/1000 + kbaud - 1) / kbaud;
  132.   if (div < 2)    div  = 0;
  133.   else            div -= 2;
  134.   if (div > 0xFF) div  = 0xFF;
  135.   SDIO->CLKCR = (SDIO->CLKCR & ~0xFF) | SDIO_CLKCR_PWRSAV | SDIO_CLKCR_CLKEN | div;
  136.   return (__TRUE);
  137. }


  138. /*--------------------------- Command ----------------------------------------*/

  139. static BOOL Command (U8 cmd, U32 arg, U32 resp_type, U32 *rp) {
  140.   /* Send a Command to Flash card and get a Response. */
  141.   U32 cmdval,stat;

  142.   cmd   &= SDIO_CMD_CMDINDEX;
  143.   cmdval = SDIO_CMD_CPSMEN | cmd;
  144.   switch (resp_type) {
  145.     case RESP_SHORT:
  146.       cmdval |= SDIO_CMD_WAITRESP_0;
  147.       break;
  148.     case RESP_LONG:
  149.       cmdval |= SDIO_CMD_WAITRESP_1 | SDIO_CMD_WAITRESP_0;
  150.       break;
  151.   }
  152.   /* Send the command. */
  153.   SDIO->ARG = arg;
  154.   SDIO->CMD = cmdval;

  155.   if (resp_type == RESP_NONE) {
  156.     /* Wait until command finished. */
  157.     while (SDIO->STA & SDIO_STA_CMDACT);
  158.     stat = SDIO->STA;
  159.     SDIO->ICR = 0x00C007FF;
  160.     if (stat & SDIO_STA_CMDSENT) {
  161.       return (__TRUE);
  162.     }
  163.     return (__FALSE);   
  164.   }

  165.   for (;;) {
  166.     stat = SDIO->STA;
  167.     if (stat & SDIO_STA_CTIMEOUT) {
  168.       SDIO->ICR = stat & SDIO_STA_CLEAR_MASK;
  169.       return (__FALSE);
  170.     }
  171.     if (stat & SDIO_STA_CCRCFAIL) {
  172.       SDIO->ICR = stat & SDIO_STA_CLEAR_MASK;
  173.       if ((cmd == SEND_OP_COND)      ||
  174.           (cmd == SEND_APP_OP_COND)  ||
  175.           (cmd == STOP_TRANS)) {
  176.         SDIO->CMD = 0;
  177.         break;
  178.       }
  179.       return (__FALSE);
  180.     }
  181.     if (stat & SDIO_STA_CMDREND) {
  182.       SDIO->ICR = stat & SDIO_STA_CLEAR_MASK;
  183.       break;
  184.     }
  185.   }
  186.   if ((SDIO->RESPCMD & 0x3F) != cmd) {
  187.     if ((SDIO->RESPCMD & 0x3F) != 0x3F) {
  188.       return (__FALSE);
  189.     }
  190.   }
  191.   /* Read MCI response registers */
  192.   rp[0] = SDIO->RESP1;
  193.   if (resp_type == RESP_LONG) {
  194.     rp[1] = SDIO->RESP2;
  195.     rp[2] = SDIO->RESP3;
  196.     rp[3] = SDIO->RESP4;
  197.   }
  198.   return (__TRUE);
  199. }


  200. /*--------------------------- ReadBlock --------------------------------------*/

  201. static BOOL ReadBlock (U32 bl, U8 *buf, U32 cnt) {
  202.   /* Read one or more 512 byte blocks from Flash Card. */
  203.   U32 i;

  204.   SDIO->DLEN    = cnt * 512;
  205.   SDIO->DTIMER  = cnt * DATA_RD_TOUT_VALUE;

  206.   SDIO->DCTRL   = SDIO_DCTRL_DBLOCKSIZE_3 | SDIO_DCTRL_DBLOCKSIZE_0 |
  207.                   SDIO_DCTRL_DMAEN        | SDIO_DCTRL_DTDIR        |
  208.                   SDIO_DCTRL_DTEN         ;

  209.   for (i = DMA_TOUT; i; i--) {   
  210.     if (DMA2->LISR & DMA_LISR_TEIF3) {
  211.       break;
  212.     }
  213.    
  214.     if (DMA2->LISR & DMA_LISR_TCIF3) {
  215.       if ((SDIO->STA & (SDIO_STA_DBCKEND|SDIO_STA_DATAEND)) == (SDIO_STA_DBCKEND|SDIO_STA_DATAEND)) {
  216.         /* Data transfer finished. */
  217.         return (__TRUE);
  218.       }
  219.     }
  220.   }
  221.   /* DMA Transfer timeout. */
  222.   return (__FALSE);
  223. }


  224. /*--------------------------- WriteBlock -------------------------------------*/

  225. static BOOL WriteBlock (U32 bl, U8 *buf, U32 cnt) {
  226.   /* Write a cnt number of 512 byte blocks to Flash Card. */
  227.   U32 i;

  228.   SDIO->DLEN    = cnt * 512;
  229.   SDIO->DTIMER  = cnt * DATA_WR_TOUT_VALUE;
  230.   SDIO->DCTRL   = SDIO_DCTRL_DBLOCKSIZE_3 | SDIO_DCTRL_DBLOCKSIZE_0 |
  231.                   SDIO_DCTRL_DMAEN        | SDIO_DCTRL_DTEN         ;

  232.   for (i = DMA_TOUT; i; i--) {
  233.     if (DMA2->LISR & DMA_LISR_TEIF3) {
  234.       break;
  235.     }
  236.    
  237.     if (DMA2->LISR & DMA_LISR_TCIF3) {
  238.       if ((SDIO->STA & (SDIO_STA_DBCKEND|SDIO_STA_DATAEND)) == (SDIO_STA_DBCKEND|SDIO_STA_DATAEND)) {
  239.         /* Data transfer finished. */
  240.         return (__TRUE);
  241.       }
  242.     }
  243.   }
  244.   /* DMA Transfer timeout. */
  245.   return (__FALSE);
  246. }


  247. /*--------------------------- DmaStart ---------------------------------------*/

  248. static BOOL SetDma (U32 mode, U8 *buf, U32 cnt) {
  249.   /* Configure DMA Channel 4, Stream 3 for read or write */

  250.   DMA2->LIFCR = 0x0F4 << 20;                   /* Clear all IRQs              */

  251.   DMA2_Stream3->CR  &= ~DMA_SxCR_EN;           /* Disable stream 3            */
  252.   while (DMA2_Stream3->CR & DMA_SxCR_EN);      /* Wait until stream disabled  */

  253.   DMA2_Stream3->FCR |=  DMA_SxFCR_DMDIS |      /* Disable direct mode         */
  254.                         DMA_SxFCR_FTH   ;      /* FIFO threshold full         */

  255.   DMA2_Stream3->PAR  = (U32)&(SDIO->FIFO);
  256.   DMA2_Stream3->M0AR = (U32)buf;

  257.   if (mode == DMA_READ) {
  258.     /* Transfer from SDIO-FIFO to memory. */
  259.     DMA2_Stream3->CR = (4 << 25) |             /* Use channel 4               */
  260.                        (1 << 23) |             /* Memory burst 4 beats        */
  261.                        (1 << 21) |             /* Peripheral burst 4 beats    */
  262.                        (3 << 16) |             /* Priority level high         */
  263.                        (2 << 13) |             /* Memory size 32-bits         */
  264.                        (2 << 11) |             /* Peripheral size 32-bits     */
  265.                        (1 << 10) |             /* Memory addr increment       */
  266.                        (1 <<  5) ;             /* Peripheral flow control     */
  267.   }
  268.   else {
  269.     /* Transfer from memory to SDIO-FIFO. */
  270.     DMA2_Stream3->CR = (4 << 25) |             /* Use channel 4               */
  271.                        (1 << 23) |             /* Memory burst 4 beats        */
  272.                        (1 << 21) |             /* Peripheral burst 4 beats    */
  273.                        (3 << 16) |             /* Priority level very high    */
  274.                        (2 << 13) |             /* Memory size 32-bits         */
  275.                        (2 << 11) |             /* Peripheral size 32-bits     */
  276.                        (1 << 10) |             /* Memory addr increment       */
  277.                        (1 <<  6) |             /* Memory-to-peripheral        */
  278.                        (1 <<  5) ;             /* Peripheral flow control     */
  279.   }

  280.   /* Enable DMA channels, little endian */
  281.   DMA2_Stream3->CR  |= DMA_SxCR_EN;            /* Enable stream 3             */
  282.   return __TRUE;
  283. }


  284. /*--------------------------- CheckMedia -------------------------------------*/

  285. static U32 CheckMedia (void) {
  286.   /* Read CardDetect and WriteProtect SD card socket pins. */
  287.   U32 stat = 0;

  288.   if (!(GPIOE->IDR & (1 << 2))) {
  289.     /* Card is inserted (CD=0). */
  290.     stat |= M_INSERTED;
  291.   }

  292. #if 0
  293.   if (/* Write protect switch is active */) {
  294.     stat |= M_PROTECTED;
  295.   }
  296. #endif

  297.   return (stat);
  298. }
复制代码



回复

使用道具 举报

2

主题

23

回帖

29

积分

新手上路

积分
29
发表于 2019-12-24 14:26:43 | 显示全部楼层
后续不知道会不会支持这个emmc
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107077
QQ
 楼主| 发表于 2019-12-24 14:45:06 | 显示全部楼层
chengying 发表于 2019-12-24 14:26
后续不知道会不会支持这个emmc

我已经改用fatfs做eMMC的fat了。

CMSIS-Driver当前提供的这个驱动接口,不太好修改,改了一次没成功。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-5-17 01:50 , Processed in 0.148536 second(s), 25 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表