quipu Posted March 27, 2018 Report Posted March 27, 2018 Hello, I attached the project hoping it could be useful. I used STM32CubeMX and Atollic True Studio. I have a 128x128 custom display with UC1610 via I2C. The display shows the uGFX logduring gfxInit(), but then nothing else. /* Initialize and clear the display */ gfxInit(); // Get the screen size width = gdispGetWidth(); height = gdispGetHeight(); gdispDrawBox(10, 10, width/2, height/2, Black); gdispFillArea(width/2, height/2, width/2-10, height/2-10, Black); gdispDrawLine(5, 30, width-50, height-40, Black); for(i = 5, j = 0; i < width && j < height; i += 7, j += i/20) gdispDrawPixel(i, j, White); /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { gfxSleepMilliseconds(500); } What could be the problem ? How can I debug correctly ? Thanks bye K150_uGFX.zip
aeroman Posted March 27, 2018 Report Posted March 27, 2018 Hi, it seems you missed #define GDISP_NEED_AUTOFLUSH TRUE in gfxconf.h
Joel Bodenmann Posted March 27, 2018 Report Posted March 27, 2018 Hello @quipu and welcome to the µGFX community! As @aeroman already mentioned the problem is that the changes are not being flushed to the real display. The UC1610 GDISP driver needs to maintain an internal framebuffer as the display controller doesn't provide one that allows addressing each pixel individually. Therefore, when rendering you always modify the framebuffer inside your microcontroller's RAM. The framebuffer contents need to be actively pushed to the UC1610 display controller. This is done by what's called "flushing" in the GDISP module. There are multiple ways to flush: Manually call gdispFlush() Use auto flushing (can be enabled in the configuration file) Use a flush timer (can be enabled in the configuration file) I hope that helps.
quipu Posted March 29, 2018 Author Report Posted March 29, 2018 (edited) Hello @aeroman and @Joel Bodenmann. Thanks for support. I followed your directions and now I see something I noticed stange behavior with this code: gdispDrawBox(10, 10, 64, 64, White); /* First box without base*/ gfxSleepMillisecond(1000); gdispDrawBox(0, 0, 128, 128, White); /* Second box: drawn also base of first box ! */ The first box does not have the base. When the second box is drawn, also the base of first box is drawn! You can watch the video at this link. Also how colors are mapped? It is correct that the White is visualized and the Black no. What are Light Gray and Dark Gray? Edited March 29, 2018 by quipu
quipu Posted March 29, 2018 Author Report Posted March 29, 2018 Other question. My display is custom, as shown in the attached image (pixels are rectangular). At this link you see the problem. How can I solve? @aeroman, is it possible to configure UC1610 to limit COM number (from 160 to 128 - registers CEN, DST, DEN)? Can the "Window" function help (registers WCP0, WPP0, WCP1, WPP1)? Regards
aeroman Posted March 29, 2018 Report Posted March 29, 2018 hi @quipu, for the "colors", i use 0, 1, 2, 3 (gray0 .. gray4) when calling gdisp drawing functions. the COM number is limited to GDISP_SCREEN_HEIGHT - 1 by the UC1610_SET_COM_END (CEN register) command in the init sequence. for the rotation problem, the way used by the driver is to mirror the ram to seg mapping for X axis (datasheet pages 36..38) and on your screen this produces some ram mapped with not connected seg (128 seg < 160). A workaroud might be to adapt the window function in gdisp_lld_flush() : // set window to fill cmdBuffer[0] = UC1610_SET_WINDOW_PROGRAM_ENABLE | 0; // before changing boundaries cmdBuffer[1] = UC1610_SET_WP_STARTING_CA; cmdBuffer[3] = UC1610_SET_WP_ENDING_CA; cmdBuffer[5] = UC1610_SET_WP_STARTING_PA; cmdBuffer[6] = y1 >> 2; cmdBuffer[7] = UC1610_SET_WP_ENDING_PA; cmdBuffer[8] = y2 >> 2; cmdBuffer[9] = UC1610_SET_WINDOW_PROGRAM_ENABLE | 1; // entering window programming switch (g->g.Orientation) { default : cmdBuffer[2] = x1; cmdBuffer[4] = x2; break; case GDISP_ROTATE_90 : cmdBuffer[2] = x1 + UC1610_SEG_NUMBER - UC1610_SCREEN_WIDTH; cmdBuffer[4] = x2 + UC1610_SEG_NUMBER - UC1610_SCREEN_WIDTH; break; case GDISP_ROTATE_180 : cmdBuffer[2] = x1 + UC1610_SEG_NUMBER - UC1610_SCREEN_WIDTH; cmdBuffer[4] = x2 + UC1610_SEG_NUMBER - UC1610_SCREEN_WIDTH; break; } where UC1610_SEG_NUMBER == 160 and UC1610_SCREEN_WIDTH == 128 I suppose there is a better way to process rotation ...
quipu Posted March 29, 2018 Author Report Posted March 29, 2018 hi @aeroman, ok for the "colors". I applied you workaroud and work well. Great! Thank you. I wait for @Joel Bodenmann to say something to the "first box without base" problem.
aeroman Posted April 9, 2018 Report Posted April 9, 2018 Hi, i reproduced this bug and it seems related to the gdisp_lld_flush() function when writing pages segments from RAM(g) to display ram : with the actual y1 <= y2 in the "for" loop, when y2 is not a multiple of UC1610_PAGE_HEIGHT, the last segment is not writed to display ram. I found this solution : for loop condition based on the end address of the flush window : // write each page segment from RAM(g) to display RAM for (c = RAM(g) + xyaddr(x1, y1) ; c < RAM(g) + xyaddr(x2, y2) ; c += GDISP_SCREEN_WIDTH) { write_data(g, c, cx); } it seems to work correcly.
quipu Posted April 9, 2018 Author Report Posted April 9, 2018 4 hours ago, aeroman said: Hi, i reproduced this bug and it seems related to the gdisp_lld_flush() function when writing pages segments from RAM(g) to display ram : with the actual y1 <= y2 in the "for" loop, when y2 is not a multiple of UC1610_PAGE_HEIGHT, the last segment is not writed to display ram. I found this solution : for loop condition based on the end address of the flush window : // write each page segment from RAM(g) to display RAM for (c = RAM(g) + xyaddr(x1, y1) ; c < RAM(g) + xyaddr(x2, y2) ; c += GDISP_SCREEN_WIDTH) { write_data(g, c, cx); } it seems to work correcly. Hi @aeroman, great work. I will Apple your patch and i will let YouTube know asap.
quipu Posted April 10, 2018 Author Report Posted April 10, 2018 @aeroman after your fix seems to work well. Great!
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now