EMSTATUS GLIB_drawBitmap(GLIB_Context_t *pContext, int32_t x, int32_t y, uint32_t width, uint32_t height, uint8_t *picData) { EMSTATUS status; /* Set display clipping area for bitmap */ status = DMD_setClippingArea(x, y, width, height); if (status != DMD_OK) return status; /* Write bitmap to display */ status = DMD_writeData(0, 0, picData, width * height); if (status != DMD_OK) return status; /* Reset driver clipping area to GLIB clipping region */ return DMD_setClippingArea(pContext->clippingRegion.xMin, pContext->clippingRegion.yMin, pContext->clippingRegion.xMin + pContext->clippingRegion.xMax + 1, pContext->clippingRegion.yMin + pContext->clippingRegion.yMax + 1); }
EMSTATUS GLIB_drawRectFilled(const GLIB_Context *pContext, GLIB_Rectangle *pRect) { EMSTATUS status; GLIB_normalizeRect(pRect); GLIB_Rectangle tmpRectangle; tmpRectangle = *pRect; /* Clip rectangle if necessary */ if (tmpRectangle.xMin < pContext->clippingRegion.xMin) { tmpRectangle.xMin = pContext->clippingRegion.xMin; } if (tmpRectangle.xMax > pContext->clippingRegion.xMax) { tmpRectangle.xMax = pContext->clippingRegion.xMax; } if (tmpRectangle.yMin < pContext->clippingRegion.yMin) { tmpRectangle.yMin = pContext->clippingRegion.yMin; } if (tmpRectangle.yMax > pContext->clippingRegion.yMax) { tmpRectangle.yMax = pContext->clippingRegion.yMax; } /* Draw filled rectangle */ uint8_t red; uint8_t green; uint8_t blue; GLIB_colorTranslate24bpp(pContext->foregroundColor, &red, &green, &blue); uint16_t width; uint16_t height; width = tmpRectangle.xMax - tmpRectangle.xMin + 1; height = tmpRectangle.yMax - tmpRectangle.yMin + 1; status = DMD_setClippingArea(tmpRectangle.xMin, tmpRectangle.yMin, width, height); if (status != 0) return status; status = DMD_writeColor(0, 0, red, green, blue, width * height); if (status != 0) return status; status = GLIB_resetDisplayClippingArea(pContext); if (status != 0) return status; return GLIB_OK; }
EMSTATUS GLIB_drawBitmap(const GLIB_Context *pContext, uint16_t x, uint16_t y, uint16_t width, uint16_t height, uint8_t *picData) { EMSTATUS status; /* Set display clipping area for bitmap */ status = DMD_setClippingArea(x, y, width, height); if (status != DMD_OK) return status; /* Write bitmap to display */ status = DMD_writeData(0, 0, picData, width * height); if (status != DMD_OK) return status; /* Reset display clipping area to the whole display */ GLIB_resetDisplayClippingArea(pContext); if (status != GLIB_OK) return status; return GLIB_OK; }
/***************************************************************************//** * @brief * Initialize LCD device * * @details * * @note * ******************************************************************************/ void efm32_spiLcd_init(void) { struct efm32_usart_device_t *usart; rt_uint32_t flag; DMD_DisplayGeometry *geometry; rt_uint32_t ret; do { USART_InitSync_TypeDef init = USART_INITSYNC_DEFAULT; /* Find SPI device */ lcd = rt_device_find(LCD_USING_DEVICE_NAME); if (lcd == RT_NULL) { lcd_debug("LCD err: Can't find %s!\n", LCD_USING_DEVICE_NAME); break; } lcd_debug("LCD: Find device %s\n", LCD_USING_DEVICE_NAME); /* Config CS pin */ usart = (struct efm32_usart_device_t *)(lcd->user_data); if (!(usart->state & USART_STATE_AUTOCS)) { GPIO_PinModeSet(LCD_CS_PORT, LCD_CS_PIN, gpioModePushPull, 1); lcdAutoCs = false; } /* TFT initialize or reinitialize. Assumes EBI has been configured correctly in DVK_init(DVK_Init_EBI) */ rt_uint32_t freq = SystemCoreClockGet(); rt_uint32_t i; rt_bool_t warning = RT_FALSE; /* If we are in BC_UIF_AEM_EFM state, we can redraw graphics */ while (DVK_readRegister(&BC_REGISTER->UIF_AEM) != BC_UIF_AEM_EFM) { if (!warning) { lcd_debug("LCD: Please press AEM button!!!\n"); warning = RT_TRUE; } } lcd_debug("LCD: Got LCD control\n"); /* If we're not BC_ARB_CTRL_EBI state, we need to reconfigure display controller */ if (DVK_readRegister(&BC_REGISTER->ARB_CTRL) != BC_ARB_CTRL_EBI) { lcd_debug("LCD: Set to EBI mode\n"); /* Configure for EBI mode and reset display */ DVK_displayControl(DVK_Display_EBI); DVK_displayControl(DVK_Display_ResetAssert); DVK_displayControl(DVK_Display_PowerDisable); /* Short delay */ freq = SystemCoreClockGet(); for(i = 0; i < (freq / 100); i++) { __NOP(); } #if defined(LCD_MAPPED) /* Configure display for address mapped method + 3-wire SPI mode */ DVK_displayControl(DVK_Display_Mode8080); DVK_displayControl(DVK_Display_PowerEnable); DVK_displayControl(DVK_Display_ResetRelease); /* Initialize graphics - abort on failure */ ret = DMD_init(BC_SSD2119_BASE, BC_SSD2119_BASE + 2); if (ret == DMD_OK) { /* Make sure display is configured with correct rotation */ DMD_flipDisplay(1, 1); } else if (ret != DMD_ERROR_DRIVER_ALREADY_INITIALIZED) { lcd_debug("LCD err: driver init failed %x\n", ret); break; } #elif defined(LCD_DIRECT) /* Configure TFT direct drive method from EBI BANK2 */ const EBI_TFTInit_TypeDef tftInit = { ebiTFTBank2, /* Select EBI Bank 2 */ ebiTFTWidthHalfWord, /* Select 2-byte (16-bit RGB565) increments */ ebiTFTColorSrcMem, /* Use memory as source for mask/blending */ ebiTFTInterleaveUnlimited, /* Unlimited interleaved accesses */ ebiTFTFrameBufTriggerVSync, /* VSYNC as frame buffer update trigger */ false, /* Drive DCLK from negative edge of internal clock */ ebiTFTMBDisabled, /* No masking and alpha blending enabled */ ebiTFTDDModeExternal, /* Drive from external memory */ ebiActiveLow, /* CS Active Low polarity */ ebiActiveHigh, /* DCLK Active High polarity */ ebiActiveLow, /* DATAEN Active Low polarity */ ebiActiveLow, /* HSYNC Active Low polarity */ ebiActiveLow, /* VSYNC Active Low polarity */ 320, /* Horizontal size in pixels */ 1, /* Horizontal Front Porch */ 30, /* Horizontal Back Porch */ 2, /* Horizontal Synchronization Pulse Width */ 240, /* Vertical size in pixels */ 1, /* Vertical Front Porch */ 4, /* Vertical Back Porch */ 2, /* Vertical Synchronization Pulse Width */ 0x0000, /* Frame Address pointer offset to EBI memory base */ 4, /* DCLK Period */ 0, /* DCLK Start cycles */ 0, /* DCLK Setup cycles */ 0, /* DCLK Hold cycles */ }; DVK_enablePeripheral(DVK_TFT); /* Configure display for Direct Drive + 3-wire SPI mode */ DVK_displayControl(DVK_Display_ModeGeneric); DVK_displayControl(DVK_Display_PowerEnable); DVK_displayControl(DVK_Display_ResetRelease); /* Configure GPIO for EBI and TFT */ /* EBI TFT DCLK/Dot Clock */ GPIO_PinModeSet(gpioPortA, 8, gpioModePushPull, 0); /* EBI TFT DATAEN */ GPIO_PinModeSet(gpioPortA, 9, gpioModePushPull, 0); /* EBI TFT VSYNC */ GPIO_PinModeSet(gpioPortA, 10, gpioModePushPull, 0); /* EBI TFT HSYNC */ GPIO_PinModeSet(gpioPortA, 11, gpioModePushPull, 0); /* Initialize display */ DMD_init(0, (rt_uint32_t)EBI_BankAddress(EBI_BANK2)); /* Configure EBI TFT direct drive */ EBI_TFTInit(&tftInit); #endif } /* Get LCD geometry */ ret = DMD_getDisplayGeometry(&geometry); if (ret != DMD_OK) { lcd_debug("LCD err: get geometry failed!\n"); break; } /* Init LCD info */ flag = RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_DMA_TX; lcd_info.pixel_format = RTGRAPHIC_PIXEL_FORMAT_RGB565P; lcd_info.bits_per_pixel = 16; lcd_info.width = geometry->xSize; lcd_info.height = geometry->ySize; #if defined(LCD_MAPPED) lcd_info.framebuffer = RT_NULL; efm32_spiLcd_register(&lcd_device, LCD_DEVICE_NAME, flag, (void *)&lcd_ops); #elif defined(LCD_DIRECT) lcd_info.framebuffer = (rt_uint8_t *)EBI_BankAddress(EBI_BANK2); efm32_spiLcd_register(&lcd_device, LCD_DEVICE_NAME, flag, RT_NULL); #endif /* Set clipping area */ ret = DMD_setClippingArea(0, 0, geometry->xSize, geometry->ySize); if (ret != DMD_OK) { lcd_debug("LCD err: set clipping area failed!\n"); break; } /* Read device code */ rt_uint16_t code = 0xFFFF; #if defined(LCD_MAPPED) code = DMDIF_readDeviceCode(); #endif /* Set as rtgui graphic driver */ rtgui_graphic_set_device(&lcd_device); lcd_debug("LCD: H/W init OK!\n"); return; } while(0); lcd_debug("LCD err: H/W init failed!\n"); }
/***************************************************************************//** * @brief * Draw a vertical line with specified color * * @details * * @note * * @param[in] c * Pointer to color * * @param[in] x * Horizontal position * * @param[in] y1 * Vertical start position * * @param[in] y2 * Vertical end position ******************************************************************************/ static void efm32_spiLcd_drawVLine(rtgui_color_t *c, int x , int y1, int y2) { rt_uint32_t ret = RT_EOK; do { /* Check if line is outside of clipping region */ if ((x < 0) || (x > lcd_info.width)) { break; } /* Swap the coordinates if y1 is larger than y2 */ if (y1 > y2) { rt_uint16_t swap; swap = y1; y1 = y2; y2 = swap; } /* Check if entire line is outside clipping region */ if ((y1 > lcd_info.height) || (y2 < 0)) { /* Nothing to draw */ break; } /* Clip the line if necessary */ if (y1 < 0) { y1 = 0; } if (y2 > lcd_info.height) { y2 = lcd_info.height; } /* Set clipping area */ rt_uint16_t length = y2 - y1 + 1; ret = DMD_setClippingArea((rt_uint16_t)x, (rt_uint16_t)y1, 1, length); if (ret != DMD_OK) { break; } /* Write color */ ret= DMD_writePixel(0, 0, (rt_uint16_t)*c, length); if (ret != DMD_OK) { break; } /* Reset clipping area */ ret = DMD_setClippingArea(0, 0, lcd_info.width, lcd_info.height); if (ret != DMD_OK) { break; } return; } while(0); // lcd_debug("LCD err: Draw vline at (%d,%d-%d: %x) failed (%x)!\n", x, y1, y2, *c, ret); }
/**************************************************************************//** * @brief Clears/updates entire background ready to be drawn *****************************************************************************/ void SLIDES_showBMP(char *fileName) { int32_t xCursor; int32_t yCursor; uint32_t pixelsRead; uint32_t nPixelsPerRow; uint32_t nRows; EMSTATUS status; /* Open file */ if (f_open(&BMPfile, fileName, FA_READ) != FR_OK) { SLIDES_showError(true, "Fatal:\n Failed to open file:\n %s", fileName); } /* Initialize BMP decoder */ if (BMP_init(palette, 1024, &SLIDES_readData) != BMP_OK) { SLIDES_showError(true, "Fatal:\n Failed to init BMP library."); } /* Read headers */ if ((status = BMP_reset()) != BMP_OK) { SLIDES_showError(false, "Info:\n %s is not a BMP file", fileName); goto cleanup; } /* Get important BMP data */ nPixelsPerRow = BMP_getWidth(); nRows = BMP_getHeight(); yCursor = nRows - 1; xCursor = 0; /* Check size of BMP */ if ((nPixelsPerRow > 320) || (nRows > 240)) { SLIDES_showError(false, "Info:\n %s is larger than 320x240.", fileName); } /* Set clipping region */ DMD_setClippingArea(0, 0, nPixelsPerRow, nRows); /* Read in and draw row for row */ while (yCursor >= 0) { /* Read in row buffer */ status = BMP_readRgbData(rgbBuffer, RGB_BUFFER_SIZE, &pixelsRead); if (status != BMP_OK || pixelsRead == 0) break; /* Draw row buffer. Remember, BMP is stored bottom-up */ status = DMD_writeData(xCursor, yCursor, rgbBuffer, pixelsRead); if (status != DMD_OK) break; /* Update cursor */ xCursor += pixelsRead; if (xCursor >= (int)nPixelsPerRow) { yCursor -= xCursor / nPixelsPerRow; xCursor = xCursor % nPixelsPerRow; } } /* Reset clipping area in DMD driver */ status = GLIB_resetDisplayClippingArea(&gc); if (status != 0) return; cleanup: /* Close the file */ f_close(&BMPfile); }