首页 > 评测 > [STM32H7] [STM32H7] STM32H750B-DK TouchGFX 测评视频播放

[STM32H7] [STM32H7] STM32H750B-DK TouchGFX 测评视频播放

  
  • 作者:
  • 来源:
  • [导读]
  • 本帖最后由 ROSHEN_007 于 2023-3-6 13:20 编辑 #申请原创# 一、搭建存储系统 视频播放一般需要SD卡进行视屏文件存储,但是开发板上没有SD卡,查看了板子的硬件资源,发现板子上有两块EMMC,所以想着用EM

本帖最后由 ROSHEN_007 于 2023-3-6 13:20 编辑

#申请原创#

一、搭建存储系统
视频播放一般需要SD卡进行视屏文件存储,但是开发板上没有SD卡,查看了板子的硬件资源,发现板子上有两块EMMC,所以想着用EMMC来作为存储设备,搭建USB+EMMC+FATFS存储读写系统;
1、USB驱动配置
直接使用CUBEMX进行配置,比较方便,需要注意的是,配置时钟的时候,千万别选自动生成USB时钟,自动生成会造成"系统紊乱",因为USB默认时钟是从PLL1上取得,要配置成48MHZ,会改PLL1的输出时钟,很多外设都用PLL1生成时钟,这里直接手动选择RC48即可;




2、EMMC驱动配置
查看STM32H750的手册,发现支持8bit DDR模式,但是实际调试的时候发现速率根本达不到200Mhz,这里简直是深坑,调试出错的时候我以为是EMMC不支持,后来查看EMMC的手册,是可以支持200M ddr模式的,应该还是ST的问题,IO翻转速度达不到200MHZ,时钟改成四分频到50MHZ就可以跑起来了;支持 1线、4线、8线MMC模式,根据需要选择即可,另外打开中断配置;





3、USB  MSC驱动代码修改调试
改过SD开驱动的应该都比较熟悉,这里我们直接找到usbd_storage_if.c文件,改写下图中的这些函数,代码下面也贴出,改写的时候主要的是要把自己添加的代码写到“恰当的位置”,不然如果你修改CUBMUX的配置,你辛辛苦苦添加的代码就会消失不见了,我也是刚开始使用cubide,在这上面吃了点小亏;

  1. /* USER CODE BEGIN Header */
  2. /**
  3.   ******************************************************************************
  4.   * [url=home.php?mod=space&uid=288409]@file[/url]           : usbd_storage_if.c
  5.   * [url=home.php?mod=space&uid=895143]@version[/url]        : v1.0_Cube
  6.   * [url=home.php?mod=space&uid=247401]@brief[/url]          : Memory management layer.
  7.   ******************************************************************************
  8.   * @attention
  9.   *
  10.   * Copyright (c) 2023 STMicroelectronics.
  11.   * All rights reserved.
  12.   *
  13.   * This software is licensed under terms that can be found in the LICENSE file
  14.   * in the root directory of this software component.
  15.   * If no LICENSE file comes with this software, it is provided AS-IS.
  16.   *
  17.   ******************************************************************************
  18.   */
  19. /* USER CODE END Header */
  20.  
  21. /* Includes ------------------------------------------------------------------*/
  22. #include "usbd_storage_if.h"
  23. /* USER CODE BEGIN INCLUDE */
  24. #include "FreeRTOS.h"
  25. #include "semphr.h"
  26. /* USER CODE END INCLUDE */
  27.  
  28. /* Private typedef -----------------------------------------------------------*/
  29. /* Private define ------------------------------------------------------------*/
  30. /* Private macro -------------------------------------------------------------*/
  31.  
  32. /* USER CODE BEGIN PV */
  33. /* Private variables ---------------------------------------------------------*/
  34.  
  35. /* USER CODE END PV */
  36.  
  37. /** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
  38.   * [url=home.php?mod=space&uid=247401]@brief[/url] Usb device.
  39.   * @{
  40.   */
  41.  
  42. /** @defgroup USBD_STORAGE
  43.   * [url=home.php?mod=space&uid=247401]@brief[/url] Usb mass storage device module
  44.   * @{
  45.   */
  46.  
  47. /** @defgroup USBD_STORAGE_Private_TypesDefinitions
  48.   * [url=home.php?mod=space&uid=247401]@brief[/url] Private types.
  49.   * @{
  50.   */
  51.  
  52. /* USER CODE BEGIN PRIVATE_TYPES */
  53. /* USER CODE END PRIVATE_TYPES */
  54.  
  55. /**
  56.   * @}
  57.   */
  58.  
  59. /** @defgroup USBD_STORAGE_Private_Defines
  60.   * [url=home.php?mod=space&uid=247401]@brief[/url] Private defines.
  61.   * @{
  62.   */
  63.  
  64. #define STORAGE_LUN_NBR                  1
  65. #define STORAGE_BLK_NBR                  0x10000
  66. #define STORAGE_BLK_SIZ                  0x200
  67.  
  68. /* USER CODE BEGIN PRIVATE_DEFINES */
  69. //#define EMMC_USE_DMA
  70. /* USER CODE END PRIVATE_DEFINES */
  71.  
  72. /**
  73.   * @}
  74.   */
  75.  
  76. /** @defgroup USBD_STORAGE_Private_Macros
  77.   * [url=home.php?mod=space&uid=247401]@brief[/url] Private macros.
  78.   * @{
  79.   */
  80.  
  81. /* USER CODE BEGIN PRIVATE_MACRO */
  82.  
  83. /* USER CODE END PRIVATE_MACRO */
  84.  
  85. /**
  86.   * @}
  87.   */
  88.  
  89. /** @defgroup USBD_STORAGE_Private_Variables
  90.   * [url=home.php?mod=space&uid=247401]@brief[/url] Private variables.
  91.   * @{
  92.   */
  93.  
  94. /* USER CODE BEGIN INQUIRY_DATA_FS */
  95. /** USB Mass storage Standard Inquiry Data. */
  96. const int8_t STORAGE_Inquirydata_FS[] = {/* 36 */
  97.  
  98.   /* LUN 0 */
  99.   0x00,
  100.   0x80,
  101.   0x02,
  102.   0x02,
  103.   (STANDARD_INQUIRY_DATA_LEN - 5),
  104.   0x00,
  105.   0x00,
  106.   0x00,
  107.   'S', 'T', 'M', ' ', ' ', ' ', ' ', ' ', /* Manufacturer : 8 bytes */
  108.   'P', 'r', 'o', 'd', 'u', 'c', 't', ' ', /* Product      : 16 Bytes */
  109.   ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
  110.   '0', '.', '0' ,'1'                      /* Version      : 4 Bytes */
  111. };
  112. /* USER CODE END INQUIRY_DATA_FS */
  113.  
  114. /* USER CODE BEGIN PRIVATE_VARIABLES */
  115.  
  116. /* USER CODE END PRIVATE_VARIABLES */
  117.  
  118. /**
  119.   * @}
  120.   */
  121.  
  122. /** @defgroup USBD_STORAGE_Exported_Variables
  123.   * @brief Public variables.
  124.   * @{
  125.   */
  126.  
  127. extern USBD_HandleTypeDef hUsbDeviceFS;
  128.  
  129. /* USER CODE BEGIN EXPORTED_VARIABLES */
  130. volatile  uint8_t  write_flag = 0, read_flag = 0;
  131. extern MMC_HandleTypeDef hmmc1;
  132. extern SemaphoreHandle_t xSemaphoreEmmc;
  133. /* USER CODE END EXPORTED_VARIABLES */
  134.  
  135. /**
  136.   * @}
  137.   */
  138.  
  139. /** @defgroup USBD_STORAGE_Private_FunctionPrototypes
  140.   * @brief Private functions declaration.
  141.   * @{
  142.   */
  143.  
  144. static int8_t STORAGE_Init_FS(uint8_t lun);
  145. static int8_t STORAGE_GetCapacity_FS(uint8_t lun, uint32_t *block_num, uint16_t *block_size);
  146. static int8_t STORAGE_IsReady_FS(uint8_t lun);
  147. static int8_t STORAGE_IsWriteProtected_FS(uint8_t lun);
  148. static int8_t STORAGE_Read_FS(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len);
  149. static int8_t STORAGE_Write_FS(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len);
  150. static int8_t STORAGE_GetMaxLun_FS(void);
  151.  
  152. /* USER CODE BEGIN PRIVATE_FUNCTIONS_DECLARATION */
  153. void HAL_MMC_TxCpltCallback(MMC_HandleTypeDef *hmmc)
  154. {
  155.         write_flag = 1;
  156. }
  157. void HAL_MMC_RxCpltCallback(MMC_HandleTypeDef *hmmc)
  158. {
  159.         read_flag = 1;
  160. }
  161. /* USER CODE END PRIVATE_FUNCTIONS_DECLARATION */
  162.  
  163. /**
  164.   * @}
  165.   */
  166.  
  167. USBD_StorageTypeDef USBD_Storage_Interface_fops_FS =
  168. {
  169.   STORAGE_Init_FS,
  170.   STORAGE_GetCapacity_FS,
  171.   STORAGE_IsReady_FS,
  172.   STORAGE_IsWriteProtected_FS,
  173.   STORAGE_Read_FS,
  174.   STORAGE_Write_FS,
  175.   STORAGE_GetMaxLun_FS,
  176.   (int8_t *)STORAGE_Inquirydata_FS
  177. };
  178.  
  179. /* Private functions ---------------------------------------------------------*/
  180. /**
  181.   * @brief  Initializes the storage unit (medium) over USB FS IP
  182.   * @param  lun: Logical unit number.
  183.   * @retval USBD_OK if all operations are OK else USBD_FAIL
  184.   */
  185. int8_t STORAGE_Init_FS(uint8_t lun)
  186. {
  187.   /* USER CODE BEGIN 2 */
  188. UNUSED(lun);
  189. // hmmc1.Instance = SDMMC1;
  190. // hmmc1.Init.ClockEdge = SDMMC_CLOCK_EDGE_RISING;
  191. // hmmc1.Init.ClockPowerSave = SDMMC_CLOCK_POWER_SAVE_DISABLE;
  192. // hmmc1.Init.BusWide = SDMMC_BUS_WIDE_8B;
  193. // hmmc1.Init.HardwareFlowControl = SDMMC_HARDWARE_FLOW_CONTROL_DISABLE;
  194. // hmmc1.Init.ClockDiv = 0;
  195. // if (HAL_MMC_Init(&hmmc1) != HAL_OK)
  196. // {
  197. //   return USBD_FAIL;
  198. // }
  199. // HAL_MMC_CardStateTypeDef State;
  200. // HAL_MMC_CardCIDTypeDef EMMC_CardCID;
  201. // State = HAL_MMC_GetCardState(&hmmc1);
  202. // if(State == HAL_MMC_CARD_TRANSFER)
  203. // {
  204. //        HAL_MMC_GetCardCID(&hmmc1,&EMMC_CardCID);
  205. // }
  206. // if(HAL_MMC_Erase(&hmmc1,0,hmmc1.MmcCard.BlockNbr) == HAL_OK)
  207. // {
  208. //         while(HAL_MMC_GetCardState(&hmmc1)!=HAL_MMC_CARD_TRANSFER);
  209. // }
  210. return (USBD_OK);
  211.   /* USER CODE END 2 */
  212. }
  213.  
  214. /**
  215.   * @brief  Returns the medium capacity.
  216.   * @param  lun: Logical unit number.
  217.   * @param  block_num: Number of total block number.
  218.   * @param  block_size: Block size.
  219.   * @retval USBD_OK if all operations are OK else USBD_FAIL
  220.   */
  221. int8_t STORAGE_GetCapacity_FS(uint8_t lun, uint32_t *block_num, uint16_t *block_size)
  222. {
  223.   /* USER CODE BEGIN 3 */
  224.   HAL_MMC_CardStateTypeDef State;
  225.   HAL_MMC_CardCIDTypeDef EMMC_CardCID;
  226.   State = HAL_MMC_GetCardState(&hmmc1);
  227.   if(State == HAL_MMC_CARD_TRANSFER)
  228.   {
  229.         HAL_MMC_GetCardCID(&hmmc1,&EMMC_CardCID);
  230.         *block_num  = hmmc1.MmcCard.BlockNbr;
  231.         *block_size = hmmc1.MmcCard.BlockSize;
  232.         return (USBD_OK);
  233.   }
  234.   else
  235.         return USBD_FAIL ;
  236.   /* USER CODE END 3 */
  237. }
  238.  
  239. /**
  240.   * @brief   Checks whether the medium is ready.
  241.   * @param  lun:  Logical unit number.
  242.   * @retval USBD_OK if all operations are OK else USBD_FAIL
  243.   */
  244. int8_t STORAGE_IsReady_FS(uint8_t lun)
  245. {
  246.   /* USER CODE BEGIN 4 */
  247.   uint8_t state = 0;
  248.   state = HAL_MMC_GetState(&hmmc1);
  249.   if(HAL_MMC_STATE_READY != state)
  250.   {
  251.           return USBD_FAIL ;
  252.   }
  253.   return (USBD_OK);
  254.   /* USER CODE END 4 */
  255. }
  256.  
  257. /**
  258.   * @brief  Checks whether the medium is write protected.
  259.   * @param  lun: Logical unit number.
  260.   * @retval USBD_OK if all operations are OK else USBD_FAIL
  261.   */
  262. int8_t STORAGE_IsWriteProtected_FS(uint8_t lun)
  263. {
  264.   /* USER CODE BEGIN 5 */
  265.   UNUSED(lun);
  266.  
  267.   return (USBD_OK);
  268.   /* USER CODE END 5 */
  269. }
  270.  
  271. /**
  272.   * @brief  Reads data from the medium.
  273.   * @param  lun: Logical unit number.
  274.   * @param  buf: data buffer.
  275.   * @param  blk_addr: Logical block address.
  276.   * @param  blk_len: Blocks number.
  277.   * @retval USBD_OK if all operations are OK else USBD_FAIL
  278.   */
  279. int8_t STORAGE_Read_FS(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len)
  280. {
  281.   /* USER CODE BEGIN 6 */
  282.   int8_t ret = USBD_FAIL;
  283.   BaseType_t semRet = pdFAIL;
  284.   if(xSemaphoreEmmc!=NULL){
  285.           semRet = xSemaphoreTakeFromISR(xSemaphoreEmmc,0);
  286.   }
  287.   if(semRet==pdPASS){
  288.         #ifdef EMMC_USE_DMA
  289.           if(HAL_OK == HAL_MMC_ReadBlocks_DMA(&hmmc1,(uint8_t *)buf, blk_addr , blk_len))
  290.           {
  291.                  while(HAL_MMC_GetCardState(&hmmc1)!=HAL_MMC_CARD_TRANSFER);
  292.                  ret = USBD_OK;
  293.           }
  294.         #else
  295.           if(HAL_OK == HAL_MMC_ReadBlocks(&hmmc1,(uint8_t *)buf, blk_addr , blk_len,0XFF))
  296.           {
  297.                  while(HAL_MMC_GetCardState(&hmmc1)!=HAL_MMC_CARD_TRANSFER);
  298.                  ret = USBD_OK;
  299.           }
  300.         #endif
  301.           xSemaphoreGiveFromISR(xSemaphoreEmmc,pdFALSE);
  302.   }
  303.   return ret;
  304.   /* USER CODE END 6 */
  305. }
  306.  
  307. /**
  308.   * @brief  Writes data into the medium.
  309.   * @param  lun: Logical unit number.
  310.   * @param  buf: data buffer.
  311.   * @param  blk_addr: Logical block address.
  312.   * @param  blk_len: Blocks number.
  313.   * @retval USBD_OK if all operations are OK else USBD_FAIL
  314.   */
  315. int8_t STORAGE_Write_FS(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len)
  316. {
  317.   /* USER CODE BEGIN 7 */
  318.   int8_t ret = USBD_FAIL;
  319.   BaseType_t semRet = pdFAIL;
  320.   if(xSemaphoreEmmc!=NULL){
  321.           semRet = xSemaphoreTakeFromISR(xSemaphoreEmmc,0);
  322.   }
  323.   if(semRet==pdPASS){
  324.         #ifdef EMMC_USE_DMA
  325.           if(HAL_OK == HAL_MMC_WriteBlocks_DMA(&hmmc1, (uint8_t *)buf, blk_addr , blk_len))
  326.           {
  327.                  while(HAL_MMC_GetCardState(&hmmc1)!=HAL_MMC_CARD_TRANSFER);
  328.                  ret = USBD_OK;
  329.           }
  330.         #else
  331.           if(HAL_OK == HAL_MMC_WriteBlocks(&hmmc1, (uint8_t *)buf, blk_addr , blk_len,0XFF))
  332.           {
  333.                  while(HAL_MMC_GetCardState(&hmmc1)!=HAL_MMC_CARD_TRANSFER);
  334.                  ret = USBD_OK;
  335.           }
  336.         #endif
  337.           xSemaphoreGiveFromISR(xSemaphoreEmmc,pdFALSE);
  338.   }
  339.   return ret;
  340.   /* USER CODE END 7 */
  341. }
  342.  
  343. /**
  344.   * @brief  Returns the Max Supported LUNs.
  345.   * @param  None
  346.   * @retval Lun(s) number.
  347.   */
  348. int8_t STORAGE_GetMaxLun_FS(void)
  349. {
  350.   /* USER CODE BEGIN 8 */
  351.   return (STORAGE_LUN_NBR - 1);
  352.   /* USER CODE END 8 */
  353. }
  354.  
  355. /* USER CODE BEGIN PRIVATE_FUNCTIONS_IMPLEMENTATION */
  356.  
  357. /* USER CODE END PRIVATE_FUNCTIONS_IMPLEMENTATION */
  358.  
  359. /**
  360.   * @}
  361.   */
  362.  
  363. /**
  364.   * @}
  365.   */
  366.  
  367.  
复制代码

到这里USB MSC的驱动就改完了,插上USB看看,能不能驱动;



在电脑端显示为G盘,首先进行格式化,格式化后看到大小为4GB,与板子上EMMC容量大小一致,然后测试读写是否正常,直接在G盘中新建txt,输入内容保存再打开,显示没问题,说明读写正常;
4、添加文件系统
能把视屏文件存入EMMC了,现在还差文件系统读取视屏文件内容,添加FATFS文件系统,模式选择User-defined,将Code_page改成DBCS;

4、修改文件系统驱动代码这里面需要注意的是任务同步,因为USB驱动里面用EMMC的读写,fatfa也要用EMMC的读写,所以要做任务同步,这里千万不能用互斥体,因为FREERTOS的互斥体
是会自动调节任务优先级的,设计初衷是为了防止低优先级的任务占用锁但是得不到执行,高优先级的任务等锁产生死锁,而且互斥体不能用在中断中;而USB MSC驱动其实是中断执行的,所以要用信号量来完成;代码改写主要就是下面这几个函数

修改的相关代码都贴出来

  1. /**
  2.   * @brief SDMMC1 Initialization Function
  3.   * @param None
  4.   * @retval None
  5.   */
  6. static void MX_SDMMC1_MMC_Init(void)
  7. {
  8.  
  9.   /* USER CODE BEGIN SDMMC1_Init 0 */
  10.  
  11.   /* USER CODE END SDMMC1_Init 0 */
  12.  
  13.   /* USER CODE BEGIN SDMMC1_Init 1 */
  14.  
  15.   /* USER CODE END SDMMC1_Init 1 */
  16.   hmmc1.Instance = SDMMC1;
  17.   hmmc1.Init.ClockEdge = SDMMC_CLOCK_EDGE_RISING;
  18.   hmmc1.Init.ClockPowerSave = SDMMC_CLOCK_POWER_SAVE_DISABLE;
  19.   hmmc1.Init.BusWide = SDMMC_BUS_WIDE_1B;
  20.   hmmc1.Init.HardwareFlowControl = SDMMC_HARDWARE_FLOW_CONTROL_DISABLE;
  21.   hmmc1.Init.ClockDiv = 4;
  22.   if (HAL_MMC_Init(&hmmc1) != HAL_OK)
  23.   {
  24.     Error_Handler();
  25.   }
  26.   /* USER CODE BEGIN SDMMC1_Init 2 */
  27.   xSemaphoreEmmc = xSemaphoreCreateBinary();
  28.   if(xSemaphoreEmmc==NULL){
  29.         Error_Handler();
  30.   }else{
  31.         xSemaphoreGive(xSemaphoreEmmc);
  32.   }
  33.  
  34.   /* USER CODE END SDMMC1_Init 2 */
  35.  
  36. }
  37.  
复制代码
  1. /* USER CODE BEGIN Header */
  2. /**
  3. ******************************************************************************
  4.   * [url=home.php?mod=space&uid=288409]@file[/url]    user_diskio.c
  5.   * @brief   This file includes a diskio driver skeleton to be completed by the user.
  6.   ******************************************************************************
  7.   * @attention
  8.   *
  9.   * Copyright (c) 2023 STMicroelectronics.
  10.   * All rights reserved.
  11.   *
  12.   * This software is licensed under terms that can be found in the LICENSE file
  13.   * in the root directory of this software component.
  14.   * If no LICENSE file comes with this software, it is provided AS-IS.
  15.   *
  16.   ******************************************************************************
  17.   */
  18. /* USER CODE END Header */
  19.  
  20. #ifdef USE_OBSOLETE_USER_CODE_SECTION_0
  21. /*
  22. * Warning: the user section 0 is no more in use (starting from CubeMx version 4.16.0)
  23. * To be suppressed in the future.
  24. * Kept to ensure backward compatibility with previous CubeMx versions when
  25. * migrating projects.
  26. * User code previously added there should be copied in the new user sections before
  27. * the section contents can be deleted.
  28. */
  29. /* USER CODE BEGIN 0 */
  30. /* USER CODE END 0 */
  31. #endif
  32.  
  33. /* USER CODE BEGIN DECL */
  34.  
  35. /* Includes ------------------------------------------------------------------*/
  36. #include <string.h>
  37. #include "ff_gen_drv.h"
  38. #include "stm32h7xx_hal.h"
  39. #include "semphr.h"
  40. /* Private typedef -----------------------------------------------------------*/
  41. /* Private define ------------------------------------------------------------*/
  42. #define EMMC_TIMEOUT 1000
  43. /* Private variables ---------------------------------------------------------*/
  44. extern SemaphoreHandle_t xSemaphoreEmmc;
  45. extern MMC_HandleTypeDef hmmc1;
  46. extern uint8_t  write_flag, read_flag;
  47. /* Disk status */
  48. static volatile DSTATUS Stat = STA_NOINIT;
  49. /* USER CODE END DECL */
  50.  
  51. /* Private function prototypes -----------------------------------------------*/
  52. DSTATUS USER_initialize (BYTE pdrv);
  53. DSTATUS USER_status (BYTE pdrv);
  54. DRESULT USER_read (BYTE pdrv, BYTE *buff, DWORD sector, UINT count);
  55. #if _USE_WRITE == 1
  56.   DRESULT USER_write (BYTE pdrv, const BYTE *buff, DWORD sector, UINT count);
  57. #endif /* _USE_WRITE == 1 */
  58. #if _USE_IOCTL == 1
  59.   DRESULT USER_ioctl (BYTE pdrv, BYTE cmd, void *buff);
  60. #endif /* _USE_IOCTL == 1 */
  61.  
  62. Diskio_drvTypeDef  USER_Driver =
  63. {
  64.   USER_initialize,
  65.   USER_status,
  66.   USER_read,
  67. #if  _USE_WRITE
  68.   USER_write,
  69. #endif  /* _USE_WRITE == 1 */
  70. #if  _USE_IOCTL == 1
  71.   USER_ioctl,
  72. #endif /* _USE_IOCTL == 1 */
  73. };
  74.  
  75. /* Private functions ---------------------------------------------------------*/
  76.  
  77. /**
  78.   * @brief  Initializes a Drive
  79.   * @param  pdrv: Physical drive number (0..)
  80.   * @retval DSTATUS: Operation status
  81.   */
  82. DSTATUS USER_initialize (
  83.         BYTE pdrv           /* Physical drive nmuber to identify the drive */
  84. )
  85. {
  86.   /* USER CODE BEGIN INIT */
  87.     Stat = STA_NOINIT;
  88.     if (HAL_MMC_Init(&hmmc1) == HAL_OK){
  89.             Stat &= ~STA_NOINIT;
  90.     }
  91.     return Stat;
  92.   /* USER CODE END INIT */
  93. }
  94.  
  95. /**
  96.   * @brief  Gets Disk Status
  97.   * @param  pdrv: Physical drive number (0..)
  98.   * @retval DSTATUS: Operation status
  99.   */
  100. DSTATUS USER_status (
  101.         BYTE pdrv       /* Physical drive number to identify the drive */
  102. )
  103. {
  104.   /* USER CODE BEGIN STATUS */
  105.     Stat = STA_NOINIT;
  106.     if(HAL_MMC_GetCardState(&hmmc1) == HAL_MMC_CARD_TRANSFER )
  107.     {
  108.       Stat &= ~STA_NOINIT;
  109.     }
  110.     return Stat;
  111.   /* USER CODE END STATUS */
  112. }
  113.  
  114. /**
  115.   * @brief  Reads Sector(s)
  116.   * @param  pdrv: Physical drive number (0..)
  117.   * @param  *buff: Data buffer to store read data
  118.   * @param  sector: Sector address (LBA)
  119.   * @param  count: Number of sectors to read (1..128)
  120.   * @retval DRESULT: Operation result
  121.   */
  122. DRESULT USER_read (
  123.         BYTE pdrv,      /* Physical drive nmuber to identify the drive */
  124.         BYTE *buff,     /* Data buffer to store read data */
  125.         DWORD sector,   /* Sector address in LBA */
  126.         UINT count      /* Number of sectors to read */
  127. )
  128. {
  129.   /* USER CODE BEGIN READ */
  130.    DRESULT ret = RES_ERROR;
  131.    BaseType_t semRet = pdFAIL;
  132.    if(xSemaphoreEmmc!=NULL){
  133.            semRet = xSemaphoreTake(xSemaphoreEmmc,portMAX_DELAY);
  134.    }
  135.    if(semRet==pdPASS){
  136.    #ifdef EMMC_USE_DMA
  137.            uint32_t timeout;
  138.            uint32_t alignedAddr;
  139.            alignedAddr = (uint32_t)buff & ~0x1F;
  140.            SCB_CleanDCache_by_Addr((uint32_t*)alignedAddr, count*MMC_BLOCKSIZE + ((uint32_t)buff - alignedAddr));
  141.            if(HAL_MMC_ReadBlocks_DMA(&hmmc1, (uint8_t*)buff,
  142.                                                                 (uint32_t) (sector),
  143.                                                                  count) == HAL_OK)
  144.            {
  145.  
  146.                   /* Wait that the reading process is completed or a timeout occurs */
  147.                   timeout = HAL_GetTick();
  148.                   while((read_flag == 0) && ((HAL_GetTick() - timeout) < EMMC_TIMEOUT));
  149.                   /* incase of a timeout return error */
  150.                   if (read_flag == 0)
  151.                   {
  152.                         ret = RES_ERROR;
  153.                   }
  154.                   else
  155.                   {
  156.                         read_flag = 0;
  157.                         timeout = HAL_GetTick();
  158.                         while((HAL_GetTick() - timeout) < EMMC_TIMEOUT)
  159.                         {
  160.                           if (HAL_MMC_GetCardState(&hmmc1) == HAL_MMC_CARD_TRANSFER)
  161.                           {
  162.                                 ret = RES_OK;
  163.                                 SCB_InvalidateDCache_by_Addr((uint32_t*)alignedAddr, count*MMC_BLOCKSIZE + ((uint32_t)buff - alignedAddr));
  164.                                 break;
  165.                           }
  166.                         }
  167.                   }
  168.                 }
  169.         #else
  170.                 if(HAL_MMC_ReadBlocks(&hmmc1, (uint8_t*)buff,
  171.                                                                  (uint32_t) (sector),
  172.                                                                   count,EMMC_TIMEOUT) == HAL_OK)
  173.                 {
  174.                         while(HAL_MMC_GetCardState(&hmmc1)!=HAL_MMC_CARD_TRANSFER);
  175.                         ret = RES_OK;
  176.                 }
  177.         #endif
  178.                 xSemaphoreGive(xSemaphoreEmmc);
  179.    }
  180.    return ret;
  181.   /* USER CODE END READ */
  182. }
  183.  
  184. /**
  185.   * @brief  Writes Sector(s)
  186.   * @param  pdrv: Physical drive number (0..)
  187.   * @param  *buff: Data to be written
  188.   * @param  sector: Sector address (LBA)
  189.   * @param  count: Number of sectors to write (1..128)
  190.   * @retval DRESULT: Operation result
  191.   */
  192. #if _USE_WRITE == 1
  193. DRESULT USER_write (
  194.         BYTE pdrv,          /* Physical drive nmuber to identify the drive */
  195.         const BYTE *buff,   /* Data to be written */
  196.         DWORD sector,       /* Sector address in LBA */
  197.         UINT count          /* Number of sectors to write */
  198. )
  199. {
  200.   /* USER CODE BEGIN WRITE */
  201.   /* USER CODE HERE */
  202.         DRESULT ret = RES_ERROR;
  203.     BaseType_t semRet = pdFAIL;
  204.     if(xSemaphoreEmmc!=NULL){
  205.             semRet = xSemaphoreTake(xSemaphoreEmmc,portMAX_DELAY);
  206.     }
  207.     if(semRet==pdPASS){
  208.         #ifdef EMMC_USE_DMA
  209.            uint32_t alignedAddr;
  210.            uint32_t timeout;
  211.  
  212.            alignedAddr = (uint32_t)buff & ~0x1F;
  213.                 SCB_CleanDCache_by_Addr((uint32_t*)alignedAddr, count*MMC_BLOCKSIZE + ((uint32_t)buff - alignedAddr));
  214.                 if(HAL_MMC_WriteBlocks_DMA(&hmmc1, (uint8_t*)buff,
  215.                                                                  (uint32_t) (sector),
  216.                                                                  count) == HAL_OK)
  217.                 {
  218.                         /* Wait that the reading process is completed or a timeout occurs */
  219.                   timeout = HAL_GetTick();
  220.                   while((write_flag == 0) && ((HAL_GetTick() - timeout) < EMMC_TIMEOUT));
  221.                   /* incase of a timeout return error */
  222.                   if (write_flag == 0)
  223.                   {
  224.                         ret = RES_ERROR;
  225.                   }
  226.                   else
  227.                   {
  228.                         write_flag = 0;
  229.                         timeout = HAL_GetTick();
  230.                         while((HAL_GetTick() - timeout) < EMMC_TIMEOUT)
  231.                         {
  232.                           if (HAL_MMC_GetCardState(&hmmc1) == HAL_MMC_CARD_TRANSFER)
  233.                           {
  234.                                 ret = RES_OK;
  235.                                 SCB_InvalidateDCache_by_Addr((uint32_t*)alignedAddr, count*MMC_BLOCKSIZE + ((uint32_t)buff - alignedAddr));
  236.                                 break;
  237.                           }
  238.                         }
  239.                   }
  240.                 }
  241.  
  242.         #else
  243.                 if(HAL_MMC_WriteBlocks(&hmmc1, (uint8_t*)buff,
  244.                                                                  (uint32_t) (sector),
  245.                                                                   count,EMMC_TIMEOUT) == HAL_OK)
  246.                 {
  247.                         while(HAL_MMC_GetCardState(&hmmc1)!=HAL_MMC_CARD_TRANSFER);
  248.                         ret = RES_OK;
  249.                 }
  250.         #endif
  251.                 xSemaphoreGive(xSemaphoreEmmc);
  252.     }
  253.         return ret;
  254.   /* USER CODE END WRITE */
  255. }
  256. #endif /* _USE_WRITE == 1 */
  257.  
  258. /**
  259.   * @brief  I/O control operation
  260.   * @param  pdrv: Physical drive number (0..)
  261.   * @param  cmd: Control code
  262.   * @param  *buff: Buffer to send/receive control data
  263.   * @retval DRESULT: Operation result
  264.   */
  265. #if _USE_IOCTL == 1
  266. DRESULT USER_ioctl (
  267.         BYTE pdrv,      /* Physical drive nmuber (0..) */
  268.         BYTE cmd,       /* Control code */
  269.         void *buff      /* Buffer to send/receive control data */
  270. )
  271. {
  272.   /* USER CODE BEGIN IOCTL */
  273.     DRESULT res = RES_ERROR;
  274.     HAL_MMC_CardInfoTypeDef emmcinfo;
  275.  
  276.     switch(cmd)
  277.         {
  278.                 case CTRL_SYNC:
  279.                         res = RES_OK;
  280.                         break;
  281.                 case GET_SECTOR_SIZE:
  282.                         *(WORD*)buff = 512;
  283.                         res = RES_OK;
  284.                         break;
  285.                 case GET_BLOCK_SIZE:
  286.                         *(WORD*)buff = 8;
  287.                         res = RES_OK;
  288.                         break;
  289.                 case GET_SECTOR_COUNT:
  290.                         HAL_MMC_GetCardInfo(&hmmc1,&emmcinfo);
  291.                         *(WORD*)buff = emmcinfo.BlockNbr;
  292.                         res = RES_OK;
  293.                         break;
  294.                 default:
  295.                         break;
  296.         }
  297.     return res;
  298.   /* USER CODE END IOCTL */
  299. }
  300. #endif /* _USE_IOCTL == 1 */
  301.  
  302.  
复制代码

到此存储加读取部分工作完成;二、视屏播放接口驱动
1、使用LIBJPEG解码库
使用LIBJPEG解码库解码视屏压缩文件;


2、添加DMA2D支持



3、驱动代码修改
整个 代码依据的还是TOUCHGFX框架,这个框架是用C++写的,要熟系C++命名空间的语法,不然看着会很头晕,沥青不算特别复杂,挑重要的相关步骤贴一下从初始化入口

  1. void touchgfx_init()
  2. {
  3.     Bitmap::registerBitmapDatabase(BitmapDatabase::getInstance(), BitmapDatabase::getInstanceSize());
  4.     TypedText::registerTexts(&texts);
  5.     Texts::setLanguage(0);
  6.  
  7.     FontManager::setFontProvider(&fontProvider);
  8.  
  9.     FrontendHeap& heap = FrontendHeap::getInstance();
  10.     /*
  11.      * we need to obtain the reference above to initialize the frontend heap.
  12.      */
  13.     (void)heap;
  14.  
  15.     /*
  16.      * Initialize TouchGFX
  17.      */
  18.     hal.initialize();
  19. }
复制代码

TouchGFX初始化,初始化解码器

  1. void TouchGFXHAL::initialize()
  2. {
  3.     // Calling parent implementation of initialize().
  4.     //
  5.     // To overwrite the generated implementation, omit call to parent function
  6.     // and implemented needed functionality here.
  7.     // Please note, HAL::initialize() must be called to initialize the framework.
  8.  
  9.     TouchGFXGeneratedHAL::initialize();
  10.     setFrameBufferStartAddresses((void*)frameBuffer0, (void*)frameBuffer1, (void*)animationBuffer);
  11.     instrumentation.init();
  12.     setMCUInstrumentation(&instrumentation);
  13.     enableMCULoadCalculation(true);
  14. }
复制代码
  1. void TouchGFXGeneratedHAL::initialize()
  2. {
  3.     HAL::initialize();
  4.     registerEventListener(*(Application::getInstance()));
  5.     setFrameBufferStartAddresses((void*)frameBuf, (void*)(frameBuf + sizeof(frameBuf) / (sizeof(uint32_t) * 2)), (void*)0);
  6.  
  7.     /*
  8.      * Add DMA2D to hardware decoder
  9.      */
  10.     mjpegdecoder1.addDMA(dma);
  11.  
  12.     /*
  13.      * Add hardware decoder to video controller
  14.      */
  15.     videoController.addDecoder(mjpegdecoder1, 0);
  16.     videoController.setRGBBuffer((uint8_t*)videoRGBBuffer, sizeof(videoRGBBuffer));
  17. }
复制代码


控件相关在mainvewbase里面

  1. MainViewBase::MainViewBase() :
  2.     buttonCallback(this, &MainViewBase::buttonCallbackHandler)
  3. {
  4.     __background.setPosition(0, 0, 480, 272);
  5.     __background.setColor(touchgfx::Color::getColorFromRGB(0, 0, 0));
  6.     add(__background);
  7.  
  8.     backgorund.setXY(0, 0);
  9.     backgorund.setBitmap(touchgfx::Bitmap(BITMAP_BACKGROUND_ID));
  10.     add(backgorund);
  11.  
  12.     video.setPosition(132, 4, 216, 216);
  13.     video.setVideoData(video_SampleVideo2_216x216_bin_start, video_SampleVideo2_216x216_bin_length);
  14.     video.setRepeat(true);
  15.     video.play();
  16.     add(video);
  17.  
  18.     play.setXY(170, 230);
  19.     play.setBitmaps(touchgfx::Bitmap(BITMAP_BUTTON_PLAY_PINK_ID), touchgfx::Bitmap(BITMAP_BUTTON_PLAY_WHITE_ID));
  20.     play.setAction(buttonCallback);
  21.     add(play);
  22.  
  23.     pause.setXY(278, 230);
  24.     pause.setBitmaps(touchgfx::Bitmap(BITMAP_BUTTON_PAUSE_PINK_ID), touchgfx::Bitmap(BITMAP_BUTTON_PAUSE_WHITE_ID));
  25.     pause.setAction(buttonCallback);
  26.     add(pause);
  27. }
复制代码

到这里video.setVideoData(video_SampleVideo2_216x216_bin_start, video_SampleVideo2_216x216_bin_length);这个函数就是这只播放数据的,这个是内置flash的播放数据,小视屏可放在flash里直接播放,但是大文件的是不可能放在flash里面的,我们要进行改写,这里面用C++的重载特性,函数名不变,改变形参,调用的时候根据形参确定执行哪个函数;




   

  • 本文系21ic原创,未经许可禁止转载!

网友评论