HX8347D driver ported to new streaming structure (untested)

ugfx_release_2.6
inmarket 2013-09-30 15:41:32 +10:00
parent dd54d42f00
commit 07f96ec3ee
5 changed files with 189 additions and 464 deletions

View File

@ -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 */

View File

@ -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

View File

@ -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 */
/** @} */

View File

@ -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 */
/** @} */

View File

@ -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