From 3a8d39980b9124fe899605cb5350f42d093b1a10 Mon Sep 17 00:00:00 2001 From: Andrew Hannam Date: Mon, 10 Sep 2012 15:54:22 +1000 Subject: Changes to Console, VMT, BitBlt, Clip & Drivers Console - Fix compile, add GDISP_NEED_CONSOLE for compilation VMT - Fix after directory structure changes BitBlt - Update API to allow a source bitmap position. Clip - Add clipping support into gdisp Arc - Allow hardware accelleration of Arc routines Nokia6610 - Fixes to BitBlt. --- drivers/gdisp/Nokia6610/gdisp_lld.c | 624 ++++----- drivers/gdisp/Nokia6610/gdisp_lld_board_example.h | 21 +- .../Nokia6610/gdisp_lld_board_olimexsam7ex256.h | 22 +- drivers/gdisp/Nokia6610/gdisp_lld_config.h | 15 +- drivers/gdisp/S6D1121/gdisp_lld.c | 289 +---- drivers/gdisp/S6D1121/gdisp_lld_config.h | 17 +- drivers/gdisp/SSD1289/gdisp_lld.c | 250 +--- drivers/gdisp/SSD1289/gdisp_lld_config.h | 13 - drivers/gdisp/SSD1963/gdisp_lld.c | 1336 +++++++++----------- drivers/gdisp/SSD1963/gdisp_lld_config.h | 118 +- drivers/gdisp/TestStub/gdisp_lld.c | 259 +--- drivers/gdisp/TestStub/gdisp_lld_config.h | 15 - drivers/gdisp/VMT/gdisp_lld.c | 42 +- drivers/gdisp/VMT/gdisp_lld_config.h | 3 + drivers/gdisp/VMT/gdisp_lld_driver1.c | 4 +- drivers/gdisp/VMT/gdisp_lld_driver2.c | 4 +- 16 files changed, 1062 insertions(+), 1970 deletions(-) (limited to 'drivers') diff --git a/drivers/gdisp/Nokia6610/gdisp_lld.c b/drivers/gdisp/Nokia6610/gdisp_lld.c index 5ebe2177..b1740609 100644 --- a/drivers/gdisp/Nokia6610/gdisp_lld.c +++ b/drivers/gdisp/Nokia6610/gdisp_lld.c @@ -60,8 +60,6 @@ /* Driver local functions. */ /*===========================================================================*/ -#include "gdisp_fonts.h" - #if defined(BOARD_OLIMEX_SAM7_EX256) #include "gdisp_lld_board_olimexsam7ex256.h" #else @@ -69,16 +67,13 @@ #include "gdisp_lld_board.h" #endif -#define gdisp_lld_write_command(cmd) GDISP_LLD(write_spi)((cmd) & ~0x0100) -#define gdisp_lld_write_data(data) GDISP_LLD(write_spi)((data) | 0x0100) - static __inline void gdisp_lld_setviewport(coord_t x, coord_t y, coord_t cx, coord_t cy) { - gdisp_lld_write_command(CASET); // Column address set - gdisp_lld_write_data(x); - gdisp_lld_write_data(x+cx-1); - gdisp_lld_write_command(PASET); // Page address set - gdisp_lld_write_data(y); - gdisp_lld_write_data(y+cy-1); + GDISP_LLD(write_cmd)(CASET); // Column address set + GDISP_LLD(write_data)(x); + GDISP_LLD(write_data)(x+cx-1); + GDISP_LLD(write_cmd)(PASET); // Page address set + GDISP_LLD(write_data)(y); + GDISP_LLD(write_data)(y+cy-1); } /*===========================================================================*/ @@ -112,141 +107,141 @@ bool_t GDISP_LLD(init)(void) { #if defined(LCD_USE_GE8) #if 1 - gdisp_lld_write_command(DISCTL); // Display control - gdisp_lld_write_data(0x00); // P1: 0x00 = 2 divisions, switching period=8 (default) - gdisp_lld_write_data(0x20); // P2: 0x20 = nlines/4 - 1 = 132/4 - 1 = 32) - gdisp_lld_write_data(0x00); // P3: 0x00 = no inversely highlighted lines - gdisp_lld_write_command(COMSCN); // COM scan - gdisp_lld_write_data(1); // P1: 0x01 = Scan 1->80, 160<-81 - gdisp_lld_write_command(OSCON); // Internal oscilator ON - gdisp_lld_write_command(SLPOUT); // Sleep out - gdisp_lld_write_command(PWRCTR); // Power control - gdisp_lld_write_data(0x0f); // reference voltage regulator on, circuit voltage follower on, BOOST ON + GDISP_LLD(write_cmd)(DISCTL); // Display control + GDISP_LLD(write_data)(0x00); // P1: 0x00 = 2 divisions, switching period=8 (default) + GDISP_LLD(write_data)(0x20); // P2: 0x20 = nlines/4 - 1 = 132/4 - 1 = 32) + GDISP_LLD(write_data)(0x00); // P3: 0x00 = no inversely highlighted lines + GDISP_LLD(write_cmd)(COMSCN); // COM scan + GDISP_LLD(write_data)(1); // P1: 0x01 = Scan 1->80, 160<-81 + GDISP_LLD(write_cmd)(OSCON); // Internal oscilator ON + GDISP_LLD(write_cmd)(SLPOUT); // Sleep out + GDISP_LLD(write_cmd)(PWRCTR); // Power control + GDISP_LLD(write_data)(0x0f); // reference voltage regulator on, circuit voltage follower on, BOOST ON // Interesting - all the code seems to say this should be done. But my display doesn't want it! - //gdisp_lld_write_command(DISINV); // Inverse display - gdisp_lld_write_command(DATCTL); // Data control - gdisp_lld_write_data(0x01); // P1: 0x01 = page address inverted, column address normal, address scan in column direction - gdisp_lld_write_data(0x00); // P2: 0x00 = RGB sequence (default value) - gdisp_lld_write_data(0x02); // P3: 0x02 = Grayscale -> 16 (selects 12-bit color, type A) - gdisp_lld_write_command(VOLCTR); // Voltage control (contrast setting) - gdisp_lld_write_data(32); // P1 = 32 volume value (experiment with this value to get the best contrast) - gdisp_lld_write_data(3); // P2 = 3 resistance ratio (only value that works) + //GDISP_LLD(write_cmd)(DISINV); // Inverse display + GDISP_LLD(write_cmd)(DATCTL); // Data control + GDISP_LLD(write_data)(0x48/*0x01*/); // P1: 0x01 = page address inverted, column address normal, address scan in column direction + GDISP_LLD(write_data)(0x00); // P2: 0x00 = RGB sequence (default value) + GDISP_LLD(write_data)(0x02); // P3: 0x02 = Grayscale -> 16 (selects 12-bit color, type A) + GDISP_LLD(write_cmd)(VOLCTR); // Voltage control (contrast setting) + GDISP_LLD(write_data)(32); // P1 = 32 volume value (experiment with this value to get the best contrast) + GDISP_LLD(write_data)(3); // P2 = 3 resistance ratio (only value that works) chThdSleepMilliseconds(100); // allow power supply to stabilize - gdisp_lld_write_command(DISON); // Turn on the display + GDISP_LLD(write_cmd)(DISON); // Turn on the display #else // Alternative - gdisp_lld_write_command(DISCTL); // Display control - gdisp_lld_write_data(0x00); // default - gdisp_lld_write_data(0x20); // (32 + 1) * 4 = 132 lines (of which 130 are visible) - gdisp_lld_write_data(0x0a); // default - gdisp_lld_write_command(COMSCN); // COM scan - gdisp_lld_write_data(0x00); // Scan 1-80 - gdisp_lld_write_command(OSCON); // Internal oscilator ON + GDISP_LLD(write_cmd)(DISCTL); // Display control + GDISP_LLD(write_data)(0x00); // default + GDISP_LLD(write_data)(0x20); // (32 + 1) * 4 = 132 lines (of which 130 are visible) + GDISP_LLD(write_data)(0x0a); // default + GDISP_LLD(write_cmd)(COMSCN); // COM scan + GDISP_LLD(write_data)(0x00); // Scan 1-80 + GDISP_LLD(write_cmd)(OSCON); // Internal oscilator ON chThdSleepMilliseconds(100); // wait aproximetly 100ms - gdisp_lld_write_command(SLPOUT); // Sleep out - gdisp_lld_write_command(VOLCTR); // Voltage control - gdisp_lld_write_data(0x1F); // middle value of V1 - gdisp_lld_write_data(0x03); // middle value of resistance value - gdisp_lld_write_command(TMPGRD); // Temperature gradient - gdisp_lld_write_data(0x00); // default - gdisp_lld_write_command(PWRCTR); // Power control - gdisp_lld_write_data(0x0f); // referance voltage regulator on, circuit voltage follower on, BOOST ON - gdisp_lld_write_command(DISNOR); // Normal display - gdisp_lld_write_command(DISINV); // Inverse display - gdisp_lld_write_command(PTLOUT); // Partial area off - // gdisp_lld_write_command(ASCSET); // Scroll area set - // gdisp_lld_write_data(0); - // gdisp_lld_write_data(0); - // gdisp_lld_write_data(40); - // gdisp_lld_write_data(3); - // gdisp_lld_write_command(SCSTART); // Vertical scrool address start - // gdisp_lld_write_data(0); - gdisp_lld_write_command(DATCTL); // Data control - gdisp_lld_write_data(0x00); // all inversions off, column direction - gdisp_lld_write_data(0x03); // RGB sequence - gdisp_lld_write_data(0x02); // Grayscale -> 16 - gdisp_lld_write_command(PASET); // Page Address set - gdisp_lld_write_data(0); - gdisp_lld_write_data(131); - gdisp_lld_write_command(CASET); // Page Column set - gdisp_lld_write_data(0); - gdisp_lld_write_data(131); - gdisp_lld_write_command(DISON); // Turn on the display + GDISP_LLD(write_cmd)(SLPOUT); // Sleep out + GDISP_LLD(write_cmd)(VOLCTR); // Voltage control + GDISP_LLD(write_data)(0x1F); // middle value of V1 + GDISP_LLD(write_data)(0x03); // middle value of resistance value + GDISP_LLD(write_cmd)(TMPGRD); // Temperature gradient + GDISP_LLD(write_data)(0x00); // default + GDISP_LLD(write_cmd)(PWRCTR); // Power control + GDISP_LLD(write_data)(0x0f); // referance voltage regulator on, circuit voltage follower on, BOOST ON + GDISP_LLD(write_cmd)(DISNOR); // Normal display + GDISP_LLD(write_cmd)(DISINV); // Inverse display + GDISP_LLD(write_cmd)(PTLOUT); // Partial area off + // GDISP_LLD(write_cmd)(ASCSET); // Scroll area set + // GDISP_LLD(write_data)(0); + // GDISP_LLD(write_data)(0); + // GDISP_LLD(write_data)(40); + // GDISP_LLD(write_data)(3); + // GDISP_LLD(write_cmd)(SCSTART); // Vertical scrool address start + // GDISP_LLD(write_data)(0); + GDISP_LLD(write_cmd)(DATCTL); // Data control + GDISP_LLD(write_data)(0x00); // all inversions off, column direction + GDISP_LLD(write_data)(0x03); // RGB sequence + GDISP_LLD(write_data)(0x02); // Grayscale -> 16 + GDISP_LLD(write_cmd)(PASET); // Page Address set + GDISP_LLD(write_data)(0); + GDISP_LLD(write_data)(131); + GDISP_LLD(write_cmd)(CASET); // Page Column set + GDISP_LLD(write_data)(0); + GDISP_LLD(write_data)(131); + GDISP_LLD(write_cmd)(DISON); // Turn on the display #endif #elif defined(LCD_USE_GE12) #if 1 - gdisp_lld_write_command(SLEEPOUT); // Sleep out - gdisp_lld_write_command(INVON); // Inversion on: seems to be required for this controller - gdisp_lld_write_command(COLMOD); // Color Interface Pixel Format - gdisp_lld_write_data(0x03); // 0x03 = 12 bits-per-pixel - gdisp_lld_write_command(MADCTL); // Memory access controler - gdisp_lld_write_data(0xC8); // 0xC0 = mirror x and y, reverse rgb - gdisp_lld_write_command(SETCON); // Write contrast - gdisp_lld_write_data(0x30); // contrast - experiental value + GDISP_LLD(write_cmd)(SLEEPOUT); // Sleep out + GDISP_LLD(write_cmd)(INVON); // Inversion on: seems to be required for this controller + GDISP_LLD(write_cmd)(COLMOD); // Color Interface Pixel Format + GDISP_LLD(write_data)(0x03); // 0x03 = 12 bits-per-pixel + GDISP_LLD(write_cmd)(MADCTL); // Memory access controler + GDISP_LLD(write_data)(0xC8); // 0xC0 = mirror x and y, reverse rgb + GDISP_LLD(write_cmd)(SETCON); // Write contrast + GDISP_LLD(write_data)(0x30); // contrast - experiental value chThdSleepMilliseconds(20); - gdisp_lld_write_command(DISPON); // Display On + GDISP_LLD(write_cmd)(DISPON); // Display On #else // Alternative // Hardware reset commented out - gdisp_lld_write_command(SOFTRST); // Software Reset + GDISP_LLD(write_cmd)(SOFTRST); // Software Reset chThdSleepMilliseconds(20); - gdisp_lld_write_command(INITESC); // Initial escape + GDISP_LLD(write_cmd)(INITESC); // Initial escape chThdSleepMilliseconds(20); - gdisp_lld_write_command(REFSET); // Refresh set - gdisp_lld_write_data(0); - gdisp_lld_write_command(DISPCTRL); // Set Display control - gdisp_lld_write_data(128); // Set the lenght of one selection term - gdisp_lld_write_data(128); // Set N inversion -> no N inversion - gdisp_lld_write_data(134); // Set frame frequence and bias rate -> 2 devision of frequency and 1/8 bias, 1/67 duty, 96x67 size - gdisp_lld_write_data(84); // Set duty parameter - gdisp_lld_write_data(69); // Set duty parameter - gdisp_lld_write_data(82); // Set duty parameter - gdisp_lld_write_data(67); // Set duty parameter - gdisp_lld_write_command(GRAYSCALE0); // Grey scale 0 position set - 15 parameters - gdisp_lld_write_data(1); // GCP1 - gray lavel to be output when the RAM data is "0001" - gdisp_lld_write_data(2); // GCP2 - gray lavel to be output when the RAM data is "0010" - gdisp_lld_write_data(4); // GCP3 - gray lavel to be output when the RAM data is "0011" - gdisp_lld_write_data(8); // GCP4 - gray lavel to be output when the RAM data is "0100" - gdisp_lld_write_data(16); // GCP5 - gray lavel to be output when the RAM data is "0101" - gdisp_lld_write_data(30); // GCP6 - gray lavel to be output when the RAM data is "0110" - gdisp_lld_write_data(40); // GCP7 - gray lavel to be output when the RAM data is "0111" - gdisp_lld_write_data(50); // GCP8 - gray lavel to be output when the RAM data is "1000" - gdisp_lld_write_data(60); // GCP9 - gray lavel to be output when the RAM data is "1001" - gdisp_lld_write_data(70); // GCP10 - gray lavel to be output when the RAM data is "1010" - gdisp_lld_write_data(80); // GCP11 - gray lavel to be output when the RAM data is "1011" - gdisp_lld_write_data(90); // GCP12 - gray lavel to be output when the RAM data is "1100" - gdisp_lld_write_data(100); // GCP13 - gray lavel to be output when the RAM data is "1101" - gdisp_lld_write_data(110); // GCP14 - gray lavel to be output when the RAM data is "1110" - gdisp_lld_write_data(127); // GCP15 - gray lavel to be output when the RAM data is "1111" - gdisp_lld_write_command(GAMMA); // Gamma curve set - select gray scale - GRAYSCALE 0 or GREYSCALE 1 - gdisp_lld_write_data(1); // Select grey scale 0 - gdisp_lld_write_command(COMMONDRV); // Command driver output - gdisp_lld_write_data(0); // Set COM1-COM41 side come first, normal mod - gdisp_lld_write_command(NORMALMODE); // Set Normal mode (my) - // gdisp_lld_write_command(INVERSIONOFF); // Inversion off - gdisp_lld_write_command(COLADDRSET); // Column address set - gdisp_lld_write_data(0); - gdisp_lld_write_data(131); - gdisp_lld_write_command(PAGEADDRSET); // Page address set - gdisp_lld_write_data(0); - gdisp_lld_write_data(131); - gdisp_lld_write_command(ACCESSCTRL); // Memory access controler - gdisp_lld_write_data(0x40); // horizontal - //gdisp_lld_write_data(0x20); // vertical - gdisp_lld_write_command(PWRCTRL); // Power control - gdisp_lld_write_data(4); // Internal resistance, V1OUT -> high power mode, oscilator devision rate - gdisp_lld_write_command(SLEEPOUT); // Sleep out - gdisp_lld_write_command(VOLTCTRL); // Voltage control - voltage control and write contrast define LCD electronic volume - //gdisp_lld_write_data(0x7f); // full voltage control - //gdisp_lld_write_data(0x03); // must be "1" - gdisp_lld_write_command(CONTRAST); // Write contrast - gdisp_lld_write_data(0x3b); // contrast + GDISP_LLD(write_cmd)(REFSET); // Refresh set + GDISP_LLD(write_data)(0); + GDISP_LLD(write_cmd)(DISPCTRL); // Set Display control + GDISP_LLD(write_data)(128); // Set the lenght of one selection term + GDISP_LLD(write_data)(128); // Set N inversion -> no N inversion + GDISP_LLD(write_data)(134); // Set frame frequence and bias rate -> 2 devision of frequency and 1/8 bias, 1/67 duty, 96x67 size + GDISP_LLD(write_data)(84); // Set duty parameter + GDISP_LLD(write_data)(69); // Set duty parameter + GDISP_LLD(write_data)(82); // Set duty parameter + GDISP_LLD(write_data)(67); // Set duty parameter + GDISP_LLD(write_cmd)(GRAYSCALE0); // Grey scale 0 position set - 15 parameters + GDISP_LLD(write_data)(1); // GCP1 - gray lavel to be output when the RAM data is "0001" + GDISP_LLD(write_data)(2); // GCP2 - gray lavel to be output when the RAM data is "0010" + GDISP_LLD(write_data)(4); // GCP3 - gray lavel to be output when the RAM data is "0011" + GDISP_LLD(write_data)(8); // GCP4 - gray lavel to be output when the RAM data is "0100" + GDISP_LLD(write_data)(16); // GCP5 - gray lavel to be output when the RAM data is "0101" + GDISP_LLD(write_data)(30); // GCP6 - gray lavel to be output when the RAM data is "0110" + GDISP_LLD(write_data)(40); // GCP7 - gray lavel to be output when the RAM data is "0111" + GDISP_LLD(write_data)(50); // GCP8 - gray lavel to be output when the RAM data is "1000" + GDISP_LLD(write_data)(60); // GCP9 - gray lavel to be output when the RAM data is "1001" + GDISP_LLD(write_data)(70); // GCP10 - gray lavel to be output when the RAM data is "1010" + GDISP_LLD(write_data)(80); // GCP11 - gray lavel to be output when the RAM data is "1011" + GDISP_LLD(write_data)(90); // GCP12 - gray lavel to be output when the RAM data is "1100" + GDISP_LLD(write_data)(100); // GCP13 - gray lavel to be output when the RAM data is "1101" + GDISP_LLD(write_data)(110); // GCP14 - gray lavel to be output when the RAM data is "1110" + GDISP_LLD(write_data)(127); // GCP15 - gray lavel to be output when the RAM data is "1111" + GDISP_LLD(write_cmd)(GAMMA); // Gamma curve set - select gray scale - GRAYSCALE 0 or GREYSCALE 1 + GDISP_LLD(write_data)(1); // Select grey scale 0 + GDISP_LLD(write_cmd)(COMMONDRV); // Command driver output + GDISP_LLD(write_data)(0); // Set COM1-COM41 side come first, normal mod + GDISP_LLD(write_cmd)(NORMALMODE); // Set Normal mode (my) + // GDISP_LLD(write_cmd)(INVERSIONOFF); // Inversion off + GDISP_LLD(write_cmd)(COLADDRSET); // Column address set + GDISP_LLD(write_data)(0); + GDISP_LLD(write_data)(131); + GDISP_LLD(write_cmd)(PAGEADDRSET); // Page address set + GDISP_LLD(write_data)(0); + GDISP_LLD(write_data)(131); + GDISP_LLD(write_cmd)(ACCESSCTRL); // Memory access controler + GDISP_LLD(write_data)(0x40); // horizontal + //GDISP_LLD(write_data)(0x20); // vertical + GDISP_LLD(write_cmd)(PWRCTRL); // Power control + GDISP_LLD(write_data)(4); // Internal resistance, V1OUT -> high power mode, oscilator devision rate + GDISP_LLD(write_cmd)(SLEEPOUT); // Sleep out + GDISP_LLD(write_cmd)(VOLTCTRL); // Voltage control - voltage control and write contrast define LCD electronic volume + //GDISP_LLD(write_data)(0x7f); // full voltage control + //GDISP_LLD(write_data)(0x03); // must be "1" + GDISP_LLD(write_cmd)(CONTRAST); // Write contrast + GDISP_LLD(write_data)(0x3b); // contrast chThdSleepMilliseconds(20); - gdisp_lld_write_command(TEMPGRADIENT); // Temperature gradient - for(i=0; i<14; i++) gdisp_lld_write_data(0); - gdisp_lld_write_command(BOOSTVON); // Booster voltage ON - gdisp_lld_write_command(DISPLAYON); // Finally - Display On + GDISP_LLD(write_cmd)(TEMPGRADIENT); // Temperature gradient + for(i=0; i<14; i++) GDISP_LLD(write_data)(0); + GDISP_LLD(write_cmd)(BOOSTVON); // Booster voltage ON + GDISP_LLD(write_cmd)(DISPLAYON); // Finally - Display On #endif #endif @@ -260,6 +255,12 @@ bool_t GDISP_LLD(init)(void) { GDISP.Powermode = powerOn; GDISP.Backlight = 100; GDISP.Contrast = 50; + #if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP + GDISP.clipx0 = 0; + GDISP.clipy0 = 0; + GDISP.clipx1 = GDISP.Width-1; + GDISP.clipy1 = GDISP.Height-1; + #endif return TRUE; } @@ -273,70 +274,21 @@ bool_t GDISP_LLD(init)(void) { * @notapi */ void GDISP_LLD(drawpixel)(coord_t x, coord_t y, color_t color) { - #if GDISP_NEED_VALIDATION - if (x >= GDISP.Width || y >= GDISP.Height) return; + #if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP + if (x < GDISP.clipx0 || y < GDISP.clipy0 || x >= GDISP.clipx1 || y >= GDISP.clipy1) return; #endif gdisp_lld_setviewport(x, y, 1, 1); - gdisp_lld_write_command(RAMWR); - gdisp_lld_write_data((color >> 4) & 0xFF); - gdisp_lld_write_data((color << 4) & 0xF0); - gdisp_lld_write_command(NOP); + GDISP_LLD(write_cmd)(RAMWR); + GDISP_LLD(write_data)((color >> 4) & 0xFF); + GDISP_LLD(write_data)((color << 4) & 0xF0); + GDISP_LLD(write_cmd)(NOP); } /* ---- Optional Routines ---- */ -/* - All the below routines are optional. - Defining them will increase speed but everything - will work if they are not defined. - If you are not using a routine - turn it off using - the appropriate GDISP_HARDWARE_XXXX macro. - Don't bother coding for obvious similar routines if - there is no performance penalty as the emulation software - makes a good job of using similar routines. - eg. If fillarea() is defined there is little - point in defining clear() unless the - performance bonus is significant. - For good performance it is suggested to implement - fillarea() and blitarea(). -*/ - -#if GDISP_HARDWARE_CLEARS || defined(__DOXYGEN__) - /** - * @brief Clear the display. - * @note Optional - The high level driver can emulate using software. - * - * @param[in] color The color of the pixel - * - * @notapi - */ - void GDISP_LLD(clear(color_t color) { - /* NOT IMPLEMENTED */ - /* Nothing to be gained by implementing this - * as fillarea is just as fast. - */ - } -#endif - -#if GDISP_HARDWARE_LINES || defined(__DOXYGEN__) - /** - * @brief Draw a line. - * @note Optional - The high level driver can emulate using software. - * - * @param[in] x0, y0 The start of the line - * @param[in] x1, y1 The end of the line - * @param[in] color The color of the line - * - * @notapi - */ - void GDISP_LLD(drawline)(coord_t x0, coord_t y0, coord_t x1, coord_t y1, color_t color) { - /* NOT IMPLEMENTED */ - } -#endif #if GDISP_HARDWARE_FILLS || defined(__DOXYGEN__) /** * @brief Fill an area with a color. - * @note Optional - The high level driver can emulate using software. * * @param[in] x, y The start filled area * @param[in] cx, cy The width and height to be filled @@ -357,11 +309,11 @@ void GDISP_LLD(drawpixel)(coord_t x, coord_t y, color_t color) { // This extra pixel is ignored by the controller. gdisp_lld_setviewport(x, y, cx, cy); - gdisp_lld_write_command(RAMWR); + GDISP_LLD(write_cmd)(RAMWR); for(i=0; i < tuples; i++) { - gdisp_lld_write_data((color >> 4) & 0xFF); - gdisp_lld_write_data(((color << 4) & 0xF0)|((color >> 8) & 0x0F)); - gdisp_lld_write_data(color & 0xFF); + GDISP_LLD(write_data)((color >> 4) & 0xFF); + GDISP_LLD(write_data)(((color << 4) & 0xF0)|((color >> 8) & 0x0F)); + GDISP_LLD(write_data)(color & 0xFF); } } #endif @@ -369,175 +321,125 @@ void GDISP_LLD(drawpixel)(coord_t x, coord_t y, color_t color) { #if GDISP_HARDWARE_BITFILLS || defined(__DOXYGEN__) /** * @brief Fill an area with a bitmap. - * @note Optional - The high level driver can emulate using software. * * @param[in] x, y The start filled area * @param[in] cx, cy The width and height to be filled + * @param[in] srcx, srcy The bitmap position to start the fill from + * @param[in] srccx The width of a line in the bitmap. * @param[in] buffer The pixels to use to fill the area. * * @notapi */ - void GDISP_LLD(blitarea)(coord_t x, coord_t y, coord_t cx, coord_t cy, const pixel_t *buffer) { - unsigned i, area, tuples; - #ifndef GDISP_PACKED_PIXELS - color_t c1, c2; + void GDISP_LLD(blitareaex)(coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t srcx, coord_t srcy, coord_t srccx, const pixel_t *buffer) { + coord_t endx, endy, lg; + color_t c1, c2; + #if GDISP_PACKED_PIXELS + coord_t pos; + const uint8_t *p; #endif - #if GDISP_NEED_VALIDATION - if (cx < 1 || cy < 1 || x >= GDISP.Width || y >= GDISP.Height) return; - if (x+cx > GDISP.Width) return; - if (y+cy > GDISP.Height) cy = GDISP.Height - y; + #if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP + if (x < GDISP.clipx0) { cx -= GDISP.clipx0 - x; srcx += GDISP.clipx0 - x; x = GDISP.clipx0; } + if (y < GDISP.clipy0) { cy -= GDISP.clipy0 - y; srcy += GDISP.clipy0 - y; y = GDISP.clipy0; } + if (srcx+cx > srccx) cx = srccx - srcx; + if (cx <= 0 || cy <= 0 || x >= GDISP.clipx1 || y >= GDISP.clipy1) return; + if (x+cx > GDISP.clipx1) cx -= GDISP.clipx1 - x; + if (y+cy > GDISP.clipy1) cy -= GDISP.clipy1 - y; #endif - area = cx*cy; + /* What are our end points */ + endx = srcx + cx; + endy = y + cy; gdisp_lld_setviewport(x, y, cx, cy); - gdisp_lld_write_command(RAMWR); - - #ifdef GDISP_PACKED_PIXELS - // 3 bytes per 2 pixels + an extra 2 bytes if the total size is odd. - // Note we can't just over-estimate this and let the controller handle the extra pixel - // as that might over-run our source buffer (very bad in some circumstances). - tuples = (area/2)*3+(area & 0x01)*2; - for(i=0; i < tuples; i++) - gdisp_lld_write_data(*buffer++); - if (area & 0x01) - gdisp_lld_write_command(NOP); - #else + GDISP_LLD(write_cmd)(RAMWR); + + #if !GDISP_PACKED_PIXELS // Although this controller uses packed pixels we support unpacked pixel // formats in this blit by packing the data as we feed it to the controller. - tuples = area/2; - for(i=0; i < tuples; i++) { + lg = srccx - cx; + buffer += srcy * srccx + srcx; + x = srcx; + while (1) { + /* Get a pixel */ c1 = *buffer++; + if (++x >= endx) { + if (++y >= endy) { + /* Odd pixel at end */ + GDISP_LLD(write_data)((c1 >> 4) & 0xFF); + GDISP_LLD(write_data)((c1 << 4) & 0xF0); + GDISP_LLD(write_cmd)(NOP); + break; + } + x = srcx; + buffer += lg; + } + /* Get the next pixel */ c2 = *buffer++; - gdisp_lld_write_data((c1 >> 4) & 0xFF); - gdisp_lld_write_data(((c1 << 4) & 0xF0)|((c2 >> 8) & 0x0F)); - gdisp_lld_write_data(c2 & 0xFF); + GDISP_LLD(write_data)((c1 >> 4) & 0xFF); + GDISP_LLD(write_data)(((c1 << 4) & 0xF0)|((c2 >> 8) & 0x0F)); + GDISP_LLD(write_data)(c2 & 0xFF); + if (++x >= endx) { + if (++y >= endy) + break; + x = srcx; + buffer += lg; + } } - if (area & 0x01) { - c1 = *buffer++; - gdisp_lld_write_data((c1 >> 4) & 0xFF); - gdisp_lld_write_data((c1 << 4) & 0xF0); - gdisp_lld_write_command(NOP); - } - #endif - } -#endif -/* Circular Drawing Functions */ -#if (GDISP_NEED_CIRCLE && GDISP_HARDWARE_CIRCLES) || defined(__DOXYGEN__) - /** - * @brief Draw a circle. - * @note Optional - The high level driver can emulate using software. - * @note If GDISP_NEED_CLIPPING is defined this routine MUST behave - * correctly if the circle is over the edges of the screen. - * - * @param[in] x, y The centre of the circle - * @param[in] radius The radius of the circle - * @param[in] color The color of the circle - * - * @notapi - */ - void GDISP_LLD(drawcircle)(coord_t x, coord_t y, coord_t radius, color_t color) { - /* NOT IMPLEMENTED */ - } -#endif - -#if (GDISP_NEED_CIRCLE && GDISP_HARDWARE_CIRCLEFILLS) || defined(__DOXYGEN__) - /** - * @brief Create a filled circle. - * @note Optional - The high level driver can emulate using software. - * @note If GDISP_NEED_CLIPPING is defined this routine MUST behave - * correctly if the circle is over the edges of the screen. - * - * @param[in] x, y The centre of the circle - * @param[in] radius The radius of the circle - * @param[in] color The color of the circle - * - * @notapi - */ - void GDISP_LLD(fillcircle)(coord_t x, coord_t y, coord_t radius, color_t color) { - /* NOT IMPLEMENTED */ - } -#endif - -#if (GDISP_NEED_ELLIPSE && GDISP_HARDWARE_ELLIPSES) || defined(__DOXYGEN__) - /** - * @brief Draw an ellipse. - * @note Optional - The high level driver can emulate using software. - * @note If GDISP_NEED_CLIPPING is defined this routine MUST behave - * correctly if the ellipse is over the edges of the screen. - * - * @param[in] x, y The centre of the ellipse - * @param[in] a, b The dimensions of the ellipse - * @param[in] color The color of the ellipse - * - * @notapi - */ - void GDISP_LLD(drawellipse)(coord_t x, coord_t y, coord_t a, coord_t b, color_t color) { - /* NOT IMPLEMENTED */ - } -#endif - -#if (GDISP_NEED_ELLIPSE && GDISP_HARDWARE_ELLIPSEFILLS) || defined(__DOXYGEN__) - /** - * @brief Create a filled ellipse. - * @note Optional - The high level driver can emulate using software. - * @note If GDISP_NEED_CLIPPING is defined this routine MUST behave - * correctly if the ellipse is over the edges of the screen. - * - * @param[in] x, y The centre of the ellipse - * @param[in] a, b The dimensions of the ellipse - * @param[in] color The color of the ellipse - * - * @notapi - */ - void GDISP_LLD(fillellipse)(coord_t x, coord_t y, coord_t a, coord_t b, color_t color) { - /* NOT IMPLEMENTED */ - } -#endif - -#if (GDISP_NEED_TEXT && GDISP_HARDWARE_TEXT) || defined(__DOXYGEN__) - #include "gdisp_fonts.h" -#endif - -#if (GDISP_NEED_TEXT && GDISP_HARDWARE_TEXT) || defined(__DOXYGEN__) - /** - * @brief Draw a character using a transparent background. - * @note Optional - The high level driver can emulate using software. - * - * @param[in] x, y The top-left corner of the text - * @param[in] c The character to print - * @param[in] color The color of the character - * - * @notapi - */ - void GDISP_LLD(drawchar)(coord_t x, coord_t y, char c, font_t font, color_t color) { - /* NOT IMPLEMENTED */ - } -#endif + #else -#if (GDISP_NEED_TEXT && GDISP_HARDWARE_TEXTFILLS) || defined(__DOXYGEN__) - /** - * @brief Draw a character using a filled background. - * @note Optional - The high level driver can emulate using software. - * - * @param[in] x, y The top-left corner of the text - * @param[in] c The character to print - * @param[in] color The color of the character - * @param[in] bgcolor The background color - * - * @notapi - */ - void GDISP_LLD(fillchar)(coord_t x, coord_t y, char c, font_t font, color_t color, color_t bgcolor) { - /* NOT IMPLEMENTED */ + // Although this controller uses packed pixels, we may have to feed it into + // the controller with different packing to the source bitmap + #if !GDISP_PACKED_LINES + srccx = (srccx + 1) & ~1; + #endif + pos = srcy*srccx; + lg = (srccx - cx)/2*3; + p = ((const uint8_t *)buffer) + ((pos+srcx)/2 * 3); + + x = srcx; + while (1) { + /* Get a pixel */ + switch((pos+x)&1) { + case 0: c1 = (((color_t)p[0]) << 4)|(((color_t)p[1])>>4); break; + case 1: c1 = (((color_t)p[1]&0x0F) << 8)|((color_t)p[1]); break; + } + if (++x >= endx) { + if (++y >= endy) { + /* Odd pixel at end */ + GDISP_LLD(write_data)((c1 >> 4) & 0xFF); + GDISP_LLD(write_data)((c1 << 4) & 0xF0); + GDISP_LLD(write_cmd)(NOP); + break; + } + x = srcx; + p += lg; + pos += srccx; + } + /* Get the next pixel */ + switch((pos+x)&1) { + case 0: c2 = (((color_t)p[0]) << 4)|(((color_t)p[1])>>4); break; + case 1: c2 = (((color_t)p[1]&0x0F) << 8)|((color_t)p[1]); break; + } + GDISP_LLD(write_data)((c1 >> 4) & 0xFF); + GDISP_LLD(write_data)(((c1 << 4) & 0xF0)|((c2 >> 8) & 0x0F)); + GDISP_LLD(write_data)(c2 & 0xFF); + if (++x >= endx) { + if (++y >= endy) + break; + x = srcx; + p += lg; + pos += srccx; + } + } + #endif } #endif -#if (GDISP_NEED_PIXELREAD && GDISP_HARDWARE_PIXELREAD) || defined(__DOXYGEN__) +#if (GDISP_NEED_PIXELREAD && GDISP_HARDWARE_PIXELREAD) /** * @brief Get the color of a particular pixel. - * @note Optional. * @note If x,y is off the screen, the result is undefined. * * @param[in] x, y The start of the text @@ -546,13 +448,15 @@ void GDISP_LLD(drawpixel)(coord_t x, coord_t y, color_t color) { */ color_t GDISP_LLD(getpixelcolor)(coord_t x, coord_t y) { /* NOT IMPLEMENTED */ + /* Some board hardware might support this in the future. + * The Olimex board doesn't. + */ } #endif -#if (GDISP_NEED_SCROLL && GDISP_HARDWARE_SCROLL) || defined(__DOXYGEN__) +#if (GDISP_NEED_SCROLL && GDISP_HARDWARE_SCROLL) /** * @brief Scroll vertically a section of the screen. - * @note Optional. * @note If x,y + cx,cy is off the screen, the result is undefined. * @note If lines is >= cy, it is equivelent to a area fill with bgcolor. * @@ -565,6 +469,9 @@ void GDISP_LLD(drawpixel)(coord_t x, coord_t y, color_t color) { */ void GDISP_LLD(verticalscroll)(coord_t x, coord_t y, coord_t cx, coord_t cy, int lines, color_t bgcolor) { /* NOT IMPLEMENTED */ + /* The hardware seems capable of doing this. + * It is just really complex so we leave it out for now. + */ } #endif @@ -590,6 +497,13 @@ void GDISP_LLD(drawpixel)(coord_t x, coord_t y, color_t color) { */ void GDISP_LLD(control)(int what, void *value) { /* NOT IMPLEMENTED YET */ + /* The hardware is capable of supporting... + * GDISP_CONTROL_POWER + * GDISP_CONTROL_ORIENTATION + * GDISP_CONTROL_BACKLIGHT (at least on the Olimex board) + * GDISP_CONTROL_CONTRAST + * We don't currently implement any of it. + */ switch(what) { case GDISP_CONTROL_POWER: if (GDISP.Powermode == (gdisp_powermode_t)value) @@ -602,7 +516,7 @@ void GDISP_LLD(drawpixel)(coord_t x, coord_t y, color_t color) { /* Code here */ /* You may need this --- if (GDISP.Powermode != powerSleep) - GDISP_LLD(init(); + GDISP_LLD(init)(); */ break; case powerSleep: @@ -642,6 +556,12 @@ void GDISP_LLD(drawpixel)(coord_t x, coord_t y, color_t color) { default: return; } + #if GDISP_NEED_CLIP || GDISP_NEED_VALIDATION + GDISP.clipx0 = 0; + GDISP.clipy0 = 0; + GDISP.clipx1 = GDISP.Width; + GDISP.clipy1 = GDISP.Height; + #endif GDISP.Orientation = (gdisp_orientation_t)value; return; /* @@ -652,37 +572,5 @@ void GDISP_LLD(drawpixel)(coord_t x, coord_t y, color_t color) { } #endif -#if (GDISP_NEED_QUERY && GDISP_HARDWARE_QUERY) || defined(__DOXYGEN__) -/** - * @brief Query a driver value. - * @detail Typecase the result to the type you want. - * @note GDISP_QUERY_WIDTH - (coord_t) Gets the width of the screen - * GDISP_QUERY_HEIGHT - (coord_t) Gets the height of the screen - * GDISP_QUERY_POWER - (gdisp_powermode_t) Get the current powermode - * GDISP_QUERY_ORIENTATION - (gdisp_orientation_t) Get the current screen orientation - * GDISP_QUERY_BACKLIGHT - (coord_t) Get the backlight state (0 to 100) - * GDISP_QUERY_CONTRAST - (coord_t) Get the contrast (0 to 100). - * GDISP_QUERY_LLD - Low level driver control constants start at - * this value. - * - * @param[in] what What to Query - * - * @notapi - */ -void *GDISP_LLD(query)(unsigned what) { - switch(what) { - case GDISP_QUERY_WIDTH: return (void *)(unsigned)GDISP.Width; - case GDISP_QUERY_HEIGHT: return (void *)(unsigned)GDISP.Height; - case GDISP_QUERY_POWER: return (void *)(unsigned)GDISP.Powermode; - case GDISP_QUERY_ORIENTATION: return (void *)(unsigned)GDISP.Orientation; - case GDISP_QUERY_BACKLIGHT: return (void *)(unsigned)GDISP.Backlight; - case GDISP_QUERY_CONTRAST: return (void *)(unsigned)GDISP.Contrast; - case GDISP_QUERY_LLD+0: - /* Code here */ - default: return (void *)-1; - } -} -#endif - #endif /* HAL_USE_GDISP */ /** @} */ diff --git a/drivers/gdisp/Nokia6610/gdisp_lld_board_example.h b/drivers/gdisp/Nokia6610/gdisp_lld_board_example.h index 0e2b806e..12b136da 100644 --- a/drivers/gdisp/Nokia6610/gdisp_lld_board_example.h +++ b/drivers/gdisp/Nokia6610/gdisp_lld_board_example.h @@ -41,6 +41,7 @@ */ static __inline void GDISP_LLD(init_board)(void) { /* Code here */ +#error "gdispNokia6610: You must supply a definition for init_board for your board" } /** @@ -52,30 +53,31 @@ static __inline void GDISP_LLD(init_board)(void) { */ static __inline void GDISP_LLD(setpin_reset)(bool_t state) { /* Code here */ +#error "gdispNokia6610: You must supply a definition for setpin_reset for your board" } /** - * @brief Set or clear the lcd back-light pin. + * @brief Send an 8 bit command to the lcd. + * + * @param[in] data The command to send * - * @param[in] state TRUE = lcd back-light on, FALSE = lcd back-light off - * * @notapi */ -static __inline void GDISP_LLD(setpin_backlight)(bool_t state) { +static __inline void GDISP_LLD(write_cmd)(uint16_t data) { /* Code here */ +#error "gdispNokia6610: You must supply a definition for write_cmd for your board" } /** - * @brief Send a 9 bit command/data to the lcd. - * @note The chip select may need to be asserted/de-asserted - * around the actual spi write + * @brief Send an 8 bit data to the lcd. * * @param[in] data The data to send * * @notapi */ -static __inline void GDISP_LLD(write_spi)(uint16_t data) { +static __inline void GDISP_LLD(write_data)(uint16_t data) { /* Code here */ +#error "gdispNokia6610: You must supply a definition for write_data for your board" } #if GDISP_HARDWARE_READPIXEL || GDISP_HARDWARE_SCROLL || defined(__DOXYGEN__) @@ -88,8 +90,9 @@ static __inline void GDISP_LLD(write_spi)(uint16_t data) { * * @notapi */ -static __inline uint16_t GDISP_LLD(read_spi)(void) { +static __inline uint16_t GDISP_LLD(read_data)(void) { /* Code here */ +#error "gdispNokia6610: You must supply a definition for read_data for your board" } #endif diff --git a/drivers/gdisp/Nokia6610/gdisp_lld_board_olimexsam7ex256.h b/drivers/gdisp/Nokia6610/gdisp_lld_board_olimexsam7ex256.h index b5b4b1d5..d42dc6d4 100644 --- a/drivers/gdisp/Nokia6610/gdisp_lld_board_olimexsam7ex256.h +++ b/drivers/gdisp/Nokia6610/gdisp_lld_board_olimexsam7ex256.h @@ -168,17 +168,31 @@ static __inline void GDISP_LLD(setpin_backlight)(bool_t state) { } /** - * @brief Send a 9 bit command/data to the lcd. + * @brief Send an 8 bit command to the lcd. + * + * @param[in] data The command to send + * + * @notapi + */ +static __inline void GDISP_LLD(write_cmd)(uint16_t data) { + // wait for the previous transfer to complete + while((pSPI->SPI_SR & AT91C_SPI_TXEMPTY) == 0); + // send the command + pSPI->SPI_TDR = data & 0xFF; +} + +/** + * @brief Send an 8 bit data to the lcd. * * @param[in] data The data to send * * @notapi */ -static __inline void GDISP_LLD(write_spi)(uint16_t data) { +static __inline void GDISP_LLD(write_data)(uint16_t data) { // wait for the previous transfer to complete while((pSPI->SPI_SR & AT91C_SPI_TXEMPTY) == 0); // send the data - pSPI->SPI_TDR = data; + pSPI->SPI_TDR = data | 0x0100; } #if GDISP_HARDWARE_READPIXEL || GDISP_HARDWARE_SCROLL || defined(__DOXYGEN__) @@ -189,7 +203,7 @@ static __inline void GDISP_LLD(write_spi)(uint16_t data) { * * @notapi */ -static __inline uint16_t GDISP_LLD(read_spi)(void) { +static __inline uint16_t GDISP_LLD(read_data)(void) { #error "gdispNokia6610: GDISP_HARDWARE_READPIXEL and GDISP_HARDWARE_SCROLL are not supported on this board" return 0; } diff --git a/drivers/gdisp/Nokia6610/gdisp_lld_config.h b/drivers/gdisp/Nokia6610/gdisp_lld_config.h index 9e2d1258..7d458447 100644 --- a/drivers/gdisp/Nokia6610/gdisp_lld_config.h +++ b/drivers/gdisp/Nokia6610/gdisp_lld_config.h @@ -38,25 +38,18 @@ #define GDISP_DRIVER_NAME "Nokia6610" #define GDISP_LLD(x) gdisp_lld_##x##_Nokia6610 -#define GDISP_HARDWARE_LINES FALSE -#define GDISP_HARDWARE_CLEARS FALSE #define GDISP_HARDWARE_FILLS TRUE #define GDISP_HARDWARE_BITFILLS TRUE -#define GDISP_HARDWARE_CIRCLES FALSE -#define GDISP_HARDWARE_CIRCLEFILLS FALSE -#define GDISP_HARDWARE_ELLIPSES FALSE -#define GDISP_HARDWARE_ELLIPSEFILLS FALSE -#define GDISP_HARDWARE_TEXT FALSE -#define GDISP_HARDWARE_TEXTFILLS FALSE -#define GDISP_HARDWARE_SCROLL FALSE -#define GDISP_HARDWARE_PIXELREAD FALSE #define GDISP_HARDWARE_CONTROL FALSE #define GDISP_HARDWARE_QUERY FALSE -#define GDISP_SOFTWARE_TEXTFILLDRAW TRUE +#define GDISP_SOFTWARE_TEXTFILLDRAW FALSE #define GDISP_SOFTWARE_TEXTBLITCOLUMN FALSE #define GDISP_PIXELFORMAT GDISP_PIXELFORMAT_RGB444 +/* This driver supports both packed and unpacked pixel formats and line formats. + * By default we leave these as FALSE. + */ #define GDISP_PACKED_PIXELS FALSE #define GDISP_PACKED_LINES FALSE diff --git a/drivers/gdisp/S6D1121/gdisp_lld.c b/drivers/gdisp/S6D1121/gdisp_lld.c index 5811a6ed..f6e8166a 100644 --- a/drivers/gdisp/S6D1121/gdisp_lld.c +++ b/drivers/gdisp/S6D1121/gdisp_lld.c @@ -35,22 +35,6 @@ /* Include the emulation code for things we don't support */ #include "gdisp_emulation.c" -/*===========================================================================*/ -/* Driver local definitions. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver exported variables. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver local variables. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver local functions. */ -/*===========================================================================*/ - #include "s6d1121_lld.c.h" /*===========================================================================*/ @@ -200,6 +184,12 @@ bool_t GDISP_LLD(init)(void) { GDISP.Powermode = powerOn; GDISP.Backlight = 100; GDISP.Contrast = 50; + #if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP + GDISP.clipx0 = 0; + GDISP.clipy0 = 0; + GDISP.clipx1 = GDISP.Width-1; + GDISP.clipy1 = GDISP.Height-1; + #endif return TRUE; } @@ -213,29 +203,14 @@ bool_t GDISP_LLD(init)(void) { * @notapi */ void GDISP_LLD(drawpixel)(coord_t x, coord_t y, color_t color) { - #if GDISP_NEED_VALIDATION - if (x >= GDISP.Width || y >= GDISP.Height) return; + #if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP + if (x < GDISP.clipx0 || y < GDISP.clipy0 || x >= GDISP.clipx1 || y >= GDISP.clipy1) return; #endif lld_lcdSetCursor(x, y); lld_lcdWriteReg(0x0022, color); } /* ---- Optional Routines ---- */ -/* - All the below routines are optional. - Defining them will increase speed but everything - will work if they are not defined. - If you are not using a routine - turn it off using - the appropriate GDISP_HARDWARE_XXXX macro. - Don't bother coding for obvious similar routines if - there is no performance penalty as the emulation software - makes a good job of using similar routines. - eg. If fillarea() is defined there is little - point in defining clear() unless the - performance bonus is significant. - For good performance it is suggested to implement - fillarea() and blitarea(). -*/ #if GDISP_HARDWARE_CLEARS || defined(__DOXYGEN__) /** @@ -259,25 +234,6 @@ void GDISP_LLD(drawpixel)(coord_t x, coord_t y, color_t color) { } #endif -#if GDISP_HARDWARE_LINES || defined(__DOXYGEN__) - /** - * @brief Draw a line. - * @note Optional - The high level driver can emulate using software. - * - * @param[in] x0, y0 The start of the line - * @param[in] x1, y1 The end of the line - * @param[in] color The color of the line - * - * @notapi - */ - void GDISP_LLD(drawline)(coord_t x0, coord_t y0, coord_t x1, coord_t y1, color_t color) { - #if GDISP_NEED_VALIDATION - /* Need to clip to screen */ - #endif - /* Code here */ - } -#endif - #if GDISP_HARDWARE_FILLS || defined(__DOXYGEN__) /** * @brief Fill an area with a color. @@ -290,14 +246,16 @@ void GDISP_LLD(drawpixel)(coord_t x, coord_t y, color_t color) { * @notapi */ void GDISP_LLD(fillarea)(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color) { - #if GDISP_NEED_VALIDATION - if (cx < 1 || cy < 1 || x >= GDISP.Width || y >= GDISP.Height) return; - if (x+cx > GDISP.Width) cx = GDISP.Width - x; - if (y+cy > GDISP.Height) cy = GDISP.Height - y; - #endif - unsigned i, area; + #if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP + if (x < GDISP.clipx0) { cx -= GDISP.clipx0 - x; x = GDISP.clipx0; } + if (y < GDISP.clipy0) { cy -= GDISP.clipy0 - y; y = GDISP.clipy0; } + if (cx <= 0 || cy <= 0 || x >= GDISP.clipx1 || y >= GDISP.clipy1) return; + if (x+cx > GDISP.clipx1) cx -= GDISP.clipx1 - x; + if (y+cy > GDISP.clipy1) cy -= GDISP.clipy1 - y; + #endif + area = cx*cy; lld_lcdSetViewPort(x, y, cx, cy); lld_lcdWriteStreamStart(); @@ -315,157 +273,40 @@ void GDISP_LLD(drawpixel)(coord_t x, coord_t y, color_t color) { * * @param[in] x, y The start filled area * @param[in] cx, cy The width and height to be filled + * @param[in] srcx, srcy The bitmap position to start the fill from + * @param[in] srccx The width of a line in the bitmap. * @param[in] buffer The pixels to use to fill the area. * * @notapi */ - void GDISP_LLD(blitarea)(coord_t x, coord_t y, coord_t cx, coord_t cy, const pixel_t *buffer) { - unsigned i, area; - - #if GDISP_NEED_VALIDATION - if (cx < 1 || cy < 1 || x >= GDISP.Width || y >= GDISP.Height) return; - if (x+cx > GDISP.Width) return; - if (y+cy > GDISP.Height) cy = GDISP.Height - y; + void GDISP_LLD(blitareaex)(coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t srcx, coord_t srcy, coord_t srccx, const pixel_t *buffer) { + coord_t endx, endy; + unsigned lg; + + #if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP + if (x < GDISP.clipx0) { cx -= GDISP.clipx0 - x; srcx += GDISP.clipx0 - x; x = GDISP.clipx0; } + if (y < GDISP.clipy0) { cy -= GDISP.clipy0 - y; srcy += GDISP.clipy0 - y; y = GDISP.clipy0; } + if (srcx+cx > srccx) cx = srccx - srcx; + if (cx <= 0 || cy <= 0 || x >= GDISP.clipx1 || y >= GDISP.clipy1) return; + if (x+cx > GDISP.clipx1) cx -= GDISP.clipx1 - x; + if (y+cy > GDISP.clipy1) cy -= GDISP.clipy1 - y; #endif - area = cx*cy; lld_lcdSetViewPort(x, y, cx, cy); lld_lcdWriteStreamStart(); - for(i = 0; i < area; i++) - lld_lcdWriteData(*buffer++); + + endx = srcx + cx; + endy = y + cy; + lg = srccx - cx; + buffer += srcx + srcy * srccx; + for(; y < endy; y++, buffer += lg) + for(x=srcx; x < endx; x++) + lld_lcdWriteData(*buffer++); lld_lcdWriteStreamStop(); lld_lcdResetViewPort(); } #endif -/* Circular Drawing Functions */ -#if (GDISP_NEED_CIRCLE && GDISP_HARDWARE_CIRCLES) || defined(__DOXYGEN__) - /** - * @brief Draw a circle. - * @note Optional - The high level driver can emulate using software. - * @note If GDISP_NEED_CLIPPING is defined this routine MUST behave - * correctly if the circle is over the edges of the screen. - * - * @param[in] x, y The centre of the circle - * @param[in] radius The radius of the circle - * @param[in] color The color of the circle - * - * @notapi - */ - void GDISP_LLD(drawcircle)(coord_t x, coord_t y, coord_t radius, color_t color) { - #if GDISP_NEED_VALIDATION - /* Code here */ - #endif - /* Code here */ - } -#endif - -#if (GDISP_NEED_CIRCLE && GDISP_HARDWARE_CIRCLEFILLS) || defined(__DOXYGEN__) - /** - * @brief Create a filled circle. - * @note Optional - The high level driver can emulate using software. - * @note If GDISP_NEED_CLIPPING is defined this routine MUST behave - * correctly if the circle is over the edges of the screen. - * - * @param[in] x, y The centre of the circle - * @param[in] radius The radius of the circle - * @param[in] color The color of the circle - * - * @notapi - */ - void GDISP_LLD(fillcircle)(coord_t x, coord_t y, coord_t radius, color_t color) { - #if GDISP_NEED_VALIDATION - /* Code here */ - #endif - /* Code here */ - } -#endif - -#if (GDISP_NEED_ELLIPSE && GDISP_HARDWARE_ELLIPSES) || defined(__DOXYGEN__) - /** - * @brief Draw an ellipse. - * @note Optional - The high level driver can emulate using software. - * @note If GDISP_NEED_CLIPPING is defined this routine MUST behave - * correctly if the ellipse is over the edges of the screen. - * - * @param[in] x, y The centre of the ellipse - * @param[in] a, b The dimensions of the ellipse - * @param[in] color The color of the ellipse - * - * @notapi - */ - void GDISP_LLD(drawellipse)(coord_t x, coord_t y, coord_t a, coord_t b, color_t color) { - #if GDISP_NEED_VALIDATION - /* Code here */ - #endif - /* Code here */ - } -#endif - -#if (GDISP_NEED_ELLIPSE && GDISP_HARDWARE_ELLIPSEFILLS) || defined(__DOXYGEN__) - /** - * @brief Create a filled ellipse. - * @note Optional - The high level driver can emulate using software. - * @note If GDISP_NEED_CLIPPING is defined this routine MUST behave - * correctly if the ellipse is over the edges of the screen. - * - * @param[in] x, y The centre of the ellipse - * @param[in] a, b The dimensions of the ellipse - * @param[in] color The color of the ellipse - * - * @notapi - */ - void GDISP_LLD(fillellipse)(coord_t x, coord_t y, coord_t a, coord_t b, color_t color) { - #if GDISP_NEED_VALIDATION - /* Code here */ - #endif - /* Code here */ - } -#endif - -#if (GDISP_NEED_TEXT && GDISP_HARDWARE_TEXT) || defined(__DOXYGEN__) - #include "gdisp_fonts.h" -#endif - -#if (GDISP_NEED_TEXT && GDISP_HARDWARE_TEXT) || defined(__DOXYGEN__) - /** - * @brief Draw a character using a transparent background. - * @note Optional - The high level driver can emulate using software. - * - * @param[in] x, y The top-left corner of the text - * @param[in] c The character to print - * @param[in] color The color of the character - * - * @notapi - */ - void GDISP_LLD(drawchar)(coord_t x, coord_t y, char c, font_t font, color_t color) { - #if GDISP_NEED_VALIDATION - /* Code here */ - #endif - /* Code here */ - } -#endif - -#if (GDISP_NEED_TEXT && GDISP_HARDWARE_TEXTFILLS) || defined(__DOXYGEN__) - /** - * @brief Draw a character using a filled background. - * @note Optional - The high level driver can emulate using software. - * - * @param[in] x, y The top-left corner of the text - * @param[in] c The character to print - * @param[in] color The color of the character - * @param[in] bgcolor The background color - * - * @notapi - */ - void GDISP_LLD(fillchar)(coord_t x, coord_t y, char c, font_t font, color_t color, color_t bgcolor) { - #if GDISP_NEED_VALIDATION - /* Code here */ - #endif - /* Code here */ - } -#endif - #if (GDISP_NEED_PIXELREAD && GDISP_HARDWARE_PIXELREAD) || defined(__DOXYGEN__) /** * @brief Get the color of a particular pixel. @@ -483,8 +324,8 @@ void GDISP_LLD(drawpixel)(coord_t x, coord_t y, color_t color) { */ color_t color; - #if GDISP_NEED_VALIDATION - if (x >= GDISP.Width || y >= GDISP.Height) return 0; + #if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP + if (x < 0 || x >= GDISP.Width || y < 0 || y >= GDISP.Height) return 0; #endif lld_lcdSetCursor(x, y); @@ -521,15 +362,15 @@ void GDISP_LLD(drawpixel)(coord_t x, coord_t y, color_t color) { coord_t row0, row1; unsigned i, gap, abslines; - abslines = lines < 0 ? -lines : lines; - - #if GDISP_NEED_VALIDATION - if (cx < 1 || cy < 1 || x >= GDISP.Width || y >= GDISP.Height) return; - if (x+cx > GDISP.Width) cx = GDISP.Width - x; - if (y+cy > GDISP.Height) cy = GDISP.Height - y; + #if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP + if (x < GDISP.clipx0) { cx -= GDISP.clipx0 - x; x = GDISP.clipx0; } + if (y < GDISP.clipy0) { cy -= GDISP.clipy0 - y; y = GDISP.clipy0; } + if (!lines || cx <= 0 || cy <= 0 || x >= GDISP.clipx1 || y >= GDISP.clipy1) return; + if (x+cx > GDISP.clipx1) cx -= GDISP.clipx1 - x; + if (y+cy > GDISP.clipy1) cy = GDISP.clipy1 - y; #endif - if (!abslines) return; + abslines = lines < 0 ? -lines : lines; if (abslines >= cy) { abslines = cy; gap = 0; @@ -642,6 +483,12 @@ void GDISP_LLD(drawpixel)(coord_t x, coord_t y, color_t color) { default: return; } + #if GDISP_NEED_CLIP || GDISP_NEED_VALIDATION + GDISP.clipx0 = 0; + GDISP.clipy0 = 0; + GDISP.clipx1 = GDISP.Width; + GDISP.clipy1 = GDISP.Height; + #endif GDISP.Orientation = (gdisp_orientation_t)value; return; /* @@ -652,37 +499,5 @@ void GDISP_LLD(drawpixel)(coord_t x, coord_t y, color_t color) { } #endif -#if (GDISP_NEED_QUERY && GDISP_HARDWARE_QUERY) || defined(__DOXYGEN__) -/** - * @brief Query a driver value. - * @detail Typecase the result to the type you want. - * @note GDISP_QUERY_WIDTH - (coord_t) Gets the width of the screen - * GDISP_QUERY_HEIGHT - (coord_t) Gets the height of the screen - * GDISP_QUERY_POWER - (gdisp_powermode_t) Get the current powermode - * GDISP_QUERY_ORIENTATION - (gdisp_orientation_t) Get the current screen orientation - * GDISP_QUERY_BACKLIGHT - (coord_t) Get the backlight state (0 to 100) - * GDISP_QUERY_CONTRAST - (coord_t) Get the contrast (0 to 100). - * GDISP_QUERY_LLD - Low level driver control constants start at - * this value. - * - * @param[in] what What to Query - * - * @notapi - */ -void *GDISP_LLD(query)(unsigned what) { - switch(what) { - case GDISP_QUERY_WIDTH: return (void *)(unsigned)GDISP.Width; - case GDISP_QUERY_HEIGHT: return (void *)(unsigned)GDISP.Height; - case GDISP_QUERY_POWER: return (void *)(unsigned)GDISP.Powermode; - case GDISP_QUERY_ORIENTATION: return (void *)(unsigned)GDISP.Orientation; - case GDISP_QUERY_BACKLIGHT: return (void *)(unsigned)GDISP.Backlight; - case GDISP_QUERY_CONTRAST: return (void *)(unsigned)GDISP.Contrast; - case GDISP_QUERY_LLD+0: - /* Code here */ - default: return (void *)-1; - } -} -#endif - #endif /* HAL_USE_GDISP */ /** @} */ diff --git a/drivers/gdisp/S6D1121/gdisp_lld_config.h b/drivers/gdisp/S6D1121/gdisp_lld_config.h index ee3fdeee..65849c40 100644 --- a/drivers/gdisp/S6D1121/gdisp_lld_config.h +++ b/drivers/gdisp/S6D1121/gdisp_lld_config.h @@ -35,30 +35,17 @@ /* Driver hardware support. */ /*===========================================================================*/ -#define GDISP_DRIVER_NAME "S6d1121" -#define GDISP_LLD(x) gdisp_lld_##x##_S6d1121 +#define GDISP_DRIVER_NAME "S6D1121" +#define GDISP_LLD(x) gdisp_lld_##x##_S6D1121 -#define GDISP_HARDWARE_LINES FALSE #define GDISP_HARDWARE_CLEARS TRUE #define GDISP_HARDWARE_FILLS TRUE #define GDISP_HARDWARE_BITFILLS TRUE -#define GDISP_HARDWARE_CIRCLES FALSE -#define GDISP_HARDWARE_CIRCLEFILLS FALSE -#define GDISP_HARDWARE_ELLIPSES FALSE -#define GDISP_HARDWARE_ELLIPSEFILLS FALSE -#define GDISP_HARDWARE_TEXT FALSE -#define GDISP_HARDWARE_TEXTFILLS FALSE #define GDISP_HARDWARE_SCROLL TRUE #define GDISP_HARDWARE_PIXELREAD FALSE #define GDISP_HARDWARE_CONTROL TRUE -#define GDISP_HARDWARE_QUERY FALSE - -#define GDISP_SOFTWARE_TEXTFILLDRAW FALSE -#define GDISP_SOFTWARE_TEXTBLITCOLUMN FALSE #define GDISP_PIXELFORMAT GDISP_PIXELFORMAT_RGB565 -#define GDISP_PACKED_PIXELS FALSE -#define GDISP_PACKED_LINES FALSE #endif /* HAL_USE_GDISP */ diff --git a/drivers/gdisp/SSD1289/gdisp_lld.c b/drivers/gdisp/SSD1289/gdisp_lld.c index 5f017b37..21e0abf0 100644 --- a/drivers/gdisp/SSD1289/gdisp_lld.c +++ b/drivers/gdisp/SSD1289/gdisp_lld.c @@ -35,22 +35,6 @@ /* Include the emulation code for things we don't support */ #include "gdisp_emulation.c" -/*===========================================================================*/ -/* Driver local definitions. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver exported variables. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver local variables. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver local functions. */ -/*===========================================================================*/ - #include "ssd1289_lld.c.h" /*===========================================================================*/ @@ -141,6 +125,12 @@ bool_t GDISP_LLD(init)(void) { GDISP.Powermode = powerOn; GDISP.Backlight = 100; GDISP.Contrast = 50; + #if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP + GDISP.clipx0 = 0; + GDISP.clipy0 = 0; + GDISP.clipx1 = GDISP.Width-1; + GDISP.clipy1 = GDISP.Height-1; + #endif return TRUE; } @@ -154,8 +144,8 @@ bool_t GDISP_LLD(init)(void) { * @notapi */ void GDISP_LLD(drawpixel)(coord_t x, coord_t y, color_t color) { - #if GDISP_NEED_VALIDATION - if (x >= GDISP.Width || y >= GDISP.Height) return; + #if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP + if (x < GDISP.clipx0 || y < GDISP.clipy0 || x >= GDISP.clipx1 || y >= GDISP.clipy1) return; #endif lld_lcdSetCursor(x, y); lld_lcdWriteReg(0x0022, color); @@ -200,22 +190,6 @@ void GDISP_LLD(drawpixel)(coord_t x, coord_t y, color_t color) { } #endif -#if GDISP_HARDWARE_LINES || defined(__DOXYGEN__) - /** - * @brief Draw a line. - * @note Optional - The high level driver can emulate using software. - * - * @param[in] x0, y0 The start of the line - * @param[in] x1, y1 The end of the line - * @param[in] color The color of the line - * - * @notapi - */ - void GDISP_LLD(drawline)(coord_t x0, coord_t y0, coord_t x1, coord_t y1, color_t color) { - /* NOT IMPLEMENTED */ - } -#endif - #if GDISP_HARDWARE_FILLS || defined(__DOXYGEN__) /** * @brief Fill an area with a color. @@ -228,10 +202,12 @@ void GDISP_LLD(drawpixel)(coord_t x, coord_t y, color_t color) { * @notapi */ void GDISP_LLD(fillarea)(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color) { - #if GDISP_NEED_VALIDATION - if (cx < 1 || cy < 1 || x >= GDISP.Width || y >= GDISP.Height) return; - if (x+cx > GDISP.Width) cx = GDISP.Width - x; - if (y+cy > GDISP.Height) cy = GDISP.Height - y; + #if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP + if (x < GDISP.clipx0) { cx -= GDISP.clipx0 - x; x = GDISP.clipx0; } + if (y < GDISP.clipy0) { cy -= GDISP.clipy0 - y; y = GDISP.clipy0; } + if (cx <= 0 || cy <= 0 || x >= GDISP.clipx1 || y >= GDISP.clipy1) return; + if (x+cx > GDISP.clipx1) cx -= GDISP.clipx1 - x; + if (y+cy > GDISP.clipy1) cy -= GDISP.clipy1 - y; #endif unsigned i, area; @@ -253,139 +229,40 @@ void GDISP_LLD(drawpixel)(coord_t x, coord_t y, color_t color) { * * @param[in] x, y The start filled area * @param[in] cx, cy The width and height to be filled + * @param[in] srcx, srcy The bitmap position to start the fill from + * @param[in] srccx The width of a line in the bitmap. * @param[in] buffer The pixels to use to fill the area. * * @notapi */ - void GDISP_LLD(blitarea)(coord_t x, coord_t y, coord_t cx, coord_t cy, const pixel_t *buffer) { - unsigned i, area; - - #if GDISP_NEED_VALIDATION - if (cx < 1 || cy < 1 || x >= GDISP.Width || y >= GDISP.Height) return; - if (x+cx > GDISP.Width) return; - if (y+cy > GDISP.Height) cy = GDISP.Height - y; + void GDISP_LLD(blitareaex)(coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t srcx, coord_t srcy, coord_t srccx, const pixel_t *buffer) { + coord_t endx, endy; + unsigned lg; + + #if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP + if (x < GDISP.clipx0) { cx -= GDISP.clipx0 - x; srcx += GDISP.clipx0 - x; x = GDISP.clipx0; } + if (y < GDISP.clipy0) { cy -= GDISP.clipy0 - y; srcy += GDISP.clipy0 - y; y = GDISP.clipy0; } + if (srcx+cx > srccx) cx = srccx - srcx; + if (cx <= 0 || cy <= 0 || x >= GDISP.clipx1 || y >= GDISP.clipy1) return; + if (x+cx > GDISP.clipx1) cx -= GDISP.clipx1 - x; + if (y+cy > GDISP.clipy1) cy -= GDISP.clipy1 - y; #endif - area = cx*cy; lld_lcdSetViewPort(x, y, cx, cy); lld_lcdWriteStreamStart(); - for(i = 0; i < area; i++) - lld_lcdWriteData(*buffer++); + + endx = srcx + cx; + endy = y + cy; + lg = srccx - cx; + buffer += srcx + srcy * srccx; + for(; y < endy; y++, buffer += lg) + for(x=srcx; x < endx; x++) + lld_lcdWriteData(*buffer++); lld_lcdWriteStreamStop(); lld_lcdResetViewPort(); } #endif -/* Circular Drawing Functions */ -#if (GDISP_NEED_CIRCLE && GDISP_HARDWARE_CIRCLES) || defined(__DOXYGEN__) - /** - * @brief Draw a circle. - * @note Optional - The high level driver can emulate using software. - * @note If GDISP_NEED_CLIPPING is defined this routine MUST behave - * correctly if the circle is over the edges of the screen. - * - * @param[in] x, y The centre of the circle - * @param[in] radius The radius of the circle - * @param[in] color The color of the circle - * - * @notapi - */ - void GDISP_LLD(drawcircle)(coord_t x, coord_t y, coord_t radius, color_t color) { - /* NOT IMPLEMENTED */ - } -#endif - -#if (GDISP_NEED_CIRCLE && GDISP_HARDWARE_CIRCLEFILLS) || defined(__DOXYGEN__) - /** - * @brief Create a filled circle. - * @note Optional - The high level driver can emulate using software. - * @note If GDISP_NEED_CLIPPING is defined this routine MUST behave - * correctly if the circle is over the edges of the screen. - * - * @param[in] x, y The centre of the circle - * @param[in] radius The radius of the circle - * @param[in] color The color of the circle - * - * @notapi - */ - void GDISP_LLD(fillcircle)(coord_t x, coord_t y, coord_t radius, color_t color) { - /* NOT IMPLEMENTED */ - } -#endif - -#if (GDISP_NEED_ELLIPSE && GDISP_HARDWARE_ELLIPSES) || defined(__DOXYGEN__) - /** - * @brief Draw an ellipse. - * @note Optional - The high level driver can emulate using software. - * @note If GDISP_NEED_CLIPPING is defined this routine MUST behave - * correctly if the ellipse is over the edges of the screen. - * - * @param[in] x, y The centre of the ellipse - * @param[in] a, b The dimensions of the ellipse - * @param[in] color The color of the ellipse - * - * @notapi - */ - void GDISP_LLD(drawellipse)(coord_t x, coord_t y, coord_t a, coord_t b, color_t color) { - /* NOT IMPLEMENTED */ - } -#endif - -#if (GDISP_NEED_ELLIPSE && GDISP_HARDWARE_ELLIPSEFILLS) || defined(__DOXYGEN__) - /** - * @brief Create a filled ellipse. - * @note Optional - The high level driver can emulate using software. - * @note If GDISP_NEED_CLIPPING is defined this routine MUST behave - * correctly if the ellipse is over the edges of the screen. - * - * @param[in] x, y The centre of the ellipse - * @param[in] a, b The dimensions of the ellipse - * @param[in] color The color of the ellipse - * - * @notapi - */ - void GDISP_LLD(fillellipse)(coord_t x, coord_t y, coord_t a, coord_t b, color_t color) { - /* NOT IMPLEMENTED */ - } -#endif - -#if (GDISP_NEED_TEXT && GDISP_HARDWARE_TEXT) || defined(__DOXYGEN__) - #include "gdisp_fonts.h" -#endif - -#if (GDISP_NEED_TEXT && GDISP_HARDWARE_TEXT) || defined(__DOXYGEN__) - /** - * @brief Draw a character using a transparent background. - * @note Optional - The high level driver can emulate using software. - * - * @param[in] x, y The top-left corner of the text - * @param[in] c The character to print - * @param[in] color The color of the character - * - * @notapi - */ - void GDISP_LLD(drawchar)(coord_t x, coord_t y, char c, font_t font, color_t color) { - /* NOT IMPLEMENTED */ - } -#endif - -#if (GDISP_NEED_TEXT && GDISP_HARDWARE_TEXTFILLS) || defined(__DOXYGEN__) - /** - * @brief Draw a character using a filled background. - * @note Optional - The high level driver can emulate using software. - * - * @param[in] x, y The top-left corner of the text - * @param[in] c The character to print - * @param[in] color The color of the character - * @param[in] bgcolor The background color - * - * @notapi - */ - void GDISP_LLD(fillchar)(coord_t x, coord_t y, char c, font_t font, color_t color, color_t bgcolor) { - /* NOT IMPLEMENTED */ - } -#endif - #if (GDISP_NEED_PIXELREAD && GDISP_HARDWARE_PIXELREAD) || defined(__DOXYGEN__) /** * @brief Get the color of a particular pixel. @@ -399,8 +276,8 @@ void GDISP_LLD(drawpixel)(coord_t x, coord_t y, color_t color) { color_t GDISP_LLD(getpixelcolor)(coord_t x, coord_t y) { color_t color; - #if GDISP_NEED_VALIDATION - if (x >= GDISP.Width || y >= GDISP.Height) return 0; + #if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP + if (x < 0 || x >= GDISP.Width || y < 0 || y >= GDISP.Height) return 0; #endif lld_lcdSetCursor(x, y); @@ -434,15 +311,16 @@ void GDISP_LLD(drawpixel)(coord_t x, coord_t y, color_t color) { coord_t row0, row1; unsigned i, gap, abslines; - abslines = lines < 0 ? -lines : lines; - - #if GDISP_NEED_VALIDATION - if (cx < 1 || cy < 1 || x >= GDISP.Width || y >= GDISP.Height) return; - if (x+cx > GDISP.Width) cx = GDISP.Width - x; - if (y+cy > GDISP.Height) cy = GDISP.Height - y; + #if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP + if (x < GDISP.clipx0) { cx -= GDISP.clipx0 - x; x = GDISP.clipx0; } + if (y < GDISP.clipy0) { cy -= GDISP.clipy0 - y; y = GDISP.clipy0; } + if (!lines || cx <= 0 || cy <= 0 || x >= GDISP.clipx1 || y >= GDISP.clipy1) return; + if (x+cx > GDISP.clipx1) cx -= GDISP.clipx1 - x; + if (y+cy > GDISP.clipy1) cy = GDISP.clipy1 - y; #endif - if (!abslines) return; + abslines = lines < 0 ? -lines : lines; + if (abslines >= cy) { abslines = cy; gap = 0; @@ -560,6 +438,12 @@ void GDISP_LLD(drawpixel)(coord_t x, coord_t y, color_t color) { default: return; } + #if GDISP_NEED_CLIP || GDISP_NEED_VALIDATION + GDISP.clipx0 = 0; + GDISP.clipy0 = 0; + GDISP.clipx1 = GDISP.Width; + GDISP.clipy1 = GDISP.Height; + #endif GDISP.Orientation = (gdisp_orientation_t)value; return; /* @@ -570,37 +454,5 @@ void GDISP_LLD(drawpixel)(coord_t x, coord_t y, color_t color) { } #endif -#if (GDISP_NEED_QUERY && GDISP_HARDWARE_QUERY) || defined(__DOXYGEN__) -/** - * @brief Query a driver value. - * @detail Typecase the result to the type you want. - * @note GDISP_QUERY_WIDTH - (coord_t) Gets the width of the screen - * GDISP_QUERY_HEIGHT - (coord_t) Gets the height of the screen - * GDISP_QUERY_POWER - (gdisp_powermode_t) Get the current powermode - * GDISP_QUERY_ORIENTATION - (gdisp_orientation_t) Get the current screen orientation - * GDISP_QUERY_BACKLIGHT - (coord_t) Get the backlight state (0 to 100) - * GDISP_QUERY_CONTRAST - (coord_t) Get the contrast (0 to 100). - * GDISP_QUERY_LLD - Low level driver control constants start at - * this value. - * - * @param[in] what What to Query - * - * @notapi - */ -void *GDISP_LLD(query)(unsigned what) { - switch(what) { - case GDISP_QUERY_WIDTH: return (void *)(unsigned)GDISP.Width; - case GDISP_QUERY_HEIGHT: return (void *)(unsigned)GDISP.Height; - case GDISP_QUERY_POWER: return (void *)(unsigned)GDISP.Powermode; - case GDISP_QUERY_ORIENTATION: return (void *)(unsigned)GDISP.Orientation; - case GDISP_QUERY_BACKLIGHT: return (void *)(unsigned)GDISP.Backlight; - case GDISP_QUERY_CONTRAST: return (void *)(unsigned)GDISP.Contrast; - case GDISP_QUERY_LLD+0: - /* Code here */ - default: return (void *)-1; - } -} -#endif - #endif /* HAL_USE_GDISP */ /** @} */ diff --git a/drivers/gdisp/SSD1289/gdisp_lld_config.h b/drivers/gdisp/SSD1289/gdisp_lld_config.h index 123ce875..7311c7ba 100644 --- a/drivers/gdisp/SSD1289/gdisp_lld_config.h +++ b/drivers/gdisp/SSD1289/gdisp_lld_config.h @@ -38,27 +38,14 @@ #define GDISP_DRIVER_NAME "SSD1289" #define GDISP_LLD(x) gdisp_lld_##x##_SSD1289 -#define GDISP_HARDWARE_LINES FALSE #define GDISP_HARDWARE_CLEARS TRUE #define GDISP_HARDWARE_FILLS TRUE #define GDISP_HARDWARE_BITFILLS TRUE -#define GDISP_HARDWARE_CIRCLES FALSE -#define GDISP_HARDWARE_CIRCLEFILLS FALSE -#define GDISP_HARDWARE_ELLIPSES FALSE -#define GDISP_HARDWARE_ELLIPSEFILLS FALSE -#define GDISP_HARDWARE_TEXT FALSE -#define GDISP_HARDWARE_TEXTFILLS FALSE #define GDISP_HARDWARE_SCROLL TRUE #define GDISP_HARDWARE_PIXELREAD TRUE #define GDISP_HARDWARE_CONTROL TRUE -#define GDISP_HARDWARE_QUERY FALSE - -#define GDISP_SOFTWARE_TEXTFILLDRAW FALSE -#define GDISP_SOFTWARE_TEXTBLITCOLUMN FALSE #define GDISP_PIXELFORMAT GDISP_PIXELFORMAT_RGB565 -#define GDISP_PACKED_PIXELS FALSE -#define GDISP_PACKED_LINES FALSE #endif /* HAL_USE_GDISP */ diff --git a/drivers/gdisp/SSD1963/gdisp_lld.c b/drivers/gdisp/SSD1963/gdisp_lld.c index 2d8bacce..63d5f6b2 100644 --- a/drivers/gdisp/SSD1963/gdisp_lld.c +++ b/drivers/gdisp/SSD1963/gdisp_lld.c @@ -1,771 +1,565 @@ -/* - ChibiOS-LCD-Driver - Copyright (C) 2012 - Joel Bodenmann aka Tectu - - This file is part of ChibiOS-LCD-Driver. - - ChibiOS-LCD-Driver is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - ChibiOS-LCD-Driver is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -/** - * @file SSD1963/gdisp_lld.c - * @brief GDISP Graphics Driver subsystem low level driver source. - * - * @addtogroup GDISP - * @{ - */ - -#include "ch.h" -#include "hal.h" -#include "gdisp.h" - -#if HAL_USE_GDISP || defined(__DOXYGEN__) - -/* Include the emulation code for things we don't support */ -#include "gdisp_emulation.c" - -/*===========================================================================*/ -/* Driver local definitions. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver exported variables. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver local variables. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver local functions. */ -/*===========================================================================*/ - -#if GDISP_NEED_TEXT - #include "gdisp_fonts.h" -#endif - -/* All the board specific code should go in these include file so the driver - * can be ported to another board just by creating a suitable file. - */ -#if defined(BOARD_YOURBOARDNAME) - #include "gdisp_lld_board_yourboardname.h" -#else - /* Include the user supplied board definitions */ - #include "gdisp_lld_board.h" -#endif - -/*===========================================================================*/ -/* Driver interrupt handlers. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver exported functions. */ -/*===========================================================================*/ - -#include "ssd1963.h" - - -#if defined(LCD_USE_FSMC) -__inline void GDISP_LLD(writeindex)(uint8_t cmd) { - LCD_REG = cmd; -} - -__inline void GDISP_LLD(writereg)(uint16_t lcdReg,uint16_t lcdRegValue) { - LCD_REG = lcdReg; - LCD_RAM = lcdRegValue; -} - -__inline void GDISP_LLD(writedata)(uint16_t data) { - LCD_RAM = data; -} - -__inline uint16_t GDISP_LLD(readdata)(void) { - return (LCD_RAM); -} - -__inline uint8_t GDISP_LLD(readreg)(uint8_t lcdReg) { - LCD_REG = lcdReg; - return (LCD_RAM); -} - -__inline void GDISP_LLD(writestreamstart)(void) { - GDISP_LLD(writeindex)(SSD1963_WRITE_MEMORY_START); -} - -__inline void GDISP_LLD(readstreamstart)(void) { - GDISP_LLD(writeindex)(SSD1963_READ_MEMORY_START); -} - -__inline void GDISP_LLD(writestream)(uint16_t *buffer, uint16_t size) { - uint16_t i; - for(i = 0; i < size; i++) - LCD_RAM = buffer[i]; -} - -__inline void GDISP_LLD(readstream)(uint16_t *buffer, size_t size) { - uint16_t i; - - for(i = 0; i < size; i++) { - buffer[i] = LCD_RAM; - } -} - -#elif defined(LCD_USE_GPIO) - -__inline void GDISP_LLD(writeindex)(uint8_t cmd) { - Set_CS; Set_RS; Set_WR; Clr_RD; - palWritePort(LCD_DATA_PORT, cmd); - Clr_CS; -} - -__inline void GDISP_LLD(writereg)(uint16_t lcdReg,uint16_t lcdRegValue) { - Set_CS; Set_RS; Set_WR; Clr_RD; - palWritePort(LCD_DATA_PORT, lcdReg); - Clr_RS; - palWritePort(LCD_DATA_PORT, lcdRegValue); - Clr_CS; -} -__inline void GDISP_LLD(writedata)(uint16_t data) { - Set_CS; Clr_RS; Set_WR; Clr_RD; - palWritePort(LCD_DATA_PORT, data); - Clr_CS; -} - -__inline uint16_t GDISP_LLD(readdata)(void) { - Set_CS; Clr_RS; Clr_WR; Set_RD; - uint16_t data = palReadPort(LCD_DATA_PORT); - Clr_CS; - return data; -} - -__inline uint8_t GDISP_LLD(readreg)(uint8_t lcdReg) { - Set_CS; Set_RS; Clr_WR; Set_RD; - palWritePort(LCD_DATA_PORT, lcdReg); - Clr_RS; - uint16_t data = palReadPort(LCD_DATA_PORT); - Clr_CS; - return data; -} - -__inline void GDISP_LLD(writestreamstart)(void) { - GDISP_LLD(writeindex)(SSD1963_WRITE_MEMORY_START); -} - -__inline void GDISP_LLD(readstreamstart)(void) { - GDISP_LLD(writeindex)(SSD1963_READ_MEMORY_START); -} - -__inline void GDISP_LLD(writestream)(uint16_t *buffer, uint16_t size) { - uint16_t i; - Set_CS; Clr_RS; Set_WR; Clr_RD; - for(i = 0; i < size; i++) { - Set_WR; - palWritePort(LCD_DATA_PORT, buffer[i]); - Clr_WR; - } - Clr_CS; -} - -__inline void GDISP_LLD(readstream)(uint16_t *buffer, size_t size) { - uint16_t i; - Set_CS; Clr_RS; Clr_WR; Set_RD; - for(i = 0; i < size; i++) { - Set_RD; - buffer[i] = palReadPort(LCD_DATA_PORT); - Clr_RD; - } -} -#endif - -/* ---- Required Routines ---- */ -/* - The following 2 routines are required. - All other routines are optional. -*/ - -/** - * @brief Low level GDISP driver initialisation. - * @return TRUE if successful, FALSE on error. - * - * @notapi - */ -bool_t GDISP_LLD(init)(void) { - /* Initialise your display */ - - /* Initialise the GDISP structure to match */ - GDISP.Width = SCREEN_WIDTH; - GDISP.Height = SCREEN_HEIGHT; - GDISP.Orientation = landscape; - GDISP.Powermode = powerOn; - GDISP.Backlight = 100; - GDISP.Contrast = 50; - -#if defined(LCD_USE_FSMC) - - #if defined(STM32F1XX) || defined(STM32F3XX) - /* FSMC setup for F1/F3 */ - rccEnableAHB(RCC_AHBENR_FSMCEN, 0); - - #elif defined(STM32F4XX) || defined(STM32F2XX) - /* STM32F2-F4 FSMC init */ - rccEnableAHB3(RCC_AHB3ENR_FSMCEN, 0); - #else - #error "FSMC not implemented for this device" - #endif - - /* set pins to FSMC mode */ - IOBus busD = {GPIOD, (1 << 0) | (1 << 1) | (1 << 4) | (1 << 5) | (1 << 7) | (1 << 8) | - (1 << 9) | (1 << 10) | (1 << 11) | (1 << 14) | (1 << 15), 0}; - - IOBus busE = {GPIOE, (1 << 7) | (1 << 8) | (1 << 9) | (1 << 10) | (1 << 11) | (1 << 12) | - (1 << 13) | (1 << 14) | (1 << 15), 0}; - - palSetBusMode(&busD, PAL_MODE_ALTERNATE(12)); - palSetBusMode(&busE, PAL_MODE_ALTERNATE(12)); - - const unsigned char FSMC_Bank = 0; - /* FSMC timing */ - FSMC_Bank1->BTCR[FSMC_Bank+1] = (FSMC_BTR1_ADDSET_1 | FSMC_BTR1_ADDSET_3) \ - | (FSMC_BTR1_DATAST_1 | FSMC_BTR1_DATAST_3) \ - | (FSMC_BTR1_BUSTURN_1 | FSMC_BTR1_BUSTURN_3) ; - - /* Bank1 NOR/SRAM control register configuration - * This is actually not needed as already set by default after reset */ - FSMC_Bank1->BTCR[FSMC_Bank] = FSMC_BCR1_MWID_0 | FSMC_BCR1_WREN | FSMC_BCR1_MBKEN; - - #elif defined(LCD_USE_GPIO) - IOBus busCMD = {LCD_CMD_PORT, (1 << LCD_CS) | (1 << LCD_RS) | (1 << LCD_WR) | (1 << LCD_RD), 0}; - IOBus busDATA = {LCD_CMD_PORT, 0xFFFFF, 0}; - palSetBusMode(&busCMD, PAL_MODE_OUTPUT_PUSHPULL); - palSetBusMode(&busDATA, PAL_MODE_OUTPUT_PUSHPULL); - - #else - #error "Please define LCD_USE_FSMC or LCD_USE_GPIO" -#endif - GDISP_LLD(writeindex)(SSD1963_SOFT_RESET); - chThdSleepMicroseconds(100); - - /* Driver PLL config */ - GDISP_LLD(writeindex)(SSD1963_SET_PLL_MN); - GDISP_LLD(writedata)(35); // PLLclk = REFclk (10Mhz) * 36 (360Mhz) - GDISP_LLD(writedata)(2); // SYSclk = PLLclk / 3 (120MHz) - GDISP_LLD(writedata)(4); // Apply calculation bit, else it is ignored - - GDISP_LLD(writeindex)(SSD1963_SET_PLL); // Enable PLL - GDISP_LLD(writedata)(0x01); - chThdSleepMicroseconds(200); - - GDISP_LLD(writeindex)(SSD1963_SET_PLL); // Use PLL - GDISP_LLD(writedata)(0x03); - chThdSleepMicroseconds(200); - - GDISP_LLD(writeindex)(SSD1963_SOFT_RESET); - chThdSleepMicroseconds(100); - - /* Screen size */ - GDISP_LLD(writeindex)(SSD1963_SET_LCD_MODE); -// GDISP_LLD(writedata)(0x0000); - GDISP_LLD(writedata)(0b00011000); - GDISP_LLD(writedata)(0x0000); - GDISP_LLD(writedata)(mHIGH((SCREEN_WIDTH+1))); - GDISP_LLD(writedata)((SCREEN_WIDTH+1)); - GDISP_LLD(writedata)(mHIGH((SCREEN_HEIGHT+1))); - GDISP_LLD(writedata)((SCREEN_HEIGHT+1)); - GDISP_LLD(writedata)(0x0000); - - GDISP_LLD(writeindex)(SSD1963_SET_PIXEL_DATA_INTERFACE); - GDISP_LLD(writedata)(SSD1963_PDI_16BIT565); - - /* LCD Clock specs */ - GDISP_LLD(writeindex)(SSD1963_SET_LSHIFT_FREQ); - GDISP_LLD(writedata)((LCD_FPR >> 16) & 0xFF); - GDISP_LLD(writedata)((LCD_FPR >> 8) & 0xFF); - GDISP_LLD(writedata)(LCD_FPR & 0xFF); - - GDISP_LLD(writeindex)(SSD1963_SET_HORI_PERIOD); - GDISP_LLD(writedata)(mHIGH(SCREEN_HSYNC_PERIOD)); - GDISP_LLD(writedata)(mLOW(SCREEN_HSYNC_PERIOD)); - GDISP_LLD(writedata)(mHIGH((SCREEN_HSYNC_PULSE + SCREEN_HSYNC_BACK_PORCH))); - GDISP_LLD(writedata)(mLOW((SCREEN_HSYNC_PULSE + SCREEN_HSYNC_BACK_PORCH))); - GDISP_LLD(writedata)(SCREEN_HSYNC_PULSE); - GDISP_LLD(writedata)(0x00); - GDISP_LLD(writedata)(0x00); - GDISP_LLD(writedata)(0x00); - - GDISP_LLD(writeindex)(SSD1963_SET_VERT_PERIOD); - GDISP_LLD(writedata)(mHIGH(SCREEN_VSYNC_PERIOD)); - GDISP_LLD(writedata)(mLOW(SCREEN_VSYNC_PERIOD)); - GDISP_LLD(writedata)(mHIGH((SCREEN_VSYNC_PULSE + SCREEN_VSYNC_BACK_PORCH))); - GDISP_LLD(writedata)(mLOW((SCREEN_VSYNC_PULSE + SCREEN_VSYNC_BACK_PORCH))); - GDISP_LLD(writedata)(SCREEN_VSYNC_PULSE); - GDISP_LLD(writedata)(0x00); - GDISP_LLD(writedata)(0x00); - - /* Tear effect indicator ON. This is used to tell the host MCU when the driver is not refreshing the panel */ - GDISP_LLD(writeindex)(SSD1963_SET_TEAR_ON); - GDISP_LLD(writedata)(0x0000); - - /* Turn on */ - GDISP_LLD(writeindex)(SSD1963_SET_DISPLAY_ON); -#if defined(LCD_USE_FSMC) - /* FSMC delay reduced as the controller now runs at full speed */ - FSMC_Bank1->BTCR[FSMC_Bank+1] = FSMC_BTR1_ADDSET_0 | FSMC_BTR1_DATAST_2 | FSMC_BTR1_BUSTURN_0 ; - FSMC_Bank1->BTCR[FSMC_Bank] = FSMC_BCR1_MWID_0 | FSMC_BCR1_WREN | FSMC_BCR1_MBKEN; -#endif - - return TRUE; -} - -void GDISP_LLD(setwindow)(coord_t x0, coord_t y0, coord_t x1, coord_t y1) { - #if GDISP_NEED_VALIDATION - if (x0 >= GDISP.Width || y0 >= GDISP.Height) return; - else if (x1 >= GDISP.Width || y1 >= GDISP.Height) return; - #endif - GDISP_LLD(writeindex)(SSD1963_SET_PAGE_ADDRESS); - GDISP_LLD(writedata)((y0 >> 8) & 0xFF); - GDISP_LLD(writedata)((y0 >> 0) & 0xFF); - GDISP_LLD(writedata)((y1 >> 8) & 0xFF); - GDISP_LLD(writedata)((y1 >> 0) & 0xFF); - GDISP_LLD(writeindex)(SSD1963_SET_COLUMN_ADDRESS); - GDISP_LLD(writedata)((x0 >> 8) & 0xFF); - GDISP_LLD(writedata)((x0 >> 0) & 0xFF); - GDISP_LLD(writedata)((x1 >> 8) & 0xFF); - GDISP_LLD(writedata)((x1 >> 0) & 0xFF); -} - -/** - * @brief Draws a pixel on the display. - * - * @param[in] x X location of the pixel - * @param[in] y Y location of the pixel - * @param[in] color The color of the pixel - * - * @notapi - */ -void GDISP_LLD(drawpixel)(coord_t x, coord_t y, color_t color) { - #if GDISP_NEED_VALIDATION - if (x >= GDISP.Width || y >= GDISP.Height) return; - #endif - - GDISP_LLD(setwindow)(x, y, x, y); - GDISP_LLD(writestreamstart)(); - GDISP_LLD(writedata)(color); -} - -/* ---- Optional Routines ---- */ -/* - All the below routines are optional. - Defining them will increase speed but everything - will work if they are not defined. - If you are not using a routine - turn it off using - the appropriate GDISP_HARDWARE_XXXX macro. - Don't bother coding for obvious similar routines if - there is no performance penalty as the emulation software - makes a good job of using similar routines. - eg. If fillarea() is defined there is little - point in defining clear() unless the - performance bonus is significant. - For good performance it is suggested to implement - fillarea() and blitarea(). -*/ - -#if GDISP_HARDWARE_CLEARS || defined(__DOXYGEN__) - /** - * @brief Clear the display. - * @note Optional - The high level driver can emulate using software. - * - * @param[in] color The color of the pixel - * - * @notapi - */ - void GDISP_LLD(clear)(color_t color) { - GDISP_LLD(fillarea)(0, 0, GDISP.Width-1, GDISP.Height-1, color); - } -#endif - -#if GDISP_HARDWARE_LINES || defined(__DOXYGEN__) - /** - * @brief Draw a line. - * @note Optional - The high level driver can emulate using software. - * - * @param[in] x0, y0 The start of the line - * @param[in] x1, y1 The end of the line - * @param[in] color The color of the line - * - * @notapi - */ - void GDISP_LLD(drawline)(coord_t x0, coord_t y0, coord_t x1, coord_t y1, color_t color) { - #if GDISP_NEED_VALIDATION - /* Need to clip to screen */ - #endif - /* Code here */ - } -#endif - -#if GDISP_HARDWARE_FILLS || defined(__DOXYGEN__) - /** - * @brief Fill an area with a color. - * @note Optional - The high level driver can emulate using software. - * - * @param[in] x, y The start filled area - * @param[in] cx, cy The width and height to be filled - * @param[in] color The color of the fill - * - * @notapi - */ - void GDISP_LLD(fillarea)(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color) { - #if GDISP_NEED_VALIDATION - if (cx < 1 || cy < 1 || x >= GDISP.Width || y >= GDISP.Height) return; - if (x+cx > GDISP.Width) cx = GDISP.Width - x; - if (y+cy > GDISP.Height) cy = GDISP.Height - y; - #endif - - uint32_t index = 0, area; - area = (cx+1)*(cy+1); - - GDISP_LLD(setwindow)(x, y, x+cx, y+cy); - GDISP_LLD(writestreamstart)(); - - for(index = 0; index <= area; index++) - GDISP_LLD(writedata)(color); - - } -#endif - -#if GDISP_HARDWARE_BITFILLS || defined(__DOXYGEN__) - /** - * @brief Fill an area with a bitmap. - * @note Optional - The high level driver can emulate using software. - * - * @param[in] x, y The start filled area - * @param[in] cx, cy The width and height to be filled - * @param[in] buffer The pixels to use to fill the area. - * - * @notapi - */ - void GDISP_LLD(blitarea)(coord_t x, coord_t y, coord_t cx, coord_t cy, const pixel_t *buffer) { - #if GDISP_NEED_VALIDATION - if (cx < 1 || cy < 1 || x >= GDISP.Width || y >= GDISP.Height) return; - if (x+cx > GDISP.Width) return; - if (y+cy > GDISP.Height) cy = GDISP.Height - y; - #endif - /* Code here */ - } -#endif - -/* Circular Drawing Functions */ -#if (GDISP_NEED_CIRCLE && GDISP_HARDWARE_CIRCLES) || defined(__DOXYGEN__) - /** - * @brief Draw a circle. - * @note Optional - The high level driver can emulate using software. - * @note If GDISP_NEED_CLIPPING is defined this routine MUST behave - * correctly if the circle is over the edges of the screen. - * - * @param[in] x, y The centre of the circle - * @param[in] radius The radius of the circle - * @param[in] color The color of the circle - * - * @notapi - */ - void GDISP_LLD(drawcircle)(coord_t x, coord_t y, coord_t radius, color_t color) { - #if GDISP_NEED_VALIDATION - /* Code here */ - #endif - /* Code here */ - } -#endif - -#if (GDISP_NEED_CIRCLE && GDISP_HARDWARE_CIRCLEFILLS) || defined(__DOXYGEN__) - /** - * @brief Create a filled circle. - * @note Optional - The high level driver can emulate using software. - * @note If GDISP_NEED_CLIPPING is defined this routine MUST behave - * correctly if the circle is over the edges of the screen. - * - * @param[in] x, y The centre of the circle - * @param[in] radius The radius of the circle - * @param[in] color The color of the circle - * - * @notapi - */ - void GDISP_LLD(fillcircle)(coord_t x, coord_t y, coord_t radius, color_t color) { - #if GDISP_NEED_VALIDATION - /* Code here */ - #endif - /* Code here */ - } -#endif - -#if (GDISP_NEED_ELLIPSE && GDISP_HARDWARE_ELLIPSES) || defined(__DOXYGEN__) - /** - * @brief Draw an ellipse. - * @note Optional - The high level driver can emulate using software. - * @note If GDISP_NEED_CLIPPING is defined this routine MUST behave - * correctly if the ellipse is over the edges of the screen. - * - * @param[in] x, y The centre of the ellipse - * @param[in] a, b The dimensions of the ellipse - * @param[in] color The color of the ellipse - * - * @notapi - */ - void GDISP_LLD(drawellipse)(coord_t x, coord_t y, coord_t a, coord_t b, color_t color) { - #if GDISP_NEED_VALIDATION - /* Code here */ - #endif - /* Code here */ - } -#endif - -#if (GDISP_NEED_ELLIPSE && GDISP_HARDWARE_ELLIPSEFILLS) || defined(__DOXYGEN__) - /** - * @brief Create a filled ellipse. - * @note Optional - The high level driver can emulate using software. - * @note If GDISP_NEED_CLIPPING is defined this routine MUST behave - * correctly if the ellipse is over the edges of the screen. - * - * @param[in] x, y The centre of the ellipse - * @param[in] a, b The dimensions of the ellipse - * @param[in] color The color of the ellipse - * - * @notapi - */ - void GDISP_LLD(fillellipse)(coord_t x, coord_t y, coord_t a, coord_t b, color_t color) { - #if GDISP_NEED_VALIDATION - /* Code here */ - #endif - /* Code here */ - } -#endif - -#if (GDISP_NEED_TEXT && GDISP_HARDWARE_TEXT) || defined(__DOXYGEN__) - /** - * @brief Draw a character using a transparent background. - * @note Optional - The high level driver can emulate using software. - * - * @param[in] x, y The top-left corner of the text - * @param[in] c The character to print - * @param[in] color The color of the character - * - * @notapi - */ - void GDISP_LLD(drawchar)(coord_t x, coord_t y, char c, font_t font, color_t color) { - #if GDISP_NEED_VALIDATION - /* Code here */ - #endif - /* Code here */ - } -#endif - -#if (GDISP_NEED_TEXT && GDISP_HARDWARE_TEXTFILLS) || defined(__DOXYGEN__) - /** - * @brief Draw a character using a filled background. - * @note Optional - The high level driver can emulate using software. - * - * @param[in] x, y The top-left corner of the text - * @param[in] c The character to print - * @param[in] color The color of the character - * @param[in] bgcolor The background color - * - * @notapi - */ - void GDISP_LLD(fillchar)(coord_t x, coord_t y, char c, font_t font, color_t color, color_t bgcolor) { - #if GDISP_NEED_VALIDATION - /* Code here */ - #endif - /* Code here */ - } -#endif - -#if (GDISP_NEED_PIXELREAD && GDISP_HARDWARE_PIXELREAD) || defined(__DOXYGEN__) - /** - * @brief Get the color of a particular pixel. - * @note Optional. - * @note If x,y is off the screen, the result is undefined. - * @return The color of the specified pixel. - * - * @param[in] x, y The start of the text - * - * @notapi - */ - color_t GDISP_LLD(getpixelcolor)(coord_t x, coord_t y) { - #if GDISP_NEED_VALIDATION - if (x >= GDISP.Width || y >= GDISP.Height) return 0; - #endif - /* Code here */ - } -#endif - -#if (GDISP_NEED_SCROLL && GDISP_HARDWARE_SCROLL) || defined(__DOXYGEN__) - /** - * @brief Scroll vertically a section of the screen. - * @note Optional. - * @note If x,y + cx,cy is off the screen, the result is undefined. - * @note If lines is >= cy, it is equivelent to a area fill with bgcolor. - * - * @param[in] x, y The start of the area to be scrolled - * @param[in] cx, cy The size of the area to be scrolled - * @param[in] lines The number of lines to scroll (Can be positive or negative) - * @param[in] bgcolor The color to fill the newly exposed area. - * - * @notapi - */ - void GDISP_LLD(verticalscroll)(coord_t x, coord_t y, coord_t cx, coord_t cy, int lines, color_t bgcolor) { - #if GDISP_NEED_VALIDATION - if (cx < 1 || cy < 1 || x >= GDISP.Width || y >= GDISP.Height) return; - if (x+cx > GDISP.Width) cx = GDISP.Width - x; - if (y+cy > GDISP.Height) cy = GDISP.Height - y; - #endif - /* Code here */ - - /* - uint16_t size = x1 - x0 ; - - lld_lcdWriteIndex(SSD1963_SET_SCROLL_AREA); - lld_lcdWriteData((x0 >> 8) & 0xFF); - lld_lcdWriteData((x0 >> 0) & 0xFF); - lld_lcdWriteData((size >> 8) & 0xFF); - lld_lcdWriteData((size >> 0) & 0xFF); - lld_lcdWriteData(((lcd_height-x1) >> 8) & 0xFF); - lld_lcdWriteData(((lcd_height-x1) >> 0) & 0xFF); - - lld_lcdWriteIndex(SSD1963_SET_SCROLL_START); - lld_lcdWriteData((lines >> 8) & 0xFF); - lld_lcdWriteData((lines >> 0) & 0xFF); - */ - } - -#endif - -#if (GDISP_NEED_CONTROL && GDISP_HARDWARE_CONTROL) || defined(__DOXYGEN__) - /** - * @brief Driver Control - * @detail Unsupported control codes are ignored. - * @note The value parameter should always be typecast to (void *). - * @note There are some predefined and some specific to the low level driver. - * @note GDISP_CONTROL_POWER - Takes a gdisp_powermode_t - * GDISP_CONTROL_ORIENTATION - Takes a gdisp_orientation_t - * GDISP_CONTROL_BACKLIGHT - Takes an int from 0 to 100. For a driver - * that only supports off/on anything other - * than zero is on. - * GDISP_CONTROL_CONTRAST - Takes an int from 0 to 100. - * GDISP_CONTROL_LLD - Low level driver control constants start at - * this value. - * - * @param[in] what What to do. - * @param[in] value The value to use (always cast to a void *). - * - * @notapi - */ - void GDISP_LLD(control)(unsigned what, void *value) { - switch(what) { - case GDISP_CONTROL_POWER: - if (GDISP.Powermode == (gdisp_powermode_t)value) - return; - switch((gdisp_powermode_t)value) { - case powerOff: - GDISP_LLD(writeindex)(SSD1963_EXIT_SLEEP_MODE); // leave sleep mode - chThdSleepMicroseconds(5000); - GDISP_LLD(writeindex)(SSD1963_SET_DISPLAY_OFF); - GDISP_LLD(writeindex)(SSD1963_SET_DEEP_SLEEP); // enter deep sleep mode - break; - case powerOn: - GDISP_LLD(readreg)(0x0000); chThdSleepMicroseconds(5000); // 2x Dummy reads to wake up from deep sleep - GDISP_LLD(readreg)(0x0000); chThdSleepMicroseconds(5000); - if (GDISP.Powermode != powerSleep) - GDISP_LLD(init)(); - GDISP_LLD(writeindex)(SSD1963_SET_DISPLAY_ON); - - break; - case powerSleep: - GDISP_LLD(writeindex)(SSD1963_SET_DISPLAY_OFF); - GDISP_LLD(writeindex)(SSD1963_ENTER_SLEEP_MODE); // enter sleep mode - chThdSleepMicroseconds(5000); - break; - default: - return; - } - GDISP.Powermode = (gdisp_powermode_t)value; - return; - case GDISP_CONTROL_ORIENTATION: - if (GDISP.Orientation == (gdisp_orientation_t)value) - return; - switch((gdisp_orientation_t)value) { - case portrait: - /* Code here */ - GDISP.Height = SCREEN_HEIGHT; - GDISP.Width = SCREEN_WIDTH; - break; - case landscape: - /* Code here */ - GDISP.Height = SCREEN_WIDTH; - GDISP.Width = SCREEN_HEIGHT; - break; - case portraitInv: - /* Code here */ - GDISP.Height = SCREEN_HEIGHT; - GDISP.Width = SCREEN_WIDTH; - break; - case landscapeInv: - /* Code here */ - GDISP.Height = SCREEN_WIDTH; - GDISP.Width = SCREEN_HEIGHT; - break; - default: - return; - } - GDISP.Orientation = (gdisp_orientation_t)value; - return; -/* - case GDISP_CONTROL_BACKLIGHT: - case GDISP_CONTROL_CONTRAST: -*/ - } - } -#endif - -#if (GDISP_NEED_QUERY && GDISP_HARDWARE_QUERY) || defined(__DOXYGEN__) -/** - * @brief Query a driver value. - * @detail Typecase the result to the type you want. - * @note GDISP_QUERY_WIDTH - (coord_t) Gets the width of the screen - * GDISP_QUERY_HEIGHT - (coord_t) Gets the height of the screen - * GDISP_QUERY_POWER - (gdisp_powermode_t) Get the current powermode - * GDISP_QUERY_ORIENTATION - (gdisp_orientation_t) Get the current screen orientation - * GDISP_QUERY_BACKLIGHT - (coord_t) Get the backlight state (0 to 100) - * GDISP_QUERY_CONTRAST - (coord_t) Get the contrast (0 to 100). - * GDISP_QUERY_LLD - Low level driver control constants start at - * this value. - * - * @param[in] what What to Query - * - * @notapi - */ -void *GDISP_LLD(query)(unsigned what) { - switch(what) { - case GDISP_QUERY_WIDTH: return (void *)(unsigned)GDISP.Width; - case GDISP_QUERY_HEIGHT: return (void *)(unsigned)GDISP.Height; - case GDISP_QUERY_POWER: return (void *)(unsigned)GDISP.Powermode; - case GDISP_QUERY_ORIENTATION: return (void *)(unsigned)GDISP.Orientation; - case GDISP_QUERY_BACKLIGHT: return (void *)(unsigned)GDISP.Backlight; - case GDISP_QUERY_CONTRAST: return (void *)(unsigned)GDISP.Contrast; - case GDISP_QUERY_LLD+0: - /* Code here */ - default: return (void *)-1; - } -} -#endif - -#endif /* HAL_USE_GDISP */ -/** @} */ +/* + ChibiOS-LCD-Driver - Copyright (C) 2012 + Joel Bodenmann aka Tectu + + This file is part of ChibiOS-LCD-Driver. + + ChibiOS-LCD-Driver is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS-LCD-Driver is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file SSD1963/gdisp_lld.c + * @brief GDISP Graphics Driver subsystem low level driver source. + * + * @addtogroup GDISP + * @{ + */ + +#include "ch.h" +#include "hal.h" +#include "gdisp.h" + +#if HAL_USE_GDISP || defined(__DOXYGEN__) + +/* Include the emulation code for things we don't support */ +#include "gdisp_emulation.c" + +/* All the board specific code should go in these include file so the driver + * can be ported to another board just by creating a suitable file. + */ +//#if defined(BOARD_YOURBOARDNAME) +// #include "gdisp_lld_board_yourboardname.h" +//#else +// /* Include the user supplied board definitions */ +// #include "gdisp_lld_board.h" +//#endif + +/*===========================================================================*/ +/* Driver interrupt handlers. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +#include "ssd1963.h" + + +#if defined(LCD_USE_FSMC) +__inline void GDISP_LLD(writeindex)(uint8_t cmd) { + LCD_REG = cmd; +} + +__inline void GDISP_LLD(writereg)(uint16_t lcdReg,uint16_t lcdRegValue) { + LCD_REG = lcdReg; + LCD_RAM = lcdRegValue; +} + +__inline void GDISP_LLD(writedata)(uint16_t data) { + LCD_RAM = data; +} + +__inline uint16_t GDISP_LLD(readdata)(void) { + return (LCD_RAM); +} + +__inline uint8_t GDISP_LLD(readreg)(uint8_t lcdReg) { + LCD_REG = lcdReg; + return (LCD_RAM); +} + +__inline void GDISP_LLD(writestreamstart)(void) { + GDISP_LLD(writeindex)(SSD1963_WRITE_MEMORY_START); +} + +__inline void GDISP_LLD(readstreamstart)(void) { + GDISP_LLD(writeindex)(SSD1963_READ_MEMORY_START); +} + +__inline void GDISP_LLD(writestream)(uint16_t *buffer, uint16_t size) { + uint16_t i; + for(i = 0; i < size; i++) + LCD_RAM = buffer[i]; +} + +__inline void GDISP_LLD(readstream)(uint16_t *buffer, size_t size) { + uint16_t i; + + for(i = 0; i < size; i++) { + buffer[i] = LCD_RAM; + } +} + +#elif defined(LCD_USE_GPIO) + +__inline void GDISP_LLD(writeindex)(uint8_t cmd) { + Set_CS; Set_RS; Set_WR; Clr_RD; + palWritePort(LCD_DATA_PORT, cmd); + Clr_CS; +} + +__inline void GDISP_LLD(writereg)(uint16_t lcdReg,uint16_t lcdRegValue) { + Set_CS; Set_RS; Set_WR; Clr_RD; + palWritePort(LCD_DATA_PORT, lcdReg); + Clr_RS; + palWritePort(LCD_DATA_PORT, lcdRegValue); + Clr_CS; +} +__inline void GDISP_LLD(writedata)(uint16_t data) { + Set_CS; Clr_RS; Set_WR; Clr_RD; + palWritePort(LCD_DATA_PORT, data); + Clr_CS; +} + +__inline uint16_t GDISP_LLD(readdata)(void) { + Set_CS; Clr_RS; Clr_WR; Set_RD; + uint16_t data = palReadPort(LCD_DATA_PORT); + Clr_CS; + return data; +} + +__inline uint8_t GDISP_LLD(readreg)(uint8_t lcdReg) { + Set_CS; Set_RS; Clr_WR; Set_RD; + palWritePort(LCD_DATA_PORT, lcdReg); + Clr_RS; + uint16_t data = palReadPort(LCD_DATA_PORT); + Clr_CS; + return data; +} + +__inline void GDISP_LLD(writestreamstart)(void) { + GDISP_LLD(writeindex)(SSD1963_WRITE_MEMORY_START); +} + +__inline void GDISP_LLD(readstreamstart)(void) { + GDISP_LLD(writeindex)(SSD1963_READ_MEMORY_START); +} + +__inline void GDISP_LLD(writestream)(uint16_t *buffer, uint16_t size) { + uint16_t i; + Set_CS; Clr_RS; Set_WR; Clr_RD; + for(i = 0; i < size; i++) { + Set_WR; + palWritePort(LCD_DATA_PORT, buffer[i]); + Clr_WR; + } + Clr_CS; +} + +__inline void GDISP_LLD(readstream)(uint16_t *buffer, size_t size) { + uint16_t i; + Set_CS; Clr_RS; Clr_WR; Set_RD; + for(i = 0; i < size; i++) { + Set_RD; + buffer[i] = palReadPort(LCD_DATA_PORT); + Clr_RD; + } +} +#endif + +/* ---- Required Routines ---- */ +/* + The following 2 routines are required. + All other routines are optional. +*/ + +/** + * @brief Low level GDISP driver initialisation. + * @return TRUE if successful, FALSE on error. + * + * @notapi + */ +bool_t GDISP_LLD(init)(void) { + /* Initialise the display */ + +#if defined(LCD_USE_FSMC) + + #if defined(STM32F1XX) || defined(STM32F3XX) + /* FSMC setup for F1/F3 */ + rccEnableAHB(RCC_AHBENR_FSMCEN, 0); + + #elif defined(STM32F4XX) || defined(STM32F2XX) + /* STM32F2-F4 FSMC init */ + rccEnableAHB3(RCC_AHB3ENR_FSMCEN, 0); + #else + #error "FSMC not implemented for this device" + #endif + + /* set pins to FSMC mode */ + IOBus busD = {GPIOD, (1 << 0) | (1 << 1) | (1 << 4) | (1 << 5) | (1 << 7) | (1 << 8) | + (1 << 9) | (1 << 10) | (1 << 11) | (1 << 14) | (1 << 15), 0}; + + IOBus busE = {GPIOE, (1 << 7) | (1 << 8) | (1 << 9) | (1 << 10) | (1 << 11) | (1 << 12) | + (1 << 13) | (1 << 14) | (1 << 15), 0}; + + palSetBusMode(&busD, PAL_MODE_ALTERNATE(12)); + palSetBusMode(&busE, PAL_MODE_ALTERNATE(12)); + + const unsigned char FSMC_Bank = 0; + /* FSMC timing */ + FSMC_Bank1->BTCR[FSMC_Bank+1] = (FSMC_BTR1_ADDSET_1 | FSMC_BTR1_ADDSET_3) \ + | (FSMC_BTR1_DATAST_1 | FSMC_BTR1_DATAST_3) \ + | (FSMC_BTR1_BUSTURN_1 | FSMC_BTR1_BUSTURN_3) ; + + /* Bank1 NOR/SRAM control register configuration + * This is actually not needed as already set by default after reset */ + FSMC_Bank1->BTCR[FSMC_Bank] = FSMC_BCR1_MWID_0 | FSMC_BCR1_WREN | FSMC_BCR1_MBKEN; + + #elif defined(LCD_USE_GPIO) + IOBus busCMD = {LCD_CMD_PORT, (1 << LCD_CS) | (1 << LCD_RS) | (1 << LCD_WR) | (1 << LCD_RD), 0}; + IOBus busDATA = {LCD_CMD_PORT, 0xFFFFF, 0}; + palSetBusMode(&busCMD, PAL_MODE_OUTPUT_PUSHPULL); + palSetBusMode(&busDATA, PAL_MODE_OUTPUT_PUSHPULL); + + #else + #error "Please define LCD_USE_FSMC or LCD_USE_GPIO" +#endif + GDISP_LLD(writeindex)(SSD1963_SOFT_RESET); + chThdSleepMicroseconds(100); + + /* Driver PLL config */ + GDISP_LLD(writeindex)(SSD1963_SET_PLL_MN); + GDISP_LLD(writedata)(35); // PLLclk = REFclk (10Mhz) * 36 (360Mhz) + GDISP_LLD(writedata)(2); // SYSclk = PLLclk / 3 (120MHz) + GDISP_LLD(writedata)(4); // Apply calculation bit, else it is ignored + + GDISP_LLD(writeindex)(SSD1963_SET_PLL); // Enable PLL + GDISP_LLD(writedata)(0x01); + chThdSleepMicroseconds(200); + + GDISP_LLD(writeindex)(SSD1963_SET_PLL); // Use PLL + GDISP_LLD(writedata)(0x03); + chThdSleepMicroseconds(200); + + GDISP_LLD(writeindex)(SSD1963_SOFT_RESET); + chThdSleepMicroseconds(100); + + /* Screen size */ + GDISP_LLD(writeindex)(SSD1963_SET_LCD_MODE); +// GDISP_LLD(writedata)(0x0000); + GDISP_LLD(writedata)(0b00011000); + GDISP_LLD(writedata)(0x0000); + GDISP_LLD(writedata)(mHIGH((SCREEN_WIDTH+1))); + GDISP_LLD(writedata)((SCREEN_WIDTH+1)); + GDISP_LLD(writedata)(mHIGH((SCREEN_HEIGHT+1))); + GDISP_LLD(writedata)((SCREEN_HEIGHT+1)); + GDISP_LLD(writedata)(0x0000); + + GDISP_LLD(writeindex)(SSD1963_SET_PIXEL_DATA_INTERFACE); + GDISP_LLD(writedata)(SSD1963_PDI_16BIT565); + + /* LCD Clock specs */ + GDISP_LLD(writeindex)(SSD1963_SET_LSHIFT_FREQ); + GDISP_LLD(writedata)((LCD_FPR >> 16) & 0xFF); + GDISP_LLD(writedata)((LCD_FPR >> 8) & 0xFF); + GDISP_LLD(writedata)(LCD_FPR & 0xFF); + + GDISP_LLD(writeindex)(SSD1963_SET_HORI_PERIOD); + GDISP_LLD(writedata)(mHIGH(SCREEN_HSYNC_PERIOD)); + GDISP_LLD(writedata)(mLOW(SCREEN_HSYNC_PERIOD)); + GDISP_LLD(writedata)(mHIGH((SCREEN_HSYNC_PULSE + SCREEN_HSYNC_BACK_PORCH))); + GDISP_LLD(writedata)(mLOW((SCREEN_HSYNC_PULSE + SCREEN_HSYNC_BACK_PORCH))); + GDISP_LLD(writedata)(SCREEN_HSYNC_PULSE); + GDISP_LLD(writedata)(0x00); + GDISP_LLD(writedata)(0x00); + GDISP_LLD(writedata)(0x00); + + GDISP_LLD(writeindex)(SSD1963_SET_VERT_PERIOD); + GDISP_LLD(writedata)(mHIGH(SCREEN_VSYNC_PERIOD)); + GDISP_LLD(writedata)(mLOW(SCREEN_VSYNC_PERIOD)); + GDISP_LLD(writedata)(mHIGH((SCREEN_VSYNC_PULSE + SCREEN_VSYNC_BACK_PORCH))); + GDISP_LLD(writedata)(mLOW((SCREEN_VSYNC_PULSE + SCREEN_VSYNC_BACK_PORCH))); + GDISP_LLD(writedata)(SCREEN_VSYNC_PULSE); + GDISP_LLD(writedata)(0x00); + GDISP_LLD(writedata)(0x00); + + /* Tear effect indicator ON. This is used to tell the host MCU when the driver is not refreshing the panel */ + GDISP_LLD(writeindex)(SSD1963_SET_TEAR_ON); + GDISP_LLD(writedata)(0x0000); + + /* Turn on */ + GDISP_LLD(writeindex)(SSD1963_SET_DISPLAY_ON); +#if defined(LCD_USE_FSMC) + /* FSMC delay reduced as the controller now runs at full speed */ + FSMC_Bank1->BTCR[FSMC_Bank+1] = FSMC_BTR1_ADDSET_0 | FSMC_BTR1_DATAST_2 | FSMC_BTR1_BUSTURN_0 ; + FSMC_Bank1->BTCR[FSMC_Bank] = FSMC_BCR1_MWID_0 | FSMC_BCR1_WREN | FSMC_BCR1_MBKEN; +#endif + + /* Initialise the GDISP structure to match */ + GDISP.Width = SCREEN_WIDTH; + GDISP.Height = SCREEN_HEIGHT; + GDISP.Orientation = landscape; + GDISP.Powermode = powerOn; + GDISP.Backlight = 100; + GDISP.Contrast = 50; + #if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP + GDISP.clipx0 = 0; + GDISP.clipy0 = 0; + GDISP.clipx1 = GDISP.Width-1; + GDISP.clipy1 = GDISP.Height-1; + #endif + + return TRUE; +} + +void GDISP_LLD(setwindow)(coord_t x0, coord_t y0, coord_t x1, coord_t y1) { + /* We don't need to validate here as the LLD routines will validate first. + * + * #if GDISP_NEED_VALIDATION + * if (x0 >= GDISP.Width || y0 >= GDISP.Height || x0 < 0 || y0 < 0) return; + * else if (x1 >= GDISP.Width || y1 >= GDISP.Height || y1 < 0 || y2 < 0) return; + * #endif + */ + GDISP_LLD(writeindex)(SSD1963_SET_PAGE_ADDRESS); + GDISP_LLD(writedata)((y0 >> 8) & 0xFF); + GDISP_LLD(writedata)((y0 >> 0) & 0xFF); + GDISP_LLD(writedata)((y1 >> 8) & 0xFF); + GDISP_LLD(writedata)((y1 >> 0) & 0xFF); + GDISP_LLD(writeindex)(SSD1963_SET_COLUMN_ADDRESS); + GDISP_LLD(writedata)((x0 >> 8) & 0xFF); + GDISP_LLD(writedata)((x0 >> 0) & 0xFF); + GDISP_LLD(writedata)((x1 >> 8) & 0xFF); + GDISP_LLD(writedata)((x1 >> 0) & 0xFF); +} + +/** + * @brief Draws a pixel on the display. + * + * @param[in] x X location of the pixel + * @param[in] y Y location of the pixel + * @param[in] color The color of the pixel + * + * @notapi + */ +void GDISP_LLD(drawpixel)(coord_t x, coord_t y, color_t color) { + #if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP + if (x < GDISP.clipx0 || y < GDISP.clipy0 || x >= GDISP.clipx1 || y >= GDISP.clipy1) return; + #endif + + GDISP_LLD(setwindow)(x, y, x, y); + GDISP_LLD(writestreamstart)(); + GDISP_LLD(writedata)(color); +} + +/* ---- Optional Routines ---- */ + +#if GDISP_HARDWARE_FILLS || defined(__DOXYGEN__) + /** + * @brief Fill an area with a color. + * @note Optional - The high level driver can emulate using software. + * + * @param[in] x, y The start filled area + * @param[in] cx, cy The width and height to be filled + * @param[in] color The color of the fill + * + * @notapi + */ + void GDISP_LLD(fillarea)(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color) { + #if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP + if (x < GDISP.clipx0) { cx -= GDISP.clipx0 - x; x = GDISP.clipx0; } + if (y < GDISP.clipy0) { cy -= GDISP.clipy0 - y; y = GDISP.clipy0; } + if (cx <= 0 || cy <= 0 || x >= GDISP.clipx1 || y >= GDISP.clipy1) return; + if (x+cx > GDISP.clipx1) cx -= GDISP.clipx1 - x; + if (y+cy > GDISP.clipy1) cy -= GDISP.clipy1 - y; + #endif + + uint32_t index = 0, area; + area = cx*cy; + + GDISP_LLD(setwindow)(x, y, x+cx-1, y+cy-1); + GDISP_LLD(writestreamstart)(); + + for(index = 0; index < area; index++) + GDISP_LLD(writedata)(color); + } +#endif + +#if GDISP_HARDWARE_BITFILLS || defined(__DOXYGEN__) + /** + * @brief Fill an area with a bitmap. + * @note Optional - The high level driver can emulate using software. + * + * @param[in] x, y The start filled area + * @param[in] cx, cy The width and height to be filled + * @param[in] srcx, srcy The bitmap position to start the fill from + * @param[in] srccx The width of a line in the bitmap. + * @param[in] buffer The pixels to use to fill the area. + * + * @notapi + */ + void GDISP_LLD(blitareaex)(coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t srcx, coord_t srcy, coord_t srccx, const pixel_t *buffer) { + coord_t endx, endy; + unsigned lg; + + #if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP + if (x < GDISP.clipx0) { cx -= GDISP.clipx0 - x; srcx += GDISP.clipx0 - x; x = GDISP.clipx0; } + if (y < GDISP.clipy0) { cy -= GDISP.clipy0 - y; srcy += GDISP.clipy0 - y; y = GDISP.clipy0; } + if (srcx+cx > srccx) cx = srccx - srcx; + if (cx <= 0 || cy <= 0 || x >= GDISP.clipx1 || y >= GDISP.clipy1) return; + if (x+cx > GDISP.clipx1) cx -= GDISP.clipx1 - x; + if (y+cy > GDISP.clipy1) cy -= GDISP.clipy1 - y; + #endif + + GDISP_LLD(setwindow)(x, y, x+cx-1, y+cy-1); + GDISP_LLD(writestreamstart)(); + + endx = srcx + cx; + endy = y + cy; + lg = srccx - cx; + buffer += srcx + srcy * srccx; + for(; y < endy; y++, buffer += lg) + for(x=srcx; x < endx; x++) + GDISP_LLD(writedata)(*buffer++); + } +#endif + +#if (GDISP_NEED_SCROLL && GDISP_HARDWARE_SCROLL) || defined(__DOXYGEN__) + /** + * @brief Scroll vertically a section of the screen. + * @note Optional. + * @note If x,y + cx,cy is off the screen, the result is undefined. + * @note If lines is >= cy, it is equivelent to a area fill with bgcolor. + * + * @param[in] x, y The start of the area to be scrolled + * @param[in] cx, cy The size of the area to be scrolled + * @param[in] lines The number of lines to scroll (Can be positive or negative) + * @param[in] bgcolor The color to fill the newly exposed area. + * + * @notapi + */ + void GDISP_LLD(verticalscroll)(coord_t x, coord_t y, coord_t cx, coord_t cy, int lines, color_t bgcolor) { + #if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP + if (x < GDISP.clipx0) { cx -= GDISP.clipx0 - x; x = GDISP.clipx0; } + if (y < GDISP.clipy0) { cy -= GDISP.clipy0 - y; y = GDISP.clipy0; } + if (!lines || cx <= 0 || cy <= 0 || x >= GDISP.clipx1 || y >= GDISP.clipy1) return; + if (x+cx > GDISP.clipx1) cx -= GDISP.clipx1 - x; + if (y+cy > GDISP.clipy1) cy = GDISP.clipy1 - y; + #endif + /* NOT IMPLEMENTED YET */ + + /* + uint16_t size = x1 - x0 ; + + lld_lcdWriteIndex(SSD1963_SET_SCROLL_AREA); + lld_lcdWriteData((x0 >> 8) & 0xFF); + lld_lcdWriteData((x0 >> 0) & 0xFF); + lld_lcdWriteData((size >> 8) & 0xFF); + lld_lcdWriteData((size >> 0) & 0xFF); + lld_lcdWriteData(((lcd_height-x1) >> 8) & 0xFF); + lld_lcdWriteData(((lcd_height-x1) >> 0) & 0xFF); + + lld_lcdWriteIndex(SSD1963_SET_SCROLL_START); + lld_lcdWriteData((lines >> 8) & 0xFF); + lld_lcdWriteData((lines >> 0) & 0xFF); + */ + } + +#endif + +#if (GDISP_NEED_CONTROL && GDISP_HARDWARE_CONTROL) || defined(__DOXYGEN__) + /** + * @brief Driver Control + * @detail Unsupported control codes are ignored. + * @note The value parameter should always be typecast to (void *). + * @note There are some predefined and some specific to the low level driver. + * @note GDISP_CONTROL_POWER - Takes a gdisp_powermode_t + * GDISP_CONTROL_ORIENTATION - Takes a gdisp_orientation_t + * GDISP_CONTROL_BACKLIGHT - Takes an int from 0 to 100. For a driver + * that only supports off/on anything other + * than zero is on. + * GDISP_CONTROL_CONTRAST - Takes an int from 0 to 100. + * GDISP_CONTROL_LLD - Low level driver control constants start at + * this value. + * + * @param[in] what What to do. + * @param[in] value The value to use (always cast to a void *). + * + * @notapi + */ + void GDISP_LLD(control)(unsigned what, void *value) { + /* NOT IMPLEMENTED YET */ + switch(what) { + case GDISP_CONTROL_POWER: + if (GDISP.Powermode == (gdisp_powermode_t)value) + return; + switch((gdisp_powermode_t)value) { + case powerOff: + GDISP_LLD(writeindex)(SSD1963_EXIT_SLEEP_MODE); // leave sleep mode + chThdSleepMicroseconds(5000); + GDISP_LLD(writeindex)(SSD1963_SET_DISPLAY_OFF); + GDISP_LLD(writeindex)(SSD1963_SET_DEEP_SLEEP); // enter deep sleep mode + break; + case powerOn: + GDISP_LLD(readreg)(0x0000); chThdSleepMicroseconds(5000); // 2x Dummy reads to wake up from deep sleep + GDISP_LLD(readreg)(0x0000); chThdSleepMicroseconds(5000); + if (GDISP.Powermode != powerSleep) + GDISP_LLD(init)(); + GDISP_LLD(writeindex)(SSD1963_SET_DISPLAY_ON); + + break; + case powerSleep: + GDISP_LLD(writeindex)(SSD1963_SET_DISPLAY_OFF); + GDISP_LLD(writeindex)(SSD1963_ENTER_SLEEP_MODE); // enter sleep mode + chThdSleepMicroseconds(5000); + break; + default: + return; + } + GDISP.Powermode = (gdisp_powermode_t)value; + return; + case GDISP_CONTROL_ORIENTATION: + if (GDISP.Orientation == (gdisp_orientation_t)value) + return; + switch((gdisp_orientation_t)value) { + case portrait: + /* Code here */ + GDISP.Height = SCREEN_HEIGHT; + GDISP.Width = SCREEN_WIDTH; + break; + case landscape: + /* Code here */ + GDISP.Height = SCREEN_WIDTH; + GDISP.Width = SCREEN_HEIGHT; + break; + case portraitInv: + /* Code here */ + GDISP.Height = SCREEN_HEIGHT; + GDISP.Width = SCREEN_WIDTH; + break; + case landscapeInv: + /* Code here */ + GDISP.Height = SCREEN_WIDTH; + GDISP.Width = SCREEN_HEIGHT; + break; + default: + return; + } + #if GDISP_NEED_CLIP || GDISP_NEED_VALIDATION + GDISP.clipx0 = 0; + GDISP.clipy0 = 0; + GDISP.clipx1 = GDISP.Width; + GDISP.clipy1 = GDISP.Height; + #endif + GDISP.Orientation = (gdisp_orientation_t)value; + return; +/* + case GDISP_CONTROL_BACKLIGHT: + case GDISP_CONTROL_CONTRAST: +*/ + } + } +#endif + +#endif /* HAL_USE_GDISP */ +/** @} */ diff --git a/drivers/gdisp/SSD1963/gdisp_lld_config.h b/drivers/gdisp/SSD1963/gdisp_lld_config.h index 85dd7282..fc8d8489 100644 --- a/drivers/gdisp/SSD1963/gdisp_lld_config.h +++ b/drivers/gdisp/SSD1963/gdisp_lld_config.h @@ -1,66 +1,52 @@ -/* - ChibiOS-LCD-Driver Copyright (C) 2012 - Joel Bodenmann aka Tectu - - This file is part of ChibiOS-LCD-Driver. - - ChibiOS-LCD-Driver is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - ChibiOS-LCD-Driver is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -/** - * @file SSD1963/gdisp_lld_config.h - * @brief GDISP Graphic Driver subsystem low level driver header. - * - * @addtogroup GDISP - * @{ - */ - -#ifndef _GDISP_LLD_CONFIG_H -#define _GDISP_LLD_CONFIG_H - -#if HAL_USE_GDISP || defined(__DOXYGEN__) - -/*===========================================================================*/ -/* Driver hardware support. */ -/*===========================================================================*/ - -#define GDISP_DRIVER_NAME "SSD1963" -#define GDISP_LLD(x) gdisp_lld_##x##_SSD1963 - -#define GDISP_HARDWARE_LINES FALSE -#define GDISP_HARDWARE_CLEARS TRUE -#define GDISP_HARDWARE_FILLS TRUE -#define GDISP_HARDWARE_BITFILLS FALSE -#define GDISP_HARDWARE_CIRCLES FALSE -#define GDISP_HARDWARE_CIRCLEFILLS FALSE -#define GDISP_HARDWARE_ELLIPSES FALSE -#define GDISP_HARDWARE_ELLIPSEFILLS FALSE -#define GDISP_HARDWARE_TEXT FALSE -#define GDISP_HARDWARE_TEXTFILLS FALSE -#define GDISP_HARDWARE_SCROLL FALSE -#define GDISP_HARDWARE_PIXELREAD FALSE -#define GDISP_HARDWARE_CONTROL FALSE -#define GDISP_HARDWARE_QUERY FALSE - -#define GDISP_SOFTWARE_TEXTFILLDRAW FALSE -#define GDISP_SOFTWARE_TEXTBLITCOLUMN FALSE - -#define GDISP_PIXELFORMAT GDISP_PIXELFORMAT_RGB565 -#define GDISP_PACKED_PIXELS FALSE -#define GDISP_PACKED_LINES FALSE - -#endif /* HAL_USE_GDISP */ - -#endif /* _GDISP_LLD_CONFIG_H */ -/** @} */ +/* + ChibiOS-LCD-Driver Copyright (C) 2012 + Joel Bodenmann aka Tectu + + This file is part of ChibiOS-LCD-Driver. + + ChibiOS-LCD-Driver is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS-LCD-Driver is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file SSD1963/gdisp_lld_config.h + * @brief GDISP Graphic Driver subsystem low level driver header. + * + * @addtogroup GDISP + * @{ + */ + +#ifndef _GDISP_LLD_CONFIG_H +#define _GDISP_LLD_CONFIG_H + +#if HAL_USE_GDISP || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver hardware support. */ +/*===========================================================================*/ + +#define GDISP_DRIVER_NAME "SSD1963" +#define GDISP_LLD(x) gdisp_lld_##x##_SSD1963 + +#define GDISP_HARDWARE_FILLS TRUE +#define GDISP_HARDWARE_BITFILLS TRUE +/* Maybe someday soon */ +#define GDISP_HARDWARE_SCROLL FALSE +#define GDISP_HARDWARE_CONTROL FALSE + +#define GDISP_PIXELFORMAT GDISP_PIXELFORMAT_RGB565 + +#endif /* HAL_USE_GDISP */ + +#endif /* _GDISP_LLD_CONFIG_H */ +/** @} */ diff --git a/drivers/gdisp/TestStub/gdisp_lld.c b/drivers/gdisp/TestStub/gdisp_lld.c index fd8410fb..1999d4ec 100644 --- a/drivers/gdisp/TestStub/gdisp_lld.c +++ b/drivers/gdisp/TestStub/gdisp_lld.c @@ -35,30 +35,6 @@ /* Include the emulation code for things we don't support */ #include "gdisp_emulation.c" -/*===========================================================================*/ -/* Driver local definitions. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver exported variables. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver local variables. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver local functions. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver interrupt handlers. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver exported functions. */ -/*===========================================================================*/ - /* ---- Required Routines ---- */ /* The following 2 routines are required. @@ -78,6 +54,12 @@ bool_t GDISP_LLD(init)(void) { GDISP.Powermode = powerOff; GDISP.Backlight = 100; GDISP.Contrast = 50; + #if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP + GDISP.clipx0 = 0; + GDISP.clipy0 = 0; + GDISP.clipx1 = GDISP.Width-1; + GDISP.clipy1 = GDISP.Height-1; + #endif return TRUE; } @@ -94,179 +76,6 @@ void GDISP_LLD(drawpixel)(coord_t UNUSED(x), coord_t UNUSED(y), color_t UNUSED(c } /* ---- Optional Routines ---- */ -/* - All the below routines are optional. - Defining them will increase speed but everything - will work if they are not defined. - If you are not using a routine - turn it off using - the appropriate GDISP_HARDWARE_XXXX macro. - Don't bother coding for obvious similar routines if - there is no performance penalty as the emulation software - makes a good job of using similar routines. - eg. If fillarea() is defined there is little - point in defining clear() unless the - performance bonus is significant. - For good performance it is suggested to implement - fillarea() and blitarea(). -*/ - -#if GDISP_HARDWARE_CLEARS || defined(__DOXYGEN__) - /** - * @brief Clear the display. - * @note Optional - The high level driver can emulate using software. - * - * @param[in] color The color of the pixel - * - * @notapi - */ - void GDISP_LLD(clear)(color_t UNUSED(color)) { - } -#endif - -#if GDISP_HARDWARE_LINES || defined(__DOXYGEN__) - /** - * @brief Draw a line. - * @note Optional - The high level driver can emulate using software. - * - * @param[in] x0, y0 The start of the line - * @param[in] x1, y1 The end of the line - * @param[in] color The color of the line - * - * @notapi - */ - void GDISP_LLD(drawline)(coord_t UNUSED(x0), coord_t UNUSED(y0), coord_t UNUSED(x1), coord_t UNUSED(y1), color_t UNUSED(color)) { - } -#endif - -#if GDISP_HARDWARE_FILLS || defined(__DOXYGEN__) - /** - * @brief Fill an area with a color. - * @note Optional - The high level driver can emulate using software. - * - * @param[in] x, y The start filled area - * @param[in] cx, cy The width and height to be filled - * @param[in] color The color of the fill - * - * @notapi - */ - void GDISP_LLD(fillarea)(coord_t UNUSED(x), coord_t UNUSED(y), coord_t UNUSED(cx), coord_t UNUSED(cy), color_t UNUSED(color)) { - } -#endif - -#if GDISP_HARDWARE_BITFILLS || defined(__DOXYGEN__) - /** - * @brief Fill an area with a bitmap. - * @note Optional - The high level driver can emulate using software. - * - * @param[in] x, y The start filled area - * @param[in] cx, cy The width and height to be filled - * @param[in] buffer The pixels to use to fill the area. - * - * @notapi - */ - void GDISP_LLD(blitarea)(coord_t UNUSED(x), coord_t UNUSED(y), coord_t UNUSED(cx), coord_t UNUSED(cy), const pixel_t *UNUSED(buffer)) { - } -#endif - -/* Circular Drawing Functions */ -#if (GDISP_NEED_CIRCLE && GDISP_HARDWARE_CIRCLES) || defined(__DOXYGEN__) - /** - * @brief Draw a circle. - * @note Optional - The high level driver can emulate using software. - * @note If GDISP_NEED_CLIPPING is defined this routine MUST behave - * correctly if the circle is over the edges of the screen. - * - * @param[in] x, y The centre of the circle - * @param[in] radius The radius of the circle - * @param[in] color The color of the circle - * - * @notapi - */ - void GDISP_LLD(drawcircle)(coord_t UNUSED(x), coord_t UNUSED(y), coord_t UNUSED(radius), color_t UNUSED(color)) { - } -#endif - -#if (GDISP_NEED_CIRCLE && GDISP_HARDWARE_CIRCLEFILLS) || defined(__DOXYGEN__) - /** - * @brief Create a filled circle. - * @note Optional - The high level driver can emulate using software. - * @note If GDISP_NEED_CLIPPING is defined this routine MUST behave - * correctly if the circle is over the edges of the screen. - * - * @param[in] x, y The centre of the circle - * @param[in] radius The radius of the circle - * @param[in] color The color of the circle - * - * @notapi - */ - void GDISP_LLD(fillcircle)(coord_t UNUSED(x), coord_t UNUSED(y), coord_t UNUSED(radius), color_t UNUSED(color)) { - } -#endif - -#if (GDISP_NEED_ELLIPSE && GDISP_HARDWARE_ELLIPSES) || defined(__DOXYGEN__) - /** - * @brief Draw an ellipse. - * @note Optional - The high level driver can emulate using software. - * @note If GDISP_NEED_CLIPPING is defined this routine MUST behave - * correctly if the ellipse is over the edges of the screen. - * - * @param[in] x, y The centre of the ellipse - * @param[in] a, b The dimensions of the ellipse - * @param[in] color The color of the ellipse - * - * @notapi - */ - void GDISP_LLD(drawellipse)(coord_t UNUSED(x), coord_t UNUSED(y), coord_t UNUSED(a), coord_t UNUSED(b), color_t UNUSED(color)) { - } -#endif - -#if (GDISP_NEED_ELLIPSE && GDISP_HARDWARE_ELLIPSEFILLS) || defined(__DOXYGEN__) - /** - * @brief Create a filled ellipse. - * @note Optional - The high level driver can emulate using software. - * @note If GDISP_NEED_CLIPPING is defined this routine MUST behave - * correctly if the ellipse is over the edges of the screen. - * - * @param[in] x, y The centre of the ellipse - * @param[in] a, b The dimensions of the ellipse - * @param[in] color The color of the ellipse - * - * @notapi - */ - void GDISP_LLD(fillellipse)(coord_t UNUSED(x), coord_t UNUSED(y), coord_t UNUSED(a), coord_t UNUSED(b), color_t UNUSED(color)) { - } -#endif - -#if (GDISP_NEED_TEXT && GDISP_HARDWARE_TEXT) || defined(__DOXYGEN__) - /** - * @brief Draw a character using a transparent background. - * @note Optional - The high level driver can emulate using software. - * - * @param[in] x, y The top-left corner of the text - * @param[in] c The character to print - * @param[in] color The color of the character - * - * @notapi - */ - void GDISP_LLD(drawchar)(coord_t UNUSED(x), coord_t UNUSED(y), char UNUSED(c), font_t UNUSED(font), color_t UNUSED(color)) { - } -#endif - -#if (GDISP_NEED_TEXT && GDISP_HARDWARE_TEXTFILLS) || defined(__DOXYGEN__) - /** - * @brief Draw a character using a filled background. - * @note Optional - The high level driver can emulate using software. - * - * @param[in] x, y The top-left corner of the text - * @param[in] c The character to print - * @param[in] color The color of the character - * @param[in] bgcolor The background color - * - * @notapi - */ - void GDISP_LLD(fillchar)(coord_t UNUSED(x), coord_t UNUSED(y), char UNUSED(c), font_t UNUSED(font), color_t UNUSED(color), color_t UNUSED(bgcolor)) { - } -#endif #if (GDISP_NEED_PIXELREAD && GDISP_HARDWARE_PIXELREAD) || defined(__DOXYGEN__) /** @@ -301,61 +110,5 @@ void GDISP_LLD(drawpixel)(coord_t UNUSED(x), coord_t UNUSED(y), color_t UNUSED(c } #endif -#if (GDISP_NEED_CONTROL && GDISP_HARDWARE_CONTROL) || defined(__DOXYGEN__) - /** - * @brief Driver Control - * @detail Unsupported control codes are ignored. - * @note The value parameter should always be typecast to (void *). - * @note There are some predefined and some specific to the low level driver. - * @note GDISP_CONTROL_POWER - Takes a gdisp_powermode_t - * GDISP_CONTROL_ORIENTATION - Takes a gdisp_orientation_t - * GDISP_CONTROL_BACKLIGHT - Takes an int from 0 to 100. For a driver - * that only supports off/on anything other - * than zero is on. - * GDISP_CONTROL_CONTRAST - Takes an int from 0 to 100. - * GDISP_CONTROL_LLD - Low level driver control constants start at - * this value. - * - * @param[in] what What to do. - * @param[in] value The value to use (always cast to a void *). - * - * @notapi - */ - void GDISP_LLD(control)(unsigned UNUSED(what), void *UNUSED(value)) { - } -#endif - -#if (GDISP_NEED_QUERY && GDISP_HARDWARE_QUERY) || defined(__DOXYGEN__) -/** - * @brief Query a driver value. - * @detail Typecase the result to the type you want. - * @note GDISP_QUERY_WIDTH - (coord_t) Gets the width of the screen - * GDISP_QUERY_HEIGHT - (coord_t) Gets the height of the screen - * GDISP_QUERY_POWER - (gdisp_powermode_t) Get the current powermode - * GDISP_QUERY_ORIENTATION - (gdisp_orientation_t) Get the current screen orientation - * GDISP_QUERY_BACKLIGHT - (coord_t) Get the backlight state (0 to 100) - * GDISP_QUERY_CONTRAST - (coord_t) Get the contrast (0 to 100). - * GDISP_QUERY_LLD - Low level driver control constants start at - * this value. - * - * @param[in] what What to Query - * - * @notapi - */ -void *GDISP_LLD(query)(unsigned what) { - switch(what) { - case GDISP_QUERY_WIDTH: return (void *)(unsigned)GDISP.Width; - case GDISP_QUERY_HEIGHT: return (void *)(unsigned)GDISP.Height; - case GDISP_QUERY_POWER: return (void *)(unsigned)GDISP.Powermode; - case GDISP_QUERY_ORIENTATION: return (void *)(unsigned)GDISP.Orientation; - case GDISP_QUERY_BACKLIGHT: return (void *)(unsigned)GDISP.Backlight; - case GDISP_QUERY_CONTRAST: return (void *)(unsigned)GDISP.Contrast; - case GDISP_QUERY_LLD+0: - /* Code here */ - default: return (void *)-1; - } -} -#endif - #endif /* HAL_USE_GDISP */ /** @} */ diff --git a/drivers/gdisp/TestStub/gdisp_lld_config.h b/drivers/gdisp/TestStub/gdisp_lld_config.h index d66e050f..b570ef39 100644 --- a/drivers/gdisp/TestStub/gdisp_lld_config.h +++ b/drivers/gdisp/TestStub/gdisp_lld_config.h @@ -38,23 +38,8 @@ #define GDISP_DRIVER_NAME "TestStub" #define GDISP_LLD(x) gdisp_lld_##x##_TestStub -#define GDISP_HARDWARE_LINES FALSE -#define GDISP_HARDWARE_CLEARS FALSE -#define GDISP_HARDWARE_FILLS FALSE -#define GDISP_HARDWARE_BITFILLS FALSE -#define GDISP_HARDWARE_CIRCLES FALSE -#define GDISP_HARDWARE_CIRCLEFILLS FALSE -#define GDISP_HARDWARE_ELLIPSES FALSE -#define GDISP_HARDWARE_ELLIPSEFILLS FALSE -#define GDISP_HARDWARE_TEXT FALSE -#define GDISP_HARDWARE_TEXTFILLS FALSE #define GDISP_HARDWARE_SCROLL GDISP_NEED_SCROLL #define GDISP_HARDWARE_PIXELREAD GDISP_NEED_PIXELREAD -#define GDISP_HARDWARE_CONTROL FALSE -#define GDISP_HARDWARE_QUERY FALSE - -#define GDISP_SOFTWARE_TEXTFILLDRAW FALSE -#define GDISP_SOFTWARE_TEXTBLITCOLUMN FALSE #define GDISP_PIXELFORMAT GDISP_PIXELFORMAT_RGB565 #define GDISP_PACKED_PIXELS FALSE diff --git a/drivers/gdisp/VMT/gdisp_lld.c b/drivers/gdisp/VMT/gdisp_lld.c index 1528f470..3e149640 100644 --- a/drivers/gdisp/VMT/gdisp_lld.c +++ b/drivers/gdisp/VMT/gdisp_lld.c @@ -49,8 +49,11 @@ bool_t GDISP_LLD1(init)(void); void GDISP_LLD1(clear)(color_t color); void GDISP_LLD1(drawpixel)(coord_t x, coord_t y, color_t color); void GDISP_LLD1(fillarea)(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color); -void GDISP_LLD1(blitarea)(coord_t x, coord_t y, coord_t cx, coord_t cy, const pixel_t *buffer); +void GDISP_LLD1(blitareaex)(coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t srcx, coord_t srcy, coord_t srccx, const pixel_t *buffer); void GDISP_LLD1(drawline)(coord_t x0, coord_t y0, coord_t x1, coord_t y1, color_t color); +#if GDISP_NEED_CLIP + void GDISP_LLD1(setclip)(coord_t x, coord_t y, coord_t cx, coord_t cy); +#endif #if GDISP_NEED_CIRCLE void GDISP_LLD1(drawcircle)(coord_t x, coord_t y, coord_t radius, color_t color); void GDISP_LLD1(fillcircle)(coord_t x, coord_t y, coord_t radius, color_t color); @@ -59,6 +62,10 @@ void GDISP_LLD1(drawline)(coord_t x0, coord_t y0, coord_t x1, coord_t y1, color_ void GDISP_LLD1(drawellipse)(coord_t x, coord_t y, coord_t a, coord_t b, color_t color); void GDISP_LLD1(fillellipse)(coord_t x, coord_t y, coord_t a, coord_t b, color_t color); #endif +#if GDISP_NEED_ARC + void GDISP_LLD1(drawarc)(coord_t x, coord_t y, coord_t radius, coord_t startangle, coord_t endangle, color_t color); + void GDISP_LLD1(fillarc)(coord_t x, coord_t y, coord_t radius, coord_t startangle, coord_t endangle, color_t color); +#endif #if GDISP_NEED_TEXT void GDISP_LLD1(drawchar)(coord_t x, coord_t y, char c, font_t font, color_t color); void GDISP_LLD1(fillchar)(coord_t x, coord_t y, char c, font_t font, color_t color, color_t bgcolor); @@ -80,8 +87,11 @@ bool_t GDISP_LLD2(init)(void); void GDISP_LLD2(clear)(color_t color); void GDISP_LLD2(drawpixel)(coord_t x, coord_t y, color_t color); void GDISP_LLD2(fillarea)(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color); -void GDISP_LLD2(blitarea)(coord_t x, coord_t y, coord_t cx, coord_t cy, const pixel_t *buffer); +void GDISP_LLD2(blitareaex)(coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t srcx, coord_t srcy, coord_t srccx, const pixel_t *buffer); void GDISP_LLD2(drawline)(coord_t x0, coord_t y0, coord_t x1, coord_t y1, color_t color); +#if GDISP_NEED_CLIP + void GDISP_LLD2(setclip)(coord_t x, coord_t y, coord_t cx, coord_t cy); +#endif #if GDISP_NEED_CIRCLE void GDISP_LLD2(drawcircle)(coord_t x, coord_t y, coord_t radius, color_t color); void GDISP_LLD2(fillcircle)(coord_t x, coord_t y, coord_t radius, color_t color); @@ -90,6 +100,10 @@ void GDISP_LLD2(drawline)(coord_t x0, coord_t y0, coord_t x1, coord_t y1, color_ void GDISP_LLD2(drawellipse)(coord_t x, coord_t y, coord_t a, coord_t b, color_t color); void GDISP_LLD2(fillellipse)(coord_t x, coord_t y, coord_t a, coord_t b, color_t color); #endif +#if GDISP_NEED_ARC + void GDISP_LLD2(drawarc)(coord_t x, coord_t y, coord_t radius, coord_t startangle, coord_t endangle, color_t color); + void GDISP_LLD2(fillarc)(coord_t x, coord_t y, coord_t radius, coord_t startangle, coord_t endangle, color_t color); +#endif #if GDISP_NEED_TEXT void GDISP_LLD2(drawchar)(coord_t x, coord_t y, char c, font_t font, color_t color); void GDISP_LLD2(fillchar)(coord_t x, coord_t y, char c, font_t font, color_t color, color_t bgcolor); @@ -115,7 +129,7 @@ void GDISP_LLD2(drawline)(coord_t x0, coord_t y0, coord_t x1, coord_t y1, color_ void GDISP_LLD_VMT(clear)(color_t color); void GDISP_LLD_VMT(drawpixel)(coord_t x, coord_t y, color_t color); void GDISP_LLD_VMT(fillarea)(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color); -void GDISP_LLD_VMT(blitarea)(coord_t x, coord_t y, coord_t cx, coord_t cy, const pixel_t *buffer); +void GDISP_LLD_VMT(blitareaex)(coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t srcx, coord_t srcy, coord_t srccx, const pixel_t *buffer); void GDISP_LLD_VMT(drawline)(coord_t x0, coord_t y0, coord_t x1, coord_t y1, color_t color); #if GDISP_NEED_CIRCLE @@ -152,6 +166,10 @@ void GDISP_LLD_VMT(control)(unsigned what, void *value); #if GDISP_NEED_QUERY void *GDISP_LLD_VMT(query)(unsigned what); #endif +/* Clipping Functions */ +#if GDISP_NEED_CLIP +void GDISP_LLD_VMT(setclip)(coord_t x, coord_t y, coord_t cx, coord_t cy); +#endif /*===========================================================================*/ @@ -179,7 +197,7 @@ bool_t gdisp_lld_init_VMT(void) { gdisp_lld_clear_VMT = GDISP_VMT_NAME1(gdisp_lld_clear_); gdisp_lld_drawpixel_VMT = GDISP_VMT_NAME1(gdisp_lld_drawpixel_); gdisp_lld_fillarea_VMT = GDISP_VMT_NAME1(gdisp_lld_fillarea_); - gdisp_lld_blitarea_VMT = GDISP_VMT_NAME1(gdisp_lld_blitarea_); + gdisp_lld_blitareaex_VMT = GDISP_VMT_NAME1(gdisp_lld_blitareaex_); gdisp_lld_drawline_VMT = GDISP_VMT_NAME1(gdisp_lld_drawline_); #if GDISP_NEED_CIRCLE gdisp_lld_drawcircle_VMT = GDISP_VMT_NAME1(gdisp_lld_drawcircle_); @@ -189,6 +207,10 @@ bool_t gdisp_lld_init_VMT(void) { gdisp_lld_drawellipse_VMT = GDISP_VMT_NAME1(gdisp_lld_drawellipse_); gdisp_lld_fillellipse_VMT = GDISP_VMT_NAME1(gdisp_lld_fillellipse_); #endif + #if GDISP_NEED_ARC + gdisp_lld_drawarc_VMT = GDISP_VMT_NAME1(gdisp_lld_drawarc_); + gdisp_lld_fillarc_VMT = GDISP_VMT_NAME1(gdisp_lld_fillarc_); + #endif #if GDISP_NEED_TEXT gdisp_lld_drawchar_VMT = GDISP_VMT_NAME1(gdisp_lld_drawchar_); gdisp_lld_fillchar_VMT = GDISP_VMT_NAME1(gdisp_lld_fillchar_); @@ -205,6 +227,9 @@ bool_t gdisp_lld_init_VMT(void) { #if GDISP_NEED_QUERY gdisp_lld_query_VMT = GDISP_VMT_NAME1(gdisp_lld_query_); #endif + #if GDISP_NEED_CLIP + gdisp_lld_setclip_VMT = GDISP_VMT_NAME1(gdisp_lld_setclip_); + #endif return TRUE; } @@ -213,7 +238,7 @@ bool_t gdisp_lld_init_VMT(void) { gdisp_lld_clear_VMT = GDISP_VMT_NAME2(gdisp_lld_clear_); gdisp_lld_drawpixel_VMT = GDISP_VMT_NAME2(gdisp_lld_drawpixel_); gdisp_lld_fillarea_VMT = GDISP_VMT_NAME2(gdisp_lld_fillarea_); - gdisp_lld_blitarea_VMT = GDISP_VMT_NAME2(gdisp_lld_blitarea_); + gdisp_lld_blitareaex_VMT = GDISP_VMT_NAME2(gdisp_lld_blitareaex_); gdisp_lld_drawline_VMT = GDISP_VMT_NAME2(gdisp_lld_drawline_); #if GDISP_NEED_CIRCLE gdisp_lld_drawcircle_VMT = GDISP_VMT_NAME2(gdisp_lld_drawcircle_); @@ -223,6 +248,10 @@ bool_t gdisp_lld_init_VMT(void) { gdisp_lld_drawellipse_VMT = GDISP_VMT_NAME2(gdisp_lld_drawellipse_); gdisp_lld_fillellipse_VMT = GDISP_VMT_NAME2(gdisp_lld_fillellipse_); #endif + #if GDISP_NEED_ARC + gdisp_lld_drawarc_VMT = GDISP_VMT_NAME2(gdisp_lld_drawarc_); + gdisp_lld_fillarc_VMT = GDISP_VMT_NAME2(gdisp_lld_fillarc_); + #endif #if GDISP_NEED_TEXT gdisp_lld_drawchar_VMT = GDISP_VMT_NAME2(gdisp_lld_drawchar_); gdisp_lld_fillchar_VMT = GDISP_VMT_NAME2(gdisp_lld_fillchar_); @@ -239,6 +268,9 @@ bool_t gdisp_lld_init_VMT(void) { #if GDISP_NEED_QUERY gdisp_lld_query_VMT = GDISP_VMT_NAME2(gdisp_lld_query_); #endif + #if GDISP_NEED_CLIP + gdisp_lld_setclip_VMT = GDISP_VMT_NAME2(gdisp_lld_setclip_); + #endif return TRUE; } diff --git a/drivers/gdisp/VMT/gdisp_lld_config.h b/drivers/gdisp/VMT/gdisp_lld_config.h index 6c6f7c80..6eedc23e 100644 --- a/drivers/gdisp/VMT/gdisp_lld_config.h +++ b/drivers/gdisp/VMT/gdisp_lld_config.h @@ -47,12 +47,15 @@ #define GDISP_HARDWARE_CIRCLEFILLS TRUE #define GDISP_HARDWARE_ELLIPSES TRUE #define GDISP_HARDWARE_ELLIPSEFILLS TRUE +#define GDISP_HARDWARE_ARCS TRUE +#define GDISP_HARDWARE_ARCFILLS TRUE #define GDISP_HARDWARE_TEXT TRUE #define GDISP_HARDWARE_TEXTFILLS TRUE #define GDISP_HARDWARE_SCROLL TRUE #define GDISP_HARDWARE_PIXELREAD TRUE #define GDISP_HARDWARE_CONTROL TRUE #define GDISP_HARDWARE_QUERY TRUE +#define GDISP_HARDWARE_CLIP TRUE #define GDISP_SOFTWARE_TEXTFILLDRAW FALSE #define GDISP_SOFTWARE_TEXTBLITCOLUMN FALSE diff --git a/drivers/gdisp/VMT/gdisp_lld_driver1.c b/drivers/gdisp/VMT/gdisp_lld_driver1.c index f088623e..c15878b1 100644 --- a/drivers/gdisp/VMT/gdisp_lld_driver1.c +++ b/drivers/gdisp/VMT/gdisp_lld_driver1.c @@ -31,8 +31,8 @@ #if HAL_USE_GDISP || defined(__DOXYGEN__) -#define CONFIGFILE() <../GDISP_VMT_NAME1(gdisp)/gdisp_lld_config.h> -#define DRIVERFILE() <../GDISP_VMT_NAME1(gdisp)/gdisp_lld.c> +#define CONFIGFILE() <../GDISP_VMT_NAME1()/gdisp_lld_config.h> +#define DRIVERFILE() <../GDISP_VMT_NAME1()/gdisp_lld.c> /* We don't need these in our VMT referenced driver */ #undef GDISP_NEED_MSGAPI diff --git a/drivers/gdisp/VMT/gdisp_lld_driver2.c b/drivers/gdisp/VMT/gdisp_lld_driver2.c index 325a53e6..4c64ea70 100644 --- a/drivers/gdisp/VMT/gdisp_lld_driver2.c +++ b/drivers/gdisp/VMT/gdisp_lld_driver2.c @@ -31,8 +31,8 @@ #if HAL_USE_GDISP || defined(__DOXYGEN__) -#define CONFIGFILE() <../GDISP_VMT_NAME2(gdisp)/gdisp_lld_config.h> -#define DRIVERFILE() <../GDISP_VMT_NAME2(gdisp)/gdisp_lld.c> +#define CONFIGFILE() <../GDISP_VMT_NAME2()/gdisp_lld_config.h> +#define DRIVERFILE() <../GDISP_VMT_NAME2()/gdisp_lld.c> /* We don't need these in our VMT referenced driver */ #undef GDISP_NEED_MSGAPI -- cgit v1.2.3