From 07f96ec3ee34fd4b4fffe2e6afbe50e982555fcb Mon Sep 17 00:00:00 2001 From: inmarket Date: Mon, 30 Sep 2013 15:41:32 +1000 Subject: [PATCH] HX8347D driver ported to new streaming structure (untested) --- drivers/gdisp/HX8347D/HX8347D.h | 2 +- drivers/gdisp/HX8347D/gdisp_lld.c | 440 ++++-------------- .../gdisp_lld_board_st_stm32f4_discovery.h | 155 +++--- .../gdisp/HX8347D/gdisp_lld_board_template.h | 49 +- drivers/gdisp/HX8347D/gdisp_lld_config.h | 7 +- 5 files changed, 189 insertions(+), 464 deletions(-) diff --git a/drivers/gdisp/HX8347D/HX8347D.h b/drivers/gdisp/HX8347D/HX8347D.h index b35dda12..280cd748 100644 --- a/drivers/gdisp/HX8347D/HX8347D.h +++ b/drivers/gdisp/HX8347D/HX8347D.h @@ -33,7 +33,7 @@ #define HX8347D_REG_PSLL 0x0b /* Partial area start row low */ #define HX8347D_REG_PELH 0x0c /* Partial area end row high */ #define HX8347D_REG_PELL 0x0d /* Partial area end row low */ -#define HX8347D_REG_TFAH 0x0e /* Vertical srcoll top fixed area high */ +#define HX8347D_REG_TFAH 0x0e /* Vertical scroll top fixed area high */ #define HX8347D_REG_TFAL 0x0f /* Vertical scroll top fixed area low */ #define HX8347D_REG_VSAH 0x10 /* Vertical scroll height area high */ diff --git a/drivers/gdisp/HX8347D/gdisp_lld.c b/drivers/gdisp/HX8347D/gdisp_lld.c index bcb6dfc0..a1e2c15b 100644 --- a/drivers/gdisp/HX8347D/gdisp_lld.c +++ b/drivers/gdisp/HX8347D/gdisp_lld.c @@ -15,12 +15,11 @@ #include "gfx.h" -#include "HX8347D.h" - #if GFX_USE_GDISP /*|| defined(__DOXYGEN__)*/ -/* Include the emulation code for things we don't support */ -#include "gdisp/lld/emulation.c" +#define GDISP_LLD_DECLARATIONS +#include "gdisp/lld/gdisp_lld.h" +#include "gdisp_lld_board.h" /*===========================================================================*/ /* Driver local definitions. */ @@ -32,74 +31,44 @@ #ifndef GDISP_SCREEN_WIDTH #define GDISP_SCREEN_WIDTH 240 #endif - -#define GDISP_INITIAL_CONTRAST 50 -#define GDISP_INITIAL_BACKLIGHT 50 +#ifndef GDISP_INITIAL_CONTRAST + #define GDISP_INITIAL_CONTRAST 50 +#endif +#ifndef GDISP_INITIAL_BACKLIGHT + #define GDISP_INITIAL_BACKLIGHT 100 +#endif /*===========================================================================*/ /* Driver local functions. */ /*===========================================================================*/ -#include "gdisp_lld_board.h" +#include "HX8347D.h" -// Some common routines and macros -#define write_reg(reg, data) { write_index(reg); write_data(data); } -#define write_ram(color1, color2) { write_index(0x22); write_ram8(color1,color2); } -#define stream_start() { write_index(0x22); spiStart(&SPID1, &spi1cfg2); } -#define stream_stop() {while(((SPI1->SR & SPI_SR_TXE) == 0) || ((SPI1->SR & SPI_SR_BSY) != 0));palSetPad(GPIOA, 4);spiStart(&SPID1, &spi1cfg1); } -#define delay(us) gfxSleepMicroseconds(us) -#define delayms(ms) gfxSleepMilliseconds(ms) - -static inline void set_cursor(coord_t x, coord_t y) { - write_reg(HX8347D_REG_SCL, (uint8_t) x); - write_reg(HX8347D_REG_SCH, (uint8_t) (x >> 8)); - write_reg(HX8347D_REG_SPL, (uint8_t) y); - write_reg(HX8347D_REG_SPH, (uint8_t) (y >> 8)); +static inline void set_viewport(GDISPDriver* g) { + write_reg(HX8347D_REG_SCL, (uint8_t) g->p.x); + write_reg(HX8347D_REG_SCH, (uint8_t) (g->p.x >> 8)); + write_reg(HX8347D_REG_ECL, (uint8_t) (g->p.x + g->p.cx -1)); + write_reg(HX8347D_REG_ECH, (uint8_t) ((g->p.x + g->p.cx -1) >> 8)); + write_reg(HX8347D_REG_SPL, (uint8_t) g->p.y); + write_reg(HX8347D_REG_SPH, (uint8_t) (g->p.y >> 8)); + write_reg(HX8347D_REG_EPL, (uint8_t) (g->p.y + g->p.cy -1)); + write_reg(HX8347D_REG_EPH, (uint8_t) ((g->p.y + g->p.cy -1) >> 8)); + write_index(HX8347D_REG_SRAMWC); } -static void set_viewport(coord_t x, coord_t y, coord_t cx, coord_t cy) { - write_reg(HX8347D_REG_SCL, (uint8_t) x); - write_reg(HX8347D_REG_SCH, (uint8_t) (x >> 8)); - write_reg(HX8347D_REG_ECL, (uint8_t) (x + cx -1)); - write_reg(HX8347D_REG_ECH, (uint8_t) ((x + cx -1) >> 8)); - write_reg(HX8347D_REG_SPL, (uint8_t) y); - write_reg(HX8347D_REG_SPH, (uint8_t) (y >> 8)); - write_reg(HX8347D_REG_EPL, (uint8_t) (y + cy -1)); - write_reg(HX8347D_REG_EPH, (uint8_t) ((y + cy -1) >> 8)); -} - -static inline void reset_viewport(void) { - set_viewport(0, 0, GDISP.Width, GDISP.Height); -} - -/*===========================================================================*/ -/* Driver interrupt handlers. */ -/*===========================================================================*/ - /*===========================================================================*/ /* Driver exported functions. */ /*===========================================================================*/ -/* ---- Required Routines ---- */ -/* - The following 2 routines are required. - All other routines are optional. -*/ - -/** - * @brief Low level GDISP driver initialization. - * - * @notapi - */ -bool_t gdisp_lld_init(void) { +LLDSPEC bool_t gdisp_lld_init(GDISPDriver *g) { /* Initialise your display */ init_board(); // Hardware reset setpin_reset(TRUE); - delayms(1); + gfxSleepMilliseconds(1); setpin_reset(FALSE); - delayms(5); + gfxSleepMilliseconds(5); // Get the bus for the following initialisation commands acquire_bus(); @@ -154,329 +123,104 @@ bool_t gdisp_lld_init(void) { write_reg(HX8347D_REG_OSCCL, 0x01); /* OSC Control 2 */ write_reg(HX8347D_REG_DMODE, 0x00); /* Display Mode Control */ write_reg(HX8347D_REG_PWC6, 0x88); /* Power Control 6 */ - delayms(5); /* Delay 5 ms */ + gfxSleepMilliseconds(5); /* Delay 5 ms */ write_reg(HX8347D_REG_PWC6, 0x80); /* Power Control 6 */ - delayms(5); /* Delay 5 ms */ + gfxSleepMilliseconds(5); /* Delay 5 ms */ write_reg(HX8347D_REG_PWC6, 0x90); /* Power Control 6 */ - delayms(5); /* Delay 5 ms */ + gfxSleepMilliseconds(5); /* Delay 5 ms */ write_reg(HX8347D_REG_PWC6, 0xD0); /* Power Control 6 */ - delayms(5); /* Delay 5 ms */ + gfxSleepMilliseconds(5); /* Delay 5 ms */ write_reg(HX8347D_REG_COLMOD, 0x05); /* Colmod 16Bit/Pixel */ write_reg(HX8347D_REG_PCH, 0x00); /* Panel Characteristic */ write_reg(HX8347D_REG_DC3, 0x38); /* Display Control 3 */ - delayms(40); + gfxSleepMilliseconds(40); /* Delay 40 ms */ write_reg(HX8347D_REG_DC3, 0x3C); /* Display Control 3 */ write_reg(HX8347D_REG_MAC, 0x08); /* Memory access control */ - write_reg(HX8347D_REG_SCL, 0x00); - write_reg(HX8347D_REG_SCH, 0x00); - write_reg(HX8347D_REG_ECL, 0xef); - write_reg(HX8347D_REG_ECH, 0x00); - write_reg(HX8347D_REG_SPL, 0x00); - write_reg(HX8347D_REG_SPH, 0x00); - write_reg(HX8347D_REG_EPL, 0x3f); - write_reg(HX8347D_REG_EPH, 0x01); - // Release the bus release_bus(); /* Turn on the backlight */ set_backlight(GDISP_INITIAL_BACKLIGHT); - /* Initialise the GDISP structure */ - GDISP.Width = GDISP_SCREEN_WIDTH; - GDISP.Height = GDISP_SCREEN_HEIGHT; - GDISP.Orientation = GDISP_ROTATE_0; - GDISP.Powermode = powerOn; - GDISP.Backlight = GDISP_INITIAL_BACKLIGHT; - GDISP.Contrast = GDISP_INITIAL_CONTRAST; - #if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP - GDISP.clipx0 = 0; - GDISP.clipy0 = 0; - GDISP.clipx1 = GDISP.Width; - GDISP.clipy1 = GDISP.Height; - #endif + /* Initialise the GDISP structure */ + g->g.Width = GDISP_SCREEN_WIDTH; + g->g.Height = GDISP_SCREEN_HEIGHT; + g->g.Orientation = GDISP_ROTATE_0; + g->g.Powermode = powerOn; + g->g.Backlight = GDISP_INITIAL_BACKLIGHT; + g->g.Contrast = GDISP_INITIAL_CONTRAST; return TRUE; } -/** - * @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_draw_pixel(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 - - acquire_bus(); - set_cursor(x, y); - write_ram((color >> 8) & 0xFF, color & 0xFF); - release_bus(); -} - -/* ---- 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 gfillarea() 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) { - unsigned i; - +#if GDISP_HARDWARE_STREAM_WRITE + LLDSPEC void gdisp_lld_write_start(GDISPDriver *g) { acquire_bus(); - reset_viewport(); - stream_start(); - for(i = 0; i < GDISP_SCREEN_WIDTH * GDISP_SCREEN_HEIGHT; i++) - write_ram16(color); - stream_stop(); + set_viewport(g); + busmode16(); + } + LLDSPEC void gdisp_lld_write_color(GDISPDriver *g) { + write_ram16(g->p.color); + } + LLDSPEC void gdisp_lld_write_stop(GDISPDriver *g) { + busmode8(); release_bus(); } #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_fill_area(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color) { - unsigned i, area; +#if GDISP_NEED_CONTROL && GDISP_HARDWARE_CONTROL + LLDSPEC void gdisp_lld_control(GDISPDriver *g) { + switch(g->p.x) { + case GDISP_CONTROL_ORIENTATION: + if (g->g.Orientation == (orientation_t)g->p.ptr) + return; + switch((orientation_t)g->p.ptr) { + case GDISP_ROTATE_0: + acquire_bus(); + write_reg(HX8347D_REG_MAC, 0x08); /* Memory access control */ + release_bus(); + g->g.Height = GDISP_SCREEN_HEIGHT; + g->g.Width = GDISP_SCREEN_WIDTH; + break; - #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 + case GDISP_ROTATE_90: + acquire_bus(); + write_reg(HX8347D_REG_MAC, 0x68); /* Memory access control */ + release_bus(); + g->g.Height = GDISP_SCREEN_WIDTH; + g->g.Width = GDISP_SCREEN_HEIGHT; + break; - area = cx*cy; + case GDISP_ROTATE_180: + acquire_bus(); + write_reg(HX8347D_REG_MAC, 0xc8); /* Memory access control */ + release_bus(); + g->g.Height = GDISP_SCREEN_HEIGHT; + g->g.Width = GDISP_SCREEN_WIDTH; + break; - acquire_bus(); - set_viewport(x, y, cx, cy); - stream_start(); - for(i = 0; i < area; i++) - write_ram16(color); - stream_stop(); - release_bus(); - } -#endif + case GDISP_ROTATE_270: + acquire_bus(); + write_reg(HX8347D_REG_MAC, 0xa8); /* Memory access control */ + release_bus(); + g->g.Height = GDISP_SCREEN_WIDTH; + g->g.Width = GDISP_SCREEN_HEIGHT; + break; -#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_blit_area_ex(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 - - acquire_bus(); - set_viewport(x, y, cx, cy); - stream_start(); - - 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++) - write_data(*buffer++); - stream_stop(); - release_bus(); - } -#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. - * - * @param[in] x, y The pixel to be read - * - * @notapi - */ - color_t gdisp_lld_get_pixel_color(coord_t x, coord_t y) { - color_t color; - - #if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP - if (x < 0 || x >= GDISP.Width || y < 0 || y >= GDISP.Height) return 0; - #endif -} -#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_vertical_scroll(coord_t x, coord_t y, coord_t cx, coord_t cy, int lines, color_t bgcolor) { - static color_t buf[((GDISP_SCREEN_HEIGHT > GDISP_SCREEN_WIDTH ) ? GDISP_SCREEN_HEIGHT : GDISP_SCREEN_WIDTH)]; - coord_t row0, row1; - unsigned i, abslines, j; - static int gap; - - #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 - - } -#endif - -#if (GDISP_NEED_CONTROL && GDISP_HARDWARE_CONTROL) || defined(__DOXYGEN__) - /** - * @brief Driver Control - * @details 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. - * - * @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_ORIENTATION: - if (GDISP.Orientation == (gdisp_orientation_t)value) + default: return; - switch((gdisp_orientation_t)value) { - case GDISP_ROTATE_0: - acquire_bus(); - write_reg(HX8347D_REG_MAC, 0x08); /* Memory access control */ - write_reg(HX8347D_REG_ECL, 0xef); - write_reg(HX8347D_REG_ECH, 0x00); - write_reg(HX8347D_REG_EPL, 0x3f); - write_reg(HX8347D_REG_EPH, 0x01); - release_bus(); - GDISP.Height = GDISP_SCREEN_HEIGHT; - GDISP.Width = GDISP_SCREEN_WIDTH; - break; + } + g->g.Orientation = (orientation_t)value; + return; + case GDISP_CONTROL_BACKLIGHT: + if ((unsigned)g->p.ptr > 100) + g->p.ptr = (void *)100; + set_backlight((unsigned)g->p.ptr); + g->g.Backlight = (unsigned)g->p.ptr; + return; - case GDISP_ROTATE_90: - acquire_bus(); - write_reg(HX8347D_REG_MAC, 0x68); /* Memory access control */ - write_reg(HX8347D_REG_ECL, 0x3f); - write_reg(HX8347D_REG_ECH, 0x01); - write_reg(HX8347D_REG_EPL, 0xef); - write_reg(HX8347D_REG_EPH, 0x00); - release_bus(); - GDISP.Height = GDISP_SCREEN_WIDTH; - GDISP.Width = GDISP_SCREEN_HEIGHT; - break; - - case GDISP_ROTATE_180: - acquire_bus(); - write_reg(HX8347D_REG_MAC, 0xc8); /* Memory access control */ - write_reg(HX8347D_REG_ECL, 0xef); - write_reg(HX8347D_REG_ECH, 0x00); - write_reg(HX8347D_REG_EPL, 0x3f); - write_reg(HX8347D_REG_EPH, 0x01); - release_bus(); - GDISP.Height = GDISP_SCREEN_HEIGHT; - GDISP.Width = GDISP_SCREEN_WIDTH; - break; - - case GDISP_ROTATE_270: - acquire_bus(); - write_reg(HX8347D_REG_MAC, 0xa8); /* Memory access control */ - write_reg(HX8347D_REG_ECL, 0x3f); - write_reg(HX8347D_REG_ECH, 0x01); - write_reg(HX8347D_REG_EPL, 0xef); - write_reg(HX8347D_REG_EPH, 0x00); - release_bus(); - GDISP.Height = GDISP_SCREEN_WIDTH; - GDISP.Width = GDISP_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: - if ((unsigned)value > 100) - value = (void *)100; - set_backlight((unsigned)value); - GDISP.Backlight = (unsigned)value; - return; - - default: - return; + default: + return; } } #endif diff --git a/drivers/gdisp/HX8347D/gdisp_lld_board_st_stm32f4_discovery.h b/drivers/gdisp/HX8347D/gdisp_lld_board_st_stm32f4_discovery.h index 984b92dd..8365fe74 100644 --- a/drivers/gdisp/HX8347D/gdisp_lld_board_st_stm32f4_discovery.h +++ b/drivers/gdisp/HX8347D/gdisp_lld_board_st_stm32f4_discovery.h @@ -16,21 +16,31 @@ #ifndef _GDISP_LLD_BOARD_H #define _GDISP_LLD_BOARD_H -#define SET_RST palSetPad(GPIOB, 8); -#define CLR_RST palClearPad(GPIOB, 8); +// Overrides +#ifndef GDISP_INITIAL_BACKLIGHT + #define GDISP_INITIAL_BACKLIGHT 50 +#endif + +/* Pin assignments */ +#define SET_RST palSetPad(GPIOB, 8) +#define CLR_RST palClearPad(GPIOB, 8) +#define SET_DATA palSetPad(GPIOB, 9) +#define CLR_DATA palClearPad(GPIOB, 9) +#define SET_CS palSetPad(GPIOA, 4) +#define CLR_CS palClearPad(GPIOA, 4) /* PWM configuration structure. We use timer 4 channel 2 (orange LED on board). */ static const PWMConfig pwmcfg = { - 1000000, /* 1 MHz PWM clock frequency. */ - 100, /* PWM period is 100 cycles. */ - NULL, - { - {PWM_OUTPUT_ACTIVE_HIGH, NULL}, - {PWM_OUTPUT_ACTIVE_HIGH, NULL}, - {PWM_OUTPUT_ACTIVE_HIGH, NULL}, - {PWM_OUTPUT_ACTIVE_HIGH, NULL} - }, - 0 + 1000000, /* 1 MHz PWM clock frequency. */ + 100, /* PWM period is 100 cycles. */ + NULL, + { + {PWM_OUTPUT_ACTIVE_HIGH, NULL}, + {PWM_OUTPUT_ACTIVE_HIGH, NULL}, + {PWM_OUTPUT_ACTIVE_HIGH, NULL}, + {PWM_OUTPUT_ACTIVE_HIGH, NULL} + }, + 0 }; /* @@ -38,12 +48,12 @@ static const PWMConfig pwmcfg = { * Speed 42MHz, CPHA=0, CPOL=0, 8bits frames, MSb transmitted first. * The slave select line is the pin 4 on the port GPIOA. */ -static const SPIConfig spi1cfg1 = { - NULL, - /* HW dependent part.*/ - GPIOA, - 4, - 0 //SPI_CR1_BR_0 +static const SPIConfig spi1cfg_8bit = { + NULL, + /* HW dependent part.*/ + GPIOA, + 4, + 0 //SPI_CR1_BR_0 }; /* @@ -51,48 +61,42 @@ static const SPIConfig spi1cfg1 = { * Speed 42MHz, CPHA=0, CPOL=0, 16bits frames, MSb transmitted first. * The slave select line is the pin 4 on the port GPIOA. */ -static const SPIConfig spi1cfg2 = { - NULL, - /* HW dependent part.*/ - GPIOA, - 4, - SPI_CR1_DFF //SPI_CR1_BR_0 +static const SPIConfig spi1cfg_16bit = { + NULL, + /* HW dependent part.*/ + GPIOA, + 4, + SPI_CR1_DFF //SPI_CR1_BR_0 }; /** * @brief Initialise the board for the display. - * @notes This board definition uses GPIO and assumes exclusive access to these GPIO pins + * @notes This board definition uses GPIO and SPI. It assumes exclusive access to these GPIO pins but not necessarily the SPI port. * * @notapi */ static inline void init_board(void) { - /* Display backlight control */ /* TIM4 is an alternate function 2 (AF2) */ pwmStart(&PWMD4, &pwmcfg); palSetPadMode(GPIOD, 13, PAL_MODE_ALTERNATE(2)); pwmEnableChannel(&PWMD4, 1, 100); - palSetPadMode(GPIOB, 8, PAL_MODE_OUTPUT_PUSHPULL | - PAL_STM32_OSPEED_HIGHEST); /* RST */ - palSetPadMode(GPIOB, 9, PAL_MODE_OUTPUT_PUSHPULL | - PAL_STM32_OSPEED_HIGHEST); /* RS */ + palSetPadMode(GPIOB, 8, PAL_MODE_OUTPUT_PUSHPULL|PAL_STM32_OSPEED_HIGHEST); /* RST */ + palSetPadMode(GPIOB, 9, PAL_MODE_OUTPUT_PUSHPULL|PAL_STM32_OSPEED_HIGHEST); /* RS */ /* - * Initializes the SPI driver 1. The SPI1 signals are routed as follow: - * PB12 - NSS. - * PB13 - SCK. - * PB14 - MISO. - * PB15 - MOSI. - */ - spiStart(&SPID1, &spi1cfg1); - palSetPad(GPIOA, 4); - palSetPadMode(GPIOA, 4, PAL_MODE_OUTPUT_PUSHPULL | - PAL_STM32_OSPEED_HIGHEST); /* NSS. */ - palSetPadMode(GPIOA, 5, PAL_MODE_ALTERNATE(5) | - PAL_STM32_OSPEED_HIGHEST); /* SCK. */ - palSetPadMode(GPIOA, 6, PAL_MODE_ALTERNATE(5)); /* MISO. */ - palSetPadMode(GPIOA, 7, PAL_MODE_ALTERNATE(5) | - PAL_STM32_OSPEED_HIGHEST); /* MOSI. */ + * Initializes the SPI driver 1. The SPI1 signals are routed as follow: + * PB12 - NSS. + * PB13 - SCK. + * PB14 - MISO. + * PB15 - MOSI. + */ + SET_CS; SET_DATA; + spiStart(&SPID1, &spi1cfg_8bit); + palSetPadMode(GPIOA, 4, PAL_MODE_OUTPUT_PUSHPULL|PAL_STM32_OSPEED_HIGHEST); /* NSS. */ + palSetPadMode(GPIOA, 5, PAL_MODE_ALTERNATE(5)|PAL_STM32_OSPEED_HIGHEST); /* SCK. */ + palSetPadMode(GPIOA, 6, PAL_MODE_ALTERNATE(5)); /* MISO. */ + palSetPadMode(GPIOA, 7, PAL_MODE_ALTERNATE(5)|PAL_STM32_OSPEED_HIGHEST); /* MOSI. */ } @@ -124,79 +128,70 @@ static inline void set_backlight(uint8_t percent) { /** * @brief Take exclusive control of the bus - * @note Not needed, not implemented - * * @notapi */ static inline void acquire_bus(void) { spiAcquireBus(&SPID1); + while(((SPI1->SR & SPI_SR_TXE) == 0) || ((SPI1->SR & SPI_SR_BSY) != 0)); // Safety + CLR_CS; } /** * @brief Release exclusive control of the bus - * @note Not needed, not implemented - * * @notapi */ static inline void release_bus(void) { + SET_CS; spiReleaseBus(&SPID1); } /** - * @brief Send data to the index register. + * @brief Set the bus in 16 bit mode + * @notapi + */ +static inline void busmode16(void) { + spiStart(&SPID1, &spi1cfg_16bit); +} + +/** + * @brief Set the bus in 8 bit mode (the default) + * @notapi + */ +static inline void busmode8(void) { + spiStart(&SPID1, &spi1cfg_8bit); +} + +/** + * @brief Set which index register to use. * * @param[in] index The index register to set * * @notapi */ static inline void write_index(uint8_t cmd) { - palClearPad(GPIOB, 9); - palClearPad(GPIOA, 4); - while((SPI1->SR & SPI_SR_TXE) == 0); + CLR_DATA; SPI1->DR = cmd; while(((SPI1->SR & SPI_SR_TXE) == 0) || ((SPI1->SR & SPI_SR_BSY) != 0)); - palSetPad(GPIOB, 9); + SET_DATA; } /** - * @brief Send data to the lcd. + * @brief Send a command to the lcd. * * @param[in] data The data to send * * @notapi */ -static inline void write_data(uint8_t data) { +static inline void write_reg(uint8_t cmd, uint8_t data) { + write_index(cmd); SPI1->DR = data; while(((SPI1->SR & SPI_SR_TXE) == 0) || ((SPI1->SR & SPI_SR_BSY) != 0)); - palSetPad(GPIOA, 4); -} - -static inline void write_ram8(uint8_t data1, uint8_t data2) { - SPI1->DR = data1; - while((SPI1->SR & SPI_SR_TXE) == 0); - SPI1->DR = data2; - while(((SPI1->SR & SPI_SR_TXE) == 0) || ((SPI1->SR & SPI_SR_BSY) != 0)); - palSetPad(GPIOA, 4); } static inline void write_ram16(uint16_t data) { - while((SPI1->SR & SPI_SR_TXE) == 0); SPI1->DR = data; + while((SPI1->SR & SPI_SR_TXE) == 0); } -#if GDISP_HARDWARE_READPIXEL || defined(__DOXYGEN__) -/** - * @brief Read data from the lcd. - * - * @return The data from the lcd - * @note The chip select may need to be asserted/de-asserted - * around the actual spi read - * - * @notapi - */ -static inline uint16_t read_data(void) { -} -#endif - #endif /* _GDISP_LLD_BOARD_H */ /** @} */ diff --git a/drivers/gdisp/HX8347D/gdisp_lld_board_template.h b/drivers/gdisp/HX8347D/gdisp_lld_board_template.h index 295a7997..d3b71d97 100644 --- a/drivers/gdisp/HX8347D/gdisp_lld_board_template.h +++ b/drivers/gdisp/HX8347D/gdisp_lld_board_template.h @@ -18,8 +18,6 @@ /** * @brief Initialise the board for the display. - * @notes This board definition uses GPIO and assumes exclusive access to these GPIO pins - * * @notapi */ static inline void init_board(void) { @@ -50,8 +48,6 @@ static inline void set_backlight(uint8_t percent) { /** * @brief Take exclusive control of the bus - * @note Not needed, not implemented - * * @notapi */ static inline void acquire_bus(void) { @@ -60,8 +56,6 @@ static inline void acquire_bus(void) { /** * @brief Release exclusive control of the bus - * @note Not needed, not implemented - * * @notapi */ static inline void release_bus(void) { @@ -69,7 +63,23 @@ static inline void release_bus(void) { } /** - * @brief Send data to the index register. + * @brief Set the bus in 16 bit mode + * @notapi + */ +static inline void busmode16(void) { + +} + +/** + * @brief Set the bus in 8 bit mode (the default) + * @notapi + */ +static inline void busmode8(void) { + +} + +/** + * @brief Set which index register to use. * * @param[in] index The index register to set * @@ -80,19 +90,13 @@ static inline void write_index(uint8_t cmd) { } /** - * @brief Send data to the lcd. + * @brief Send a command to the lcd. * * @param[in] data The data to send * * @notapi */ -static inline void write_data(uint8_t data) { - - - -} - -static inline void write_ram8(uint8_t data1, uint8_t data2) { +static inline void write_reg(uint8_t cmd, uint8_t data) { } @@ -100,21 +104,6 @@ static inline void write_ram16(uint16_t data) { } -#if GDISP_HARDWARE_READPIXEL || defined(__DOXYGEN__) -/** - * @brief Read data from the lcd. - * - * @return The data from the lcd - * @note The chip select may need to be asserted/de-asserted - * around the actual spi read - * - * @notapi - */ -static inline uint16_t read_data(void) { - -} -#endif - #endif /* _GDISP_LLD_BOARD_H */ /** @} */ diff --git a/drivers/gdisp/HX8347D/gdisp_lld_config.h b/drivers/gdisp/HX8347D/gdisp_lld_config.h index 7bf47ade..a5a8e2b8 100644 --- a/drivers/gdisp/HX8347D/gdisp_lld_config.h +++ b/drivers/gdisp/HX8347D/gdisp_lld_config.h @@ -23,12 +23,9 @@ /*===========================================================================*/ #define GDISP_DRIVER_NAME "HX8347D" +#define GDISP_DRIVER_STRUCT GDISP_HX8347D -#define GDISP_HARDWARE_CLEARS TRUE -#define GDISP_HARDWARE_FILLS TRUE -#define GDISP_HARDWARE_BITFILLS TRUE -#define GDISP_HARDWARE_SCROLL FALSE -#define GDISP_HARDWARE_PIXELREAD FALSE +#define GDISP_HARDWARE_STREAM_WRITE TRUE #define GDISP_HARDWARE_CONTROL TRUE #define GDISP_PIXELFORMAT GDISP_PIXELFORMAT_RGB565