- void MPU_Config(void)
- {
- MPU_Region_InitTypeDef MPU_InitStruct = {0};
- /* Disables the MPU */
- HAL_MPU_Disable();
- /** Initializes and configures the Region and the memory to be protected
- */
- MPU_InitStruct.Enable = MPU_REGION_ENABLE;
- MPU_InitStruct.Number = MPU_REGION_NUMBER0;
- MPU_InitStruct.BaseAddress = 0x0;
- MPU_InitStruct.Size = MPU_REGION_SIZE_4GB;
- MPU_InitStruct.SubRegionDisable = 0x87;
- MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
- MPU_InitStruct.AccessPermission = MPU_REGION_NO_ACCESS;
- MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_DISABLE;
- MPU_InitStruct.IsShareable = MPU_ACCESS_SHAREABLE;
- MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
- MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
- HAL_MPU_ConfigRegion(&MPU_InitStruct);
- /** Initializes and configures the Region and the memory to be protected
- */
- MPU_InitStruct.Number = MPU_REGION_NUMBER1;
- MPU_InitStruct.BaseAddress = 0xD0000000;
- MPU_InitStruct.Size = MPU_REGION_SIZE_16MB;
- MPU_InitStruct.SubRegionDisable = 0x0;
- MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
- MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
- MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE;
- MPU_InitStruct.IsBufferable = MPU_ACCESS_BUFFERABLE;
- HAL_MPU_ConfigRegion(&MPU_InitStruct);
- /* Enables the MPU */
- HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
- }
2、FMC配置
对应代码:
- void MX_FMC_Init(void)
- {
- /* USER CODE BEGIN FMC_Init 0 */
- /* USER CODE END FMC_Init 0 */
- FMC_SDRAM_TimingTypeDef SdramTiming = {0};
- /* USER CODE BEGIN FMC_Init 1 */
- /* USER CODE END FMC_Init 1 */
- /** Perform the SDRAM2 memory initialization sequence
- */
- hsdram2.Instance = FMC_SDRAM_DEVICE;
- /* hsdram2.Init */
- hsdram2.Init.SDBank = FMC_SDRAM_BANK2;
- hsdram2.Init.ColumnBitsNumber = FMC_SDRAM_COLUMN_BITS_NUM_8;
- hsdram2.Init.RowBitsNumber = FMC_SDRAM_ROW_BITS_NUM_12;
- hsdram2.Init.MemoryDataWidth = FMC_SDRAM_MEM_BUS_WIDTH_16;
- hsdram2.Init.InternalBankNumber = FMC_SDRAM_INTERN_BANKS_NUM_4;
- hsdram2.Init.CASLatency = FMC_SDRAM_CAS_LATENCY_2;
- hsdram2.Init.WriteProtection = FMC_SDRAM_WRITE_PROTECTION_DISABLE;
- hsdram2.Init.SDClockPeriod = FMC_SDRAM_CLOCK_PERIOD_2;
- hsdram2.Init.ReadBurst = FMC_SDRAM_RBURST_ENABLE;
- hsdram2.Init.ReadPipeDelay = FMC_SDRAM_RPIPE_DELAY_0;
- /* SdramTiming */
- SdramTiming.LoadToActiveDelay = 2;
- SdramTiming.ExitSelfRefreshDelay = 6;
- SdramTiming.SelfRefreshTime = 4;
- SdramTiming.RowCycleDelay = 6;
- SdramTiming.WriteRecoveryTime = 2;
- SdramTiming.RPDelay = 2;
- SdramTiming.RCDDelay = 2;
- if (HAL_SDRAM_Init(&hsdram2, &SdramTiming) != HAL_OK)
- {
- Error_Handler( );
- }
- /* USER CODE BEGIN FMC_Init 2 */
- /* USER CODE END FMC_Init 2 */
- }
3、JPEG配置
对应代码:
- static void MX_JPEG_Init(void)
- {
- /* USER CODE BEGIN JPEG_Init 0 */
- /* USER CODE END JPEG_Init 0 */
- /* USER CODE BEGIN JPEG_Init 1 */
- /* USER CODE END JPEG_Init 1 */
- hjpeg.Instance = JPEG;
- if (HAL_JPEG_Init(&hjpeg) != HAL_OK)
- {
- Error_Handler();
- }
- /* USER CODE BEGIN JPEG_Init 2 */
- /* USER CODE END JPEG_Init 2 */
- }
4、DMA2D配置
关于LTDC配置略,与前文相同。
5、JPEG硬件解码
功能依次读取MMC中的1.jpg-18.jpg,通过JPEG_Decode_DMA解码,DMA2D_CopyBuffer显示在LCD。
jpeg文件缓存:
uint8_t jpeg_buffer[1024*1024] __attribute__((section(".bss.ARM.__at_0xD0200000")));
0xD0000000:LTDC显存地址
0xD0100000:解码后数据首地址
0xD0200000:解码前数据首地址
- static void JPEG_hard_decode(uint8_t index)
- {
- FRESULT res;
- uint32_t xPos = 0, yPos = 0;
- char image_file[50];
- memset(image_file,0,50);
- sprintf(image_file,"image%d.jpg",index);
-
- if(f_mount(&MMCFatFs, (TCHAR const*)MMCPath, 0) != FR_OK)
- {
- printf("f_mount error\r\n");
- return;
- }
-
- if(f_open(&MyFile, image_file, FA_READ) != FR_OK)
- {
- printf("f_open jpeg error\r\n");
- return;
- }else{
- printf("f_open jpeg ok\r\n");
- }
-
- if(FR_OK==f_read(&MyFile,jpeg_buffer,sizeof(jpeg_buffer),&jpeg_read_size))
- {
- printf("f_read ok\r\n");
- printf("jpeg_read_size:%d\r\n",jpeg_read_size);
- JPEG_Decode_DMA(&hjpeg, 0xD0200000, jpeg_read_size , 0xD0100000);//(uint32_t)jpeg_buffer,(uint32_t)_onepic
- while(Jpeg_HWDecodingEnd == 0)
- {
- }
- HAL_JPEG_GetInfo(&hjpeg, &JPEG_Info);
- xPos = (LCD_RES_X - JPEG_Info.ImageWidth)/2;
- yPos = (LCD_RES_Y - JPEG_Info.ImageHeight)/2;
-
- printf("xPos:%d,yPos:%d,ImageWidth:%d,ImageHeight:%d,ChromaSubsampling:%d\r\n", xPos , yPos, JPEG_Info.ImageWidth, JPEG_Info.ImageHeight, JPEG_Info.ChromaSubsampling);
- DMA2D_CopyBuffer((uint32_t *)0xD0100000, (uint32_t*)LCD_FRAME_BUFFER, xPos , yPos, JPEG_Info.ImageWidth, JPEG_Info.ImageHeight, JPEG_Info.ChromaSubsampling);
-
- }
- else
- printf("f_read error\r\n");
-
- f_close(&MyFile);
- }
JPEG_Decode_DMA函数来自例程中decode_dma.c文件。
- uint32_t JPEG_Decode_DMA(JPEG_HandleTypeDef *hjpeg, uint32_t FrameSourceAddress ,uint32_t FrameSize, uint32_t DestAddress)
- {
- JPEGSourceAddress = FrameSourceAddress ;
- FrameBufferAddress = DestAddress;
- Input_frameIndex=0;
- Input_frameSize = FrameSize;
-
- Jpeg_HWDecodingEnd = 0;
-
- /* Start JPEG decoding with DMA method */
- HAL_JPEG_Decode_DMA(hjpeg ,(uint8_t *)JPEGSourceAddress ,CHUNK_SIZE_IN ,(uint8_t *)FrameBufferAddress ,CHUNK_SIZE_OUT);
-
-
- return 0;
-
- }
DMA2D_CopyBuffer内容如下,也是源于例程
- static void DMA2D_CopyBuffer(uint32_t *pSrc, uint32_t *pDst, uint16_t x, uint16_t y, uint16_t xsize, uint16_t ysize, uint32_t ChromaSampling)
- {
-
- uint32_t cssMode = DMA2D_CSS_420, inputLineOffset = 0;
- uint32_t destination = 0;
- uint16_t timeout=0;
-
- if(ChromaSampling == JPEG_420_SUBSAMPLING)
- {
- cssMode = DMA2D_CSS_420;
-
- inputLineOffset = xsize % 16;
- if(inputLineOffset != 0)
- {
- inputLineOffset = 16 - inputLineOffset;
- }
- }
- else if(ChromaSampling == JPEG_444_SUBSAMPLING)
- {
- cssMode = DMA2D_NO_CSS;
-
- inputLineOffset = xsize % 8;
- if(inputLineOffset != 0)
- {
- inputLineOffset = 8 - inputLineOffset;
- }
- }
- else if(ChromaSampling == JPEG_422_SUBSAMPLING)
- {
- cssMode = DMA2D_CSS_422;
-
- inputLineOffset = xsize % 16;
- if(inputLineOffset != 0)
- {
- inputLineOffset = 16 - inputLineOffset;
- }
- }
-
- /*##-1- Configure the DMA2D Mode, Color Mode and output offset #############*/
- hlcd_dma2d.Init.Mode = DMA2D_M2M_PFC;
- hlcd_dma2d.Init.ColorMode = DMA2D_OUTPUT_ARGB8888;
- hlcd_dma2d.Init.OutputOffset = LCD_RES_X - xsize;
- hlcd_dma2d.Init.AlphaInverted = DMA2D_REGULAR_ALPHA; /* No Output Alpha Inversion*/
- hlcd_dma2d.Init.RedBlueSwap = DMA2D_RB_REGULAR; /* No Output Red & Blue swap DMA2D_RB_SWAP*/
-
- /*##-2- DMA2D Callbacks Configuration ######################################*/
- hlcd_dma2d.XferCpltCallback = NULL;
-
- /*##-3- Foreground Configuration ###########################################*/
- hlcd_dma2d.LayerCfg[1].AlphaMode = DMA2D_REPLACE_ALPHA;
- hlcd_dma2d.LayerCfg[1].InputAlpha = 0xFF;
- hlcd_dma2d.LayerCfg[1].InputColorMode = DMA2D_INPUT_YCBCR;
- hlcd_dma2d.LayerCfg[1].ChromaSubSampling = DMA2D_NO_CSS;//cssMode;
- hlcd_dma2d.LayerCfg[1].InputOffset = inputLineOffset;
- hlcd_dma2d.LayerCfg[1].RedBlueSwap = DMA2D_RB_REGULAR; /* No ForeGround Red/Blue swap */
- hlcd_dma2d.LayerCfg[1].AlphaInverted = DMA2D_REGULAR_ALPHA; /* No ForeGround Alpha inversion */
-
- hlcd_dma2d.Instance = DMA2D;
-
- /*##-4- DMA2D Initialization ###########################################*/
- HAL_DMA2D_Init(&hlcd_dma2d);
- HAL_DMA2D_ConfigLayer(&hlcd_dma2d, 1);
-
- /*##-5- copy the new decoded frame to the LCD Frame buffer ################*/
- //BSP_LCD_GetXSize(0, &LCD_X_Size);
- destination = (uint32_t)pDst + ((y * LCD_RES_X) + x) * 4;
- SCB_CleanDCache_by_Addr((uint32_t*)pSrc, xsize*ysize*3);
- HAL_DMA2D_Start(&hlcd_dma2d, (uint32_t)pSrc, destination, xsize, ysize);
- HAL_DMA2D_PollForTransfer(&hlcd_dma2d, 25); /* wait for the previous DMA2D transfer to ends */
- while((__HAL_DMA2D_GET_FLAG(&hlcd_dma2d,DMA2D_FLAG_TC)==0)&&(timeout<0X5000))//等待DMA2D完成
- {
- timeout++;
- }
- }
jpeg硬件解码后的数据格式为YCBCR,经过DMA2D转换为ARGB8888