Hopefully finally fix the corrupt LCD
The SPI bus is now selected and deselected before each set of commands. Also speed up things by buffering many commands into a single batch.
This commit is contained in:
		@@ -37,10 +37,14 @@
 | 
			
		||||
// MSB First
 | 
			
		||||
// CLK Low by default
 | 
			
		||||
static const SPIConfig spi1config = {
 | 
			
		||||
	NULL,
 | 
			
		||||
	/* HW dependent part.*/
 | 
			
		||||
	ST7565_GPIOPORT,
 | 
			
		||||
    ST7565_SS_PIN,
 | 
			
		||||
   // Operation complete callback or @p NULL.
 | 
			
		||||
  .end_cb = NULL,
 | 
			
		||||
   //The chip select line port - when not using pcs.
 | 
			
		||||
  .ssport = ST7565_GPIOPORT,
 | 
			
		||||
   // brief The chip select line pad number - when not using pcs.
 | 
			
		||||
  .sspad=ST7565_SS_PIN,
 | 
			
		||||
   // SPI initialization data.
 | 
			
		||||
  .tar0 =
 | 
			
		||||
    SPIx_CTARn_FMSZ(7)
 | 
			
		||||
    | SPIx_CTARn_ASC(7)
 | 
			
		||||
    | SPIx_CTARn_DT(7)
 | 
			
		||||
@@ -50,13 +54,10 @@ static const SPIConfig spi1config = {
 | 
			
		||||
	//SPI_CR1_BR_0
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static bool_t st7565_is_data_mode = 1;
 | 
			
		||||
 | 
			
		||||
static GFXINLINE void init_board(GDisplay *g) {
 | 
			
		||||
    (void) g;
 | 
			
		||||
    palSetPadModeNamed(A0, PAL_MODE_OUTPUT_PUSHPULL);
 | 
			
		||||
    palSetPad(ST7565_GPIOPORT, ST7565_A0_PIN);
 | 
			
		||||
    st7565_is_data_mode = 1;
 | 
			
		||||
    palSetPadModeNamed(RST, PAL_MODE_OUTPUT_PUSHPULL);
 | 
			
		||||
    palSetPad(ST7565_GPIOPORT, ST7565_RST_PIN);
 | 
			
		||||
    palSetPadModeRaw(MOSI, ST7565_SPI_MODE);
 | 
			
		||||
@@ -65,7 +66,6 @@ static GFXINLINE void init_board(GDisplay *g) {
 | 
			
		||||
 | 
			
		||||
    spiInit();
 | 
			
		||||
    spiStart(&SPID1, &spi1config);
 | 
			
		||||
    spiSelect(&SPID1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static GFXINLINE void post_init_board(GDisplay *g) {
 | 
			
		||||
@@ -86,39 +86,27 @@ static GFXINLINE void acquire_bus(GDisplay *g) {
 | 
			
		||||
    (void) g;
 | 
			
		||||
    // Only the LCD is using the SPI bus, so no need to acquire
 | 
			
		||||
    // spiAcquireBus(&SPID1);
 | 
			
		||||
    spiSelect(&SPID1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static GFXINLINE void release_bus(GDisplay *g) {
 | 
			
		||||
    (void) g;
 | 
			
		||||
    // Only the LCD is using the SPI bus, so no need to release
 | 
			
		||||
    //spiReleaseBus(&SPID1);
 | 
			
		||||
    spiUnselect(&SPID1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static GFXINLINE void write_cmd(GDisplay *g, uint8_t cmd) {
 | 
			
		||||
	(void) g;
 | 
			
		||||
	if (st7565_is_data_mode) {
 | 
			
		||||
	    // The sleeps need to be at lest 10 vs 25 ns respectively
 | 
			
		||||
	    // So let's sleep two ticks, one tick might not be enough
 | 
			
		||||
	    // if we are at the end of the tick
 | 
			
		||||
	    chThdSleep(2);
 | 
			
		||||
        palClearPad(ST7565_GPIOPORT, ST7565_A0_PIN);
 | 
			
		||||
        chThdSleep(2);
 | 
			
		||||
        st7565_is_data_mode = 0;
 | 
			
		||||
	}
 | 
			
		||||
	spiSend(&SPID1, 1, &cmd);
 | 
			
		||||
static GFXINLINE void enter_data_mode(GDisplay *g) {
 | 
			
		||||
    palSetPad(ST7565_GPIOPORT, ST7565_A0_PIN);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static GFXINLINE void enter_cmd_mode(GDisplay *g) {
 | 
			
		||||
    palClearPad(ST7565_GPIOPORT, ST7565_A0_PIN);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static GFXINLINE void write_data(GDisplay *g, uint8_t* data, uint16_t length) {
 | 
			
		||||
	(void) g;
 | 
			
		||||
	if (!st7565_is_data_mode) {
 | 
			
		||||
	    // The sleeps need to be at lest 10 vs 25 ns respectively
 | 
			
		||||
	    // So let's sleep two ticks, one tick might not be enough
 | 
			
		||||
	    // if we are at the end of the tick
 | 
			
		||||
	    chThdSleep(2);
 | 
			
		||||
        palSetPad(ST7565_GPIOPORT, ST7565_A0_PIN);
 | 
			
		||||
	    chThdSleep(2);
 | 
			
		||||
        st7565_is_data_mode = 1;
 | 
			
		||||
	}
 | 
			
		||||
	spiSend(&SPID1, length, data);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -20,16 +20,16 @@
 | 
			
		||||
/*===========================================================================*/
 | 
			
		||||
 | 
			
		||||
#ifndef GDISP_SCREEN_HEIGHT
 | 
			
		||||
	#define GDISP_SCREEN_HEIGHT		32
 | 
			
		||||
#define GDISP_SCREEN_HEIGHT		32
 | 
			
		||||
#endif
 | 
			
		||||
#ifndef GDISP_SCREEN_WIDTH
 | 
			
		||||
	#define GDISP_SCREEN_WIDTH		128
 | 
			
		||||
#define GDISP_SCREEN_WIDTH		128
 | 
			
		||||
#endif
 | 
			
		||||
#ifndef GDISP_INITIAL_CONTRAST
 | 
			
		||||
	#define GDISP_INITIAL_CONTRAST	0
 | 
			
		||||
#define GDISP_INITIAL_CONTRAST	0
 | 
			
		||||
#endif
 | 
			
		||||
#ifndef GDISP_INITIAL_BACKLIGHT
 | 
			
		||||
	#define GDISP_INITIAL_BACKLIGHT	100
 | 
			
		||||
#define GDISP_INITIAL_BACKLIGHT	100
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define GDISP_FLG_NEEDFLUSH			(GDISP_FLG_DRIVER<<0)
 | 
			
		||||
@@ -40,16 +40,16 @@
 | 
			
		||||
/* Driver config defaults for backward compatibility.               	     */
 | 
			
		||||
/*===========================================================================*/
 | 
			
		||||
#ifndef ST7565_LCD_BIAS
 | 
			
		||||
  #define ST7565_LCD_BIAS         ST7565_LCD_BIAS_7
 | 
			
		||||
#define ST7565_LCD_BIAS         ST7565_LCD_BIAS_7
 | 
			
		||||
#endif
 | 
			
		||||
#ifndef ST7565_ADC
 | 
			
		||||
  #define ST7565_ADC              ST7565_ADC_NORMAL
 | 
			
		||||
#define ST7565_ADC              ST7565_ADC_NORMAL
 | 
			
		||||
#endif
 | 
			
		||||
#ifndef ST7565_COM_SCAN
 | 
			
		||||
  #define ST7565_COM_SCAN         ST7565_COM_SCAN_INC
 | 
			
		||||
#define ST7565_COM_SCAN         ST7565_COM_SCAN_INC
 | 
			
		||||
#endif
 | 
			
		||||
#ifndef ST7565_PAGE_ORDER
 | 
			
		||||
  #define ST7565_PAGE_ORDER       0,1,2,3
 | 
			
		||||
#define ST7565_PAGE_ORDER       0,1,2,3
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/*===========================================================================*/
 | 
			
		||||
@@ -58,12 +58,24 @@
 | 
			
		||||
 | 
			
		||||
typedef struct{
 | 
			
		||||
    bool_t buffer2;
 | 
			
		||||
    uint8_t data_pos;
 | 
			
		||||
    uint8_t data[16];
 | 
			
		||||
    uint8_t ram[GDISP_SCREEN_HEIGHT * GDISP_SCREEN_WIDTH / 8];
 | 
			
		||||
}PrivData;
 | 
			
		||||
 | 
			
		||||
// Some common routines and macros
 | 
			
		||||
#define PRIV(g)                         ((PrivData*)g->priv)
 | 
			
		||||
#define RAM(g)							(PRIV(g)->ram)
 | 
			
		||||
 | 
			
		||||
static GFXINLINE void write_cmd(GDisplay* g, uint8_t cmd) {
 | 
			
		||||
    PRIV(g)->data[PRIV(g)->data_pos++] = cmd;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static GFXINLINE void flush_cmd(GDisplay* g) {
 | 
			
		||||
    write_data(g, PRIV(g)->data, PRIV(g)->data_pos);
 | 
			
		||||
    PRIV(g)->data_pos = 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#define write_cmd2(g, cmd1, cmd2)		{ write_cmd(g, cmd1); write_cmd(g, cmd2); }
 | 
			
		||||
#define write_cmd3(g, cmd1, cmd2, cmd3)	{ write_cmd(g, cmd1); write_cmd(g, cmd2); write_cmd(g, cmd3); }
 | 
			
		||||
 | 
			
		||||
@@ -86,207 +98,224 @@ typedef struct{
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
LLDSPEC bool_t gdisp_lld_init(GDisplay *g) {
 | 
			
		||||
	// The private area is the display surface.
 | 
			
		||||
	g->priv = gfxAlloc(sizeof(PrivData));
 | 
			
		||||
	PRIV(g)->buffer2 = false;
 | 
			
		||||
    // The private area is the display surface.
 | 
			
		||||
    g->priv = gfxAlloc(sizeof(PrivData));
 | 
			
		||||
    PRIV(g)->buffer2 = false;
 | 
			
		||||
    PRIV(g)->data_pos = 0;
 | 
			
		||||
 | 
			
		||||
	// Initialise the board interface
 | 
			
		||||
	init_board(g);
 | 
			
		||||
    // Initialise the board interface
 | 
			
		||||
    init_board(g);
 | 
			
		||||
 | 
			
		||||
	// Hardware reset
 | 
			
		||||
	setpin_reset(g, TRUE);
 | 
			
		||||
	gfxSleepMilliseconds(20);
 | 
			
		||||
	setpin_reset(g, FALSE);
 | 
			
		||||
	gfxSleepMilliseconds(20);
 | 
			
		||||
    // Hardware reset
 | 
			
		||||
    setpin_reset(g, TRUE);
 | 
			
		||||
    gfxSleepMilliseconds(20);
 | 
			
		||||
    setpin_reset(g, FALSE);
 | 
			
		||||
    gfxSleepMilliseconds(20);
 | 
			
		||||
 | 
			
		||||
	acquire_bus(g);
 | 
			
		||||
    acquire_bus(g);
 | 
			
		||||
    enter_cmd_mode(g);
 | 
			
		||||
    write_cmd(g, ST7565_DISPLAY_OFF);
 | 
			
		||||
	write_cmd(g, ST7565_LCD_BIAS);
 | 
			
		||||
    write_cmd(g, ST7565_LCD_BIAS);
 | 
			
		||||
    write_cmd(g, ST7565_ADC);
 | 
			
		||||
    write_cmd(g, ST7565_COM_SCAN);
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    write_cmd(g, ST7565_START_LINE | 0);
 | 
			
		||||
 | 
			
		||||
	write_cmd(g, ST7565_RESISTOR_RATIO | 0x6);
 | 
			
		||||
    write_cmd(g, ST7565_RESISTOR_RATIO | 0x6);
 | 
			
		||||
 | 
			
		||||
	// turn on voltage converter (VC=1, VR=0, VF=0)
 | 
			
		||||
	write_cmd(g, ST7565_POWER_CONTROL | 0x04);
 | 
			
		||||
	delay_ms(50);
 | 
			
		||||
    // turn on voltage converter (VC=1, VR=0, VF=0)
 | 
			
		||||
    write_cmd(g, ST7565_POWER_CONTROL | 0x04);
 | 
			
		||||
    flush_cmd(g);
 | 
			
		||||
    delay_ms(50);
 | 
			
		||||
 | 
			
		||||
	// turn on voltage regulator (VC=1, VR=1, VF=0)
 | 
			
		||||
	write_cmd(g, ST7565_POWER_CONTROL | 0x06);
 | 
			
		||||
	delay_ms(50);
 | 
			
		||||
    // turn on voltage regulator (VC=1, VR=1, VF=0)
 | 
			
		||||
    write_cmd(g, ST7565_POWER_CONTROL | 0x06);
 | 
			
		||||
    flush_cmd(g);
 | 
			
		||||
    delay_ms(50);
 | 
			
		||||
 | 
			
		||||
	// turn on voltage follower (VC=1, VR=1, VF=1)
 | 
			
		||||
	write_cmd(g, ST7565_POWER_CONTROL | 0x07);
 | 
			
		||||
	delay_ms(50);
 | 
			
		||||
    // turn on voltage follower (VC=1, VR=1, VF=1)
 | 
			
		||||
    write_cmd(g, ST7565_POWER_CONTROL | 0x07);
 | 
			
		||||
    flush_cmd(g);
 | 
			
		||||
    delay_ms(50);
 | 
			
		||||
 | 
			
		||||
	write_cmd(g, 0xE2);
 | 
			
		||||
    write_cmd(g, 0xE2);
 | 
			
		||||
    write_cmd(g, ST7565_COM_SCAN);
 | 
			
		||||
	write_cmd2(g, ST7565_CONTRAST, GDISP_INITIAL_CONTRAST*64/101);
 | 
			
		||||
	//write_cmd2(g, ST7565_CONTRAST, 0);
 | 
			
		||||
	write_cmd(g, ST7565_DISPLAY_ON);
 | 
			
		||||
	write_cmd(g, ST7565_ALLON_NORMAL);
 | 
			
		||||
	write_cmd(g, ST7565_INVERT_DISPLAY);
 | 
			
		||||
    write_cmd2(g, ST7565_CONTRAST, GDISP_INITIAL_CONTRAST*64/101);
 | 
			
		||||
    //write_cmd2(g, ST7565_CONTRAST, 0);
 | 
			
		||||
    write_cmd(g, ST7565_DISPLAY_ON);
 | 
			
		||||
    write_cmd(g, ST7565_ALLON_NORMAL);
 | 
			
		||||
    write_cmd(g, ST7565_INVERT_DISPLAY);
 | 
			
		||||
 | 
			
		||||
	write_cmd(g, ST7565_RMW);
 | 
			
		||||
    write_cmd(g, ST7565_RMW);
 | 
			
		||||
    flush_cmd(g);
 | 
			
		||||
 | 
			
		||||
    // Finish Init
 | 
			
		||||
    post_init_board(g);
 | 
			
		||||
 | 
			
		||||
 	// Release the bus
 | 
			
		||||
	release_bus(g);
 | 
			
		||||
    // Release the bus
 | 
			
		||||
    release_bus(g);
 | 
			
		||||
 | 
			
		||||
	/* 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;
 | 
			
		||||
    /* 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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#if GDISP_HARDWARE_FLUSH
 | 
			
		||||
	LLDSPEC void gdisp_lld_flush(GDisplay *g) {
 | 
			
		||||
		unsigned	p;
 | 
			
		||||
LLDSPEC void gdisp_lld_flush(GDisplay *g) {
 | 
			
		||||
    unsigned	p;
 | 
			
		||||
 | 
			
		||||
		// Don't flush if we don't need it.
 | 
			
		||||
		if (!(g->flags & GDISP_FLG_NEEDFLUSH))
 | 
			
		||||
			return;
 | 
			
		||||
    // Don't flush if we don't need it.
 | 
			
		||||
    if (!(g->flags & GDISP_FLG_NEEDFLUSH))
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
		acquire_bus(g);
 | 
			
		||||
		unsigned dstOffset = (PRIV(g)->buffer2 ? 4 : 0);
 | 
			
		||||
		for (p = 0; p < 4; p++) {
 | 
			
		||||
			write_cmd(g, ST7565_PAGE | (p + dstOffset));
 | 
			
		||||
			write_cmd(g, ST7565_COLUMN_MSB | 0);
 | 
			
		||||
			write_cmd(g, ST7565_COLUMN_LSB | 0);
 | 
			
		||||
			write_cmd(g, ST7565_RMW);
 | 
			
		||||
			write_data(g, RAM(g) + (p*GDISP_SCREEN_WIDTH), GDISP_SCREEN_WIDTH);
 | 
			
		||||
		}
 | 
			
		||||
		unsigned line = (PRIV(g)->buffer2 ? 32 : 0);
 | 
			
		||||
        write_cmd(g, ST7565_START_LINE | line);
 | 
			
		||||
        PRIV(g)->buffer2 = !PRIV(g)->buffer2;
 | 
			
		||||
		release_bus(g);
 | 
			
		||||
    acquire_bus(g);
 | 
			
		||||
    enter_cmd_mode(g);
 | 
			
		||||
    unsigned dstOffset = (PRIV(g)->buffer2 ? 4 : 0);
 | 
			
		||||
    for (p = 0; p < 4; p++) {
 | 
			
		||||
        write_cmd(g, ST7565_PAGE | (p + dstOffset));
 | 
			
		||||
        write_cmd(g, ST7565_COLUMN_MSB | 0);
 | 
			
		||||
        write_cmd(g, ST7565_COLUMN_LSB | 0);
 | 
			
		||||
        write_cmd(g, ST7565_RMW);
 | 
			
		||||
        flush_cmd(g);
 | 
			
		||||
        enter_data_mode(g);
 | 
			
		||||
        write_data(g, RAM(g) + (p*GDISP_SCREEN_WIDTH), GDISP_SCREEN_WIDTH);
 | 
			
		||||
        enter_cmd_mode(g);
 | 
			
		||||
    }
 | 
			
		||||
    unsigned line = (PRIV(g)->buffer2 ? 32 : 0);
 | 
			
		||||
    write_cmd(g, ST7565_START_LINE | line);
 | 
			
		||||
    flush_cmd(g);
 | 
			
		||||
    PRIV(g)->buffer2 = !PRIV(g)->buffer2;
 | 
			
		||||
    release_bus(g);
 | 
			
		||||
 | 
			
		||||
		g->flags &= ~GDISP_FLG_NEEDFLUSH;
 | 
			
		||||
	}
 | 
			
		||||
    g->flags &= ~GDISP_FLG_NEEDFLUSH;
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if GDISP_HARDWARE_DRAWPIXEL
 | 
			
		||||
	LLDSPEC void gdisp_lld_draw_pixel(GDisplay *g) {
 | 
			
		||||
		coord_t		x, y;
 | 
			
		||||
LLDSPEC void gdisp_lld_draw_pixel(GDisplay *g) {
 | 
			
		||||
    coord_t		x, y;
 | 
			
		||||
 | 
			
		||||
		switch(g->g.Orientation) {
 | 
			
		||||
		default:
 | 
			
		||||
		case GDISP_ROTATE_0:
 | 
			
		||||
			x = g->p.x;
 | 
			
		||||
			y = g->p.y;
 | 
			
		||||
			break;
 | 
			
		||||
		case GDISP_ROTATE_90:
 | 
			
		||||
			x = g->p.y;
 | 
			
		||||
			y = GDISP_SCREEN_HEIGHT-1 - g->p.x;
 | 
			
		||||
			break;
 | 
			
		||||
		case GDISP_ROTATE_180:
 | 
			
		||||
			x = GDISP_SCREEN_WIDTH-1 - g->p.x;
 | 
			
		||||
			y = GDISP_SCREEN_HEIGHT-1 - g->p.y;
 | 
			
		||||
			break;
 | 
			
		||||
		case GDISP_ROTATE_270:
 | 
			
		||||
			x = GDISP_SCREEN_HEIGHT-1 - g->p.y;
 | 
			
		||||
			y = g->p.x;
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
		if (gdispColor2Native(g->p.color) != Black)
 | 
			
		||||
			RAM(g)[xyaddr(x, y)] |= xybit(y);
 | 
			
		||||
		else
 | 
			
		||||
			RAM(g)[xyaddr(x, y)] &= ~xybit(y);
 | 
			
		||||
		g->flags |= GDISP_FLG_NEEDFLUSH;
 | 
			
		||||
	}
 | 
			
		||||
    switch(g->g.Orientation) {
 | 
			
		||||
    default:
 | 
			
		||||
    case GDISP_ROTATE_0:
 | 
			
		||||
        x = g->p.x;
 | 
			
		||||
        y = g->p.y;
 | 
			
		||||
        break;
 | 
			
		||||
    case GDISP_ROTATE_90:
 | 
			
		||||
        x = g->p.y;
 | 
			
		||||
        y = GDISP_SCREEN_HEIGHT-1 - g->p.x;
 | 
			
		||||
        break;
 | 
			
		||||
    case GDISP_ROTATE_180:
 | 
			
		||||
        x = GDISP_SCREEN_WIDTH-1 - g->p.x;
 | 
			
		||||
        y = GDISP_SCREEN_HEIGHT-1 - g->p.y;
 | 
			
		||||
        break;
 | 
			
		||||
    case GDISP_ROTATE_270:
 | 
			
		||||
        x = GDISP_SCREEN_HEIGHT-1 - g->p.y;
 | 
			
		||||
        y = g->p.x;
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
    if (gdispColor2Native(g->p.color) != Black)
 | 
			
		||||
        RAM(g)[xyaddr(x, y)] |= xybit(y);
 | 
			
		||||
    else
 | 
			
		||||
        RAM(g)[xyaddr(x, y)] &= ~xybit(y);
 | 
			
		||||
    g->flags |= GDISP_FLG_NEEDFLUSH;
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if GDISP_HARDWARE_PIXELREAD
 | 
			
		||||
	LLDSPEC color_t gdisp_lld_get_pixel_color(GDisplay *g) {
 | 
			
		||||
		coord_t		x, y;
 | 
			
		||||
LLDSPEC color_t gdisp_lld_get_pixel_color(GDisplay *g) {
 | 
			
		||||
    coord_t		x, y;
 | 
			
		||||
 | 
			
		||||
		switch(g->g.Orientation) {
 | 
			
		||||
		default:
 | 
			
		||||
		case GDISP_ROTATE_0:
 | 
			
		||||
			x = g->p.x;
 | 
			
		||||
			y = g->p.y;
 | 
			
		||||
			break;
 | 
			
		||||
		case GDISP_ROTATE_90:
 | 
			
		||||
			x = g->p.y;
 | 
			
		||||
			y = GDISP_SCREEN_HEIGHT-1 - g->p.x;
 | 
			
		||||
			break;
 | 
			
		||||
		case GDISP_ROTATE_180:
 | 
			
		||||
			x = GDISP_SCREEN_WIDTH-1 - g->p.x;
 | 
			
		||||
			y = GDISP_SCREEN_HEIGHT-1 - g->p.y;
 | 
			
		||||
			break;
 | 
			
		||||
		case GDISP_ROTATE_270:
 | 
			
		||||
			x = GDISP_SCREEN_HEIGHT-1 - g->p.y;
 | 
			
		||||
			y = g->p.x;
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
		return (RAM(g)[xyaddr(x, y)] & xybit(y)) ? White : Black;
 | 
			
		||||
	}
 | 
			
		||||
    switch(g->g.Orientation) {
 | 
			
		||||
    default:
 | 
			
		||||
    case GDISP_ROTATE_0:
 | 
			
		||||
        x = g->p.x;
 | 
			
		||||
        y = g->p.y;
 | 
			
		||||
        break;
 | 
			
		||||
    case GDISP_ROTATE_90:
 | 
			
		||||
        x = g->p.y;
 | 
			
		||||
        y = GDISP_SCREEN_HEIGHT-1 - g->p.x;
 | 
			
		||||
        break;
 | 
			
		||||
    case GDISP_ROTATE_180:
 | 
			
		||||
        x = GDISP_SCREEN_WIDTH-1 - g->p.x;
 | 
			
		||||
        y = GDISP_SCREEN_HEIGHT-1 - g->p.y;
 | 
			
		||||
        break;
 | 
			
		||||
    case GDISP_ROTATE_270:
 | 
			
		||||
        x = GDISP_SCREEN_HEIGHT-1 - g->p.y;
 | 
			
		||||
        y = g->p.x;
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
    return (RAM(g)[xyaddr(x, y)] & xybit(y)) ? White : Black;
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if GDISP_NEED_CONTROL && GDISP_HARDWARE_CONTROL
 | 
			
		||||
	LLDSPEC void gdisp_lld_control(GDisplay *g) {
 | 
			
		||||
		switch(g->p.x) {
 | 
			
		||||
		case GDISP_CONTROL_POWER:
 | 
			
		||||
			if (g->g.Powermode == (powermode_t)g->p.ptr)
 | 
			
		||||
				return;
 | 
			
		||||
			switch((powermode_t)g->p.ptr) {
 | 
			
		||||
			case powerOff:
 | 
			
		||||
			case powerSleep:
 | 
			
		||||
			case powerDeepSleep:
 | 
			
		||||
				acquire_bus(g);
 | 
			
		||||
				write_cmd(g, ST7565_DISPLAY_OFF);
 | 
			
		||||
				release_bus(g);
 | 
			
		||||
				break;
 | 
			
		||||
			case powerOn:
 | 
			
		||||
				acquire_bus(g);
 | 
			
		||||
				write_cmd(g, ST7565_DISPLAY_ON);
 | 
			
		||||
				release_bus(g);
 | 
			
		||||
				break;
 | 
			
		||||
			default:
 | 
			
		||||
				return;
 | 
			
		||||
			}
 | 
			
		||||
			g->g.Powermode = (powermode_t)g->p.ptr;
 | 
			
		||||
			return;
 | 
			
		||||
LLDSPEC void gdisp_lld_control(GDisplay *g) {
 | 
			
		||||
    switch(g->p.x) {
 | 
			
		||||
    case GDISP_CONTROL_POWER:
 | 
			
		||||
        if (g->g.Powermode == (powermode_t)g->p.ptr)
 | 
			
		||||
            return;
 | 
			
		||||
        switch((powermode_t)g->p.ptr) {
 | 
			
		||||
        case powerOff:
 | 
			
		||||
        case powerSleep:
 | 
			
		||||
        case powerDeepSleep:
 | 
			
		||||
            acquire_bus(g);
 | 
			
		||||
            enter_cmd_mode(g);
 | 
			
		||||
            write_cmd(g, ST7565_DISPLAY_OFF);
 | 
			
		||||
            flush_cmd(g);
 | 
			
		||||
            release_bus(g);
 | 
			
		||||
            break;
 | 
			
		||||
        case powerOn:
 | 
			
		||||
            acquire_bus(g);
 | 
			
		||||
            enter_cmd_mode(g);
 | 
			
		||||
            write_cmd(g, ST7565_DISPLAY_ON);
 | 
			
		||||
            flush_cmd(g);
 | 
			
		||||
            release_bus(g);
 | 
			
		||||
            break;
 | 
			
		||||
        default:
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        g->g.Powermode = (powermode_t)g->p.ptr;
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
		case GDISP_CONTROL_ORIENTATION:
 | 
			
		||||
			if (g->g.Orientation == (orientation_t)g->p.ptr)
 | 
			
		||||
				return;
 | 
			
		||||
			switch((orientation_t)g->p.ptr) {
 | 
			
		||||
			/* Rotation is handled by the drawing routines */
 | 
			
		||||
			case GDISP_ROTATE_0:
 | 
			
		||||
			case GDISP_ROTATE_180:
 | 
			
		||||
				g->g.Height = GDISP_SCREEN_HEIGHT;
 | 
			
		||||
				g->g.Width = GDISP_SCREEN_WIDTH;
 | 
			
		||||
				break;
 | 
			
		||||
			case GDISP_ROTATE_90:
 | 
			
		||||
			case GDISP_ROTATE_270:
 | 
			
		||||
				g->g.Height = GDISP_SCREEN_WIDTH;
 | 
			
		||||
				g->g.Width = GDISP_SCREEN_HEIGHT;
 | 
			
		||||
				break;
 | 
			
		||||
			default:
 | 
			
		||||
				return;
 | 
			
		||||
			}
 | 
			
		||||
			g->g.Orientation = (orientation_t)g->p.ptr;
 | 
			
		||||
			return;
 | 
			
		||||
        case GDISP_CONTROL_ORIENTATION:
 | 
			
		||||
            if (g->g.Orientation == (orientation_t)g->p.ptr)
 | 
			
		||||
                return;
 | 
			
		||||
            switch((orientation_t)g->p.ptr) {
 | 
			
		||||
            /* Rotation is handled by the drawing routines */
 | 
			
		||||
            case GDISP_ROTATE_0:
 | 
			
		||||
            case GDISP_ROTATE_180:
 | 
			
		||||
                g->g.Height = GDISP_SCREEN_HEIGHT;
 | 
			
		||||
                g->g.Width = GDISP_SCREEN_WIDTH;
 | 
			
		||||
                break;
 | 
			
		||||
            case GDISP_ROTATE_90:
 | 
			
		||||
            case GDISP_ROTATE_270:
 | 
			
		||||
                g->g.Height = GDISP_SCREEN_WIDTH;
 | 
			
		||||
                g->g.Width = GDISP_SCREEN_HEIGHT;
 | 
			
		||||
                break;
 | 
			
		||||
            default:
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            g->g.Orientation = (orientation_t)g->p.ptr;
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
		case GDISP_CONTROL_CONTRAST:
 | 
			
		||||
            if ((unsigned)g->p.ptr > 100)
 | 
			
		||||
            	g->p.ptr = (void *)100;
 | 
			
		||||
			acquire_bus(g);
 | 
			
		||||
			write_cmd2(g, ST7565_CONTRAST, ((((unsigned)g->p.ptr)<<6)/101) & 0x3F);
 | 
			
		||||
			release_bus(g);
 | 
			
		||||
            g->g.Contrast = (unsigned)g->p.ptr;
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
            case GDISP_CONTROL_CONTRAST:
 | 
			
		||||
                if ((unsigned)g->p.ptr > 100)
 | 
			
		||||
                    g->p.ptr = (void *)100;
 | 
			
		||||
                acquire_bus(g);
 | 
			
		||||
                enter_cmd_mode(g);
 | 
			
		||||
                write_cmd2(g, ST7565_CONTRAST, ((((unsigned)g->p.ptr)<<6)/101) & 0x3F);
 | 
			
		||||
                flush_cmd(g);
 | 
			
		||||
                release_bus(g);
 | 
			
		||||
                g->g.Contrast = (unsigned)g->p.ptr;
 | 
			
		||||
                return;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
#endif // GDISP_NEED_CONTROL
 | 
			
		||||
 | 
			
		||||
#endif // GFX_USE_GDISP
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user