Hello,
I'm using a custom board with a STM32H745 MCU (STemWin v5.44). The color conversion routine is GUICC_M565.
I need to display some JPEG data among other things.
For converting JPEG data to RGB data I applied hardware JPEG decoder that converts JPEG data to YCbCr data and then I converted YCbCr data to RGB data by software.
For displaying RGB data I applied DMA2D. I call _DrawBitmap() -> it calls LCD_DrawBitmap() -> it calls LCD_LL_DrawBitmap16bpp() in LCDConf.c.
Here is a screen from the board displaying a JPEG data and some non-JPEG data (just a white text on a red background) above the JPEG picture. Works fine.
The next I tried to do is to use DMA2D not only for displaying RGB data but for displaying YCbCr data without wasting time for convertion YCbCr to RGB.
I modified some functions and now I've got the screen:
RGB data is shown incorrect. I think there is some mess in data types when calling LCD_LL_DrawBitmap16bpp().
So is it possible to display both data types (YCbCr and RGB) at the same time using DMA2D?
Here's a part of the code:
/*** displaying some image and text from main.c ***/
...
GUI_JPEG_SetpfDrawEx(JPEG_X_Draw);
GUI_JPEG_Draw(_acpic, sizeof(_acpic), 0, 0);
GUI_SetFont(GUI_FONT_20_ASCII);
GUI_SetBkColor(GUI_RED);
GUI_SetColor(GUI_WHITE);
GUI_DispStringAt("A non-JPEG data", 100, 10);
...
/*** _DrawBitmap() from main.c ***/
void _DrawBitmap(int x, int y, void const * p, int xSize, int ySize, int BytesPerLine, int BitsPerPixel) {
#if (GUI_WINSUPPORT)
GUI_RECT r;
#endif
#if (GUI_WINSUPPORT)
WM_ADDORG(x,y);
r.x1 = (r.x0 = x) + xSize-1;
r.y1 = (r.y0 = y) + ySize-1;
WM_ITERATE_START(&r) {
#endif
LCD_DrawBitmap(x, y, xSize, ySize, 1, 1, BitsPerPixel, BytesPerLine, p, NULL);
#if (GUI_WINSUPPORT)
} WM_ITERATE_END();
#endif
}
/*** JPEG_X_Draw() from main.c ***/
int JPEG_X_Draw(GUI_GET_DATA_FUNC * pfGetData, void * p, int x0, int y0) {
void * pData;
uint32_t Size;
JPEG_ConfTypeDef JPEG_Info;
pData = *(void **)p;
Size = *(uint32_t *)(p + 4);
JPEG_Decode(&hjpeg, (uint32_t)pData, Size, (uint32_t)outBuf);
while (Jpeg_HWDecodingEnd == 0);
HAL_JPEG_GetInfo(&hjpeg, &JPEG_Info);
chroma_sub_sampling = JPEG_Info.ChromaSubsampling;
jpeg_draw = 1;
_DrawBitmap(x0, y0, outBuf, Custom_JPEG_Info.JPEG_Info.ImageWidth, Custom_JPEG_Info.JPEG_Info.ImageHeight, Custom_JPEG_Info.BytesPerLine, Custom_JPEG_Info.BitsPerPixel);
jpeg_draw = 0;
return 0;
}
/*** LCD_LL_DrawBitmap16bpp() from LCDConf.c ***/
...
extern uint8_t jpeg_draw;
extern uint32_t chroma_sub_sampling;
extern void DMA2D_CopyBufferJPEG(uint32_t *pSrc, uint32_t *pDst, uint16_t xsize, uint16_t ysize, uint32_t ChromaSampling, uint32_t OffLineSrc, uint32_t OffLineDst);
...
void LCD_LL_DrawBitmap16bpp(int LayerIndex, int x, int y, U16 const * p, int xSize, int ySize, int BytesPerLine)
{
U32 BufferSize, AddrDst;
int OffLineSrc, OffLineDst;
switch (jpeg_draw) {
case 0:
BufferSize = GetBufferSize(LayerIndex);
AddrDst = layer_prop[LayerIndex].address + BufferSize * layer_prop[LayerIndex].buffer_index + (y * layer_prop[LayerIndex].xSize + x) * layer_prop[LayerIndex].BytesPerPixel;
OffLineSrc = (BytesPerLine / 2) - xSize;
OffLineDst = layer_prop[LayerIndex].xSize - xSize;
DMA2D_CopyBuffer(LayerIndex, (void *)p, (void *)AddrDst, xSize, ySize, OffLineSrc, OffLineDst);
break;
case 1:
BufferSize = GetBufferSize(LayerIndex);
AddrDst = layer_prop[LayerIndex].address + BufferSize * layer_prop[LayerIndex].buffer_index + (y * layer_prop[LayerIndex].xSize + x) * layer_prop[LayerIndex].BytesPerPixel;
OffLineSrc = (BytesPerLine / 2) - xSize;
OffLineDst = layer_prop[LayerIndex].xSize - xSize;
DMA2D_CopyBufferJPEG((void *)p, (void *)AddrDst, xSize, ySize, chroma_sub_sampling, OffLineSrc, OffLineDst);
break;
}
}
/*** DMA2D_CopyBufferJPEG() from main.c***/
void DMA2D_CopyBufferJPEG(uint32_t *pSrc, uint32_t *pDst, uint16_t xsize, uint16_t ysize, uint32_t ChromaSampling, uint32_t OffLineSrc, uint32_t OffLineDst)
{
uint32_t cssMode = LL_DMA2D_CSS_420, inputLineOffset = 0;
LL_DMA2D_IsTransferOngoing(DMA2D);
if(ChromaSampling == JPEG_420_SUBSAMPLING)
{
cssMode = LL_DMA2D_CSS_420;
inputLineOffset = xsize % 16;
if(inputLineOffset != 0)
{
inputLineOffset = 16 - inputLineOffset;
}
}
else if(ChromaSampling == JPEG_444_SUBSAMPLING)
{
cssMode = LL_DMA2D_CSS_444;
inputLineOffset = xsize % 8;
if(inputLineOffset != 0)
{
inputLineOffset = 8 - inputLineOffset;
}
}
else if(ChromaSampling == JPEG_422_SUBSAMPLING)
{
cssMode = LL_DMA2D_CSS_422;
inputLineOffset = xsize % 16;
if(inputLineOffset != 0)
{
inputLineOffset = 16 - inputLineOffset;
}
}
/*##-1- Configure the DMA2D Mode, Color Mode and output offset #############*/
LL_DMA2D_SetMode(DMA2D, LL_DMA2D_MODE_M2M_PFC);
LL_DMA2D_SetOutputColorMode(DMA2D, LL_DMA2D_OUTPUT_MODE_RGB565);
LL_DMA2D_SetLineOffset(DMA2D, OffLineDst);
LL_DMA2D_FGND_SetColorMode(DMA2D, LL_DMA2D_INPUT_MODE_YCBCR);
LL_DMA2D_FGND_SetAlphaMode(DMA2D, LL_DMA2D_ALPHA_MODE_REPLACE);
LL_DMA2D_FGND_SetAlpha(DMA2D, 0xFF);
LL_DMA2D_FGND_SetLineOffset(DMA2D, inputLineOffset);
LL_DMA2D_FGND_SetRBSwapMode(DMA2D, LL_DMA2D_RB_MODE_REGULAR);
LL_DMA2D_FGND_SetAlphaInvMode(DMA2D, LL_DMA2D_ALPHA_REGULAR);
LL_DMA2D_FGND_SetChrSubSampling(DMA2D, cssMode);
LL_DMA2D_FGND_SetMemAddr(DMA2D, (uint32_t)pSrc);
LL_DMA2D_SetOutputMemAddr(DMA2D, (uint32_t)pDst);
LL_DMA2D_SetNbrOfPixelsPerLines(DMA2D, xsize);
LL_DMA2D_SetNbrOfLines(DMA2D, ysize);
LL_DMA2D_Start(DMA2D);
LL_DMA2D_IsTransferOngoing(DMA2D);
}
Display More
Also LCDConf files in attach.
Thank you.